我可以在EditorTemplate中动态分配@model类型吗?

时间:2012-08-16 08:47:08

标签: c# asp.net-mvc-3 templates editor viewmodel

我有一个图像上传器编辑器模板,目前强类型为MultiImageUploader视图模型。问题是我有一些自定义数据验证属性,我想在视图模型中直接调用编辑器模板,而不是通过MultiImageUploader视图模型进行路由。

我没有使用预设的验证属性调用MultiImageUploader视图模型,而是想做类似的事情:

public class CreateBrandViewModel
{
    .....<snipped>.....

    [PermittedFileExtensions("jpg, jpeg, png, gif")]
    [MaxFileSize("2MB")]
    [UIHint("MultiImageUploader")]
    public HttpPostedFileBase Image { get; set; }

  //Currently this view model looks like this:
  //public MultiImageUploader Image { get; set; } <-- seperate view model 

}

我目前无法使用我首选的方式,因为我的编辑器模板没有针对CreateBrandViewModel强类型化。有没有办法可以将调用视图模型的@model传递给编辑器模板视图? :

@model // Here? //
<div class="editor-field">
     @Html.TextBoxFor(x => x.Image, new { type = "file" })
     @Html.ValidationMessageFor(x => x.Image)
</div>

修改1

为了澄清,我想这样做的原因是因为我想从图像上传器更改为通用文件上传器 - 这将需要不同视图模型上的不同验证属性。为了做到这一点,我需要为每个略有不同的验证参数变体创建不同的视图模型和编辑器模板。

编辑2:关于@Joel Athertons回答

我在试图实现这个问题时遇到了一些问题(或者我可能只是没有正确理解)。

我已经创建了界面和抽象类。我的CreateBrandViewModel现在继承自FileUpload。 FileUpload当前为空,没有共享属性。当我尝试model.GetType()。Name我得到一个“对象引用没有设置为对象的实例。”错误。代码如下:

Controller将CreateBrandViewModel传递给视图:

    [HttpGet]
    public ActionResult Create()
    {
        var model = new CreateBrandViewModel();
        model.IsActive = true;

        return View(model);
    }

然后,Create视图调用EditorTemplate:

@model CumbriaMD.Infrastructure.ViewModels.BrandViewModels.CreateBrandViewModel 

@Html.EditorFor(model => model.File, "EditorTemplates/MultiImageUploader")

然后模板(为了简单起见)看起来像这样:

@model CumbriaMD.Infrastructure.ViewModels.FileUploadViewModels.FileUpload

@{
    var partialView = Model.GetType().Name;
}

<h1>@partialView</h1>

任何想法都将受到赞赏:)

2 个答案:

答案 0 :(得分:1)

我处理这个问题的方法是拥有一个允许上传的所有模型都可以实现的界面。如果你真的有共同的功能,我也会把它与一个具有任何共同属性,属性等的抽象模型结合起来。然后你的每个模型都会继承抽象类(或者如果你没有使用class),然后你可以使用它作为你的@model语句。然后你可以简单地将任何一次性碎片拆分成可以做自己的事情的部分视图。

public interface IFileUploadModel
{
    // any common properties would go here
}

public abstract class FileUploadModel : IFileUploadModel
{
    // implement the common stuff
}

public class CreateBrandViewModel : FileUploadModel
{
    [PermittedFileExtensions("jpg, jpeg, png, gif")]
    [MaxFileSize("2MB")]
    [UIHint("MultiImageUploader")]
    public HttpPostedFileBase Image { get; set; }
}

public class SomeOtherUploadModel : FileUploadModel
{
    // Other special stuff here
}

然后在你的模板中。

@model FileUploadModel

@{
    // Common output code that they all do

    // Then the special stuff
    if (model.GetType().Name == "CreateBrandViewModel")
    {
        // Render the partial and pass it the model
        Html.RenderPartial("CreateBrandPartialView", Model);
    }
}

答案 1 :(得分:0)

如果您的课程如下:

public class CreateBrandViewModel
{
    [PermittedFileExtensions("jpg, jpeg, png, gif")]
    [MaxFileSize("2MB")]
    [UIHint("MultiImageUploader")]
    public HttpPostedFileBase Image { get; set; }
}

你有一个名为MultiImageUploader.cshtml的EditorTemplate,那就是:

@model HttpPostedFileBase

@Html.LabelFor(m => m)
@Html.TextBoxFor(x => x, new { type = "file" })
@Html.ValidationMessageFor(x => x)

您可以使用以下方式在整体视图中呈现它:

@Html.EditorFor(m => m.Image)