我一直在尝试阅读关于这个DefaultModelBinder几天,但我仍然很困惑。我正在使用MVC 4 & EF 5 TablePerHiearchy结构。DefaultModelBinder返回子类MVC4
我的问题是,我有一个基类资源:
public class Resource : PocoBaseModel
{
private int _resourceID;
private string _title;
private string _description;
//public accessors
}
有子类(DVD,电子书,书等)
public class DVD : Resource
{
private string _actors;
//more fields and public accessors
}
我的控制器代码使用自定义的模型绑定器
[HttpPost]
public ActionResult Create([ModelBinder(typeof(ResourceModelBinder))] Resource resource)
{
//controller code
}
public class ResourceModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext,
ModelBindingContext bindingContext)
{
var type = controllerContext.HttpContext.Request.Form["DiscriminatorValue"];
bindingContext.ModelName = type;
bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, resourceTypeMap[type]);
return base.BindModel(controllerContext, bindingContext);
}
static Dictionary<string, Type> resourceTypeMap = new Dictionary<string, Type>
{
{"Resource", typeof(Resource)},
{"Book", typeof(Book)},
{"DVD", typeof(DVD)},
{"EBook", typeof(EBook)},
{"Hardware", typeof(Hardware)},
{"Software", typeof(Software)}
};
}
,这样我可以通过我的看法资源(铸造的DVD,书籍,或任何其他类型)
@model Models.Resource
@{
ViewBag.Title = "Create";
}
<h2>Create</h2>
@using (Html.BeginForm("Create", "Admin", null, FormMethod.Post, null))
{
@Html.ValidationSummary(true)
<fieldset>
<legend>Resource</legend>
@Html.HiddenFor(model => model.ResourceID)
@Html.HiddenFor(model => model.ResourceTypeID)
@Html.HiddenFor(model => model.Committed)
@Html.Partial("_CreateOrEdit", Model)
<p>
<input type="submit" value="Create"/>
</p>
</fieldset>
}
并将其绑定是根据它的派生属性恰好在partialview里面的开关。
@using Models.ViewModels;
@using Models.ResourceTypes;
@using Helper;
@model Models.Resource
@Html.HiddenFor(model => Model.DiscriminatorValue);
<table cellspacing="2" cellpadding="2" border="0">
@{
string type = Model.DiscriminatorValue;
switch (type)
{
case "Book":
Book book = (Book)Model;
<tr>
<td colspan="2">
<div class="editor-label" style="padding-top: 15px;">
@Html.LabelFor(model => model.Title)
</div>
<div class="editor-field">
@Html.TextAreaFor(model => model.Title, new { style = "width: 750px; height: 65px;" })
@Html.ValidationMessageFor(model => model.Title)
</div>
</td>
</tr>
<tr>
<td>
<div class="editor-label">
@Html.LabelFor(model => book.Edition)
</div>
<div class="editor-field">
@Html.TextBoxFor(model => book.Edition, new { style = "width: 150px;" })
@Html.ValidationMessageFor(model => book.Edition)
</div>
</td>
<td>
<div class="editor-label">
@Html.LabelFor(model => book.Author)
</div>
<div class="editor-field">
@Html.EditorFor(model => book.Author)
@Html.ValidationMessageFor(model => book.Author)
</div>
</td>
</tr>
<tr>
<td>
<div class="editor-label">
@Html.LabelFor(model => book.Pages)
</div>
<div class="editor-field">
@Html.TextBoxFor(model => book.Pages, new { style = "width: 75px;" })
@Html.ValidationMessageFor(model => book.Pages)
</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="editor-label">
@Html.LabelFor(model => model.Description)
</div>
<div class="editor-field">
@Html.TextAreaFor(model => model.Description, new { style = "width: 750px; height: 105px;" })
@Html.ValidationMessageFor(model => model.Description)
</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="editor-label">
@Html.LabelFor(model => model.AdminNote)
</div>
<div class="editor-field">
@Html.TextAreaFor(model => model.AdminNote, new { style = "width: 750px; height: 105px;" })
@Html.ValidationMessageFor(model => model.AdminNote)
</div>
</td>
</tr>
<tr>
<td>
<div class="editor-label">
@{ int copies = Model == null ? 1 : Model.Copies; }
@Html.LabelFor(model => model.Copies)
</div>
<div class="editor-field">
@Html.TextBoxFor(model => model.Copies, new { style = "width: 75px;", @Value = copies.ToString() })
@Html.ValidationMessageFor(model => model.Copies)
</div>
</td>
</tr>
<tr>
<td>
<div class="editor-label">
@Html.LabelFor(model => book.ISBN10)
</div>
<div class="editor-field">
@Html.EditorFor(model => book.ISBN10)
@Html.ValidationMessageFor(model => book.ISBN10)
</div>
</td>
<td>
<div class="editor-label">
@Html.LabelFor(model => book.ISBN13)
</div>
<div class="editor-field">
@Html.EditorFor(model => book.ISBN13)
@Html.ValidationMessageFor(model => book.ISBN13)
</div>
</td>
</tr>
break;
我的第一个问题是,当我张贴的形式回来,这又回到作为一种资源,而不是作为铸造型(所以我失去了所有的派生型属性)这就是为什么我创建的ResourceModelBinder。现在它正确绑定/回发铸造类型,但它不绑定资源的基类属性,如标题,资源ID,资源类型ID ..
任何人都可以帮助我了解我缺少的东西,以便它实际上绑定基础资源类属性以及派生类型属性。