将数据传递给EditorTemplate

时间:2015-08-22 15:28:15

标签: asp.net asp.net-mvc asp.net-mvc-3 asp.net-mvc-4 razor

我是一名学习MVC的新手,非常感谢您的帮助。我有两个模型,Firms和Address。我试图有一个简单的表单,有人可以添加公司详细信息。

加载公司表单时,包含地址模型的编辑器模板将被渲染。我遇到的问题是直截了当的问题。我甚至在堆栈溢出时看到了它的解决方案但在我的情况下它不会工作(奇怪)。当我将新Innuendo.Models.AddressModel()传递给地址模板时,在回发期间,ModelState.IsValid为false,Model.Address仍设为null。我究竟做错了什么?

公司视图

@model Innuendo.Models.FirmModel

@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>

@using (Html.BeginForm()) {
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>FirmModel</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Name)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Name)
            @Html.ValidationMessageFor(model => model.Name)
        </div>
        <div>
            @Html.Partial("~/Views/shared/EditorTemplates/_Address.cshtml", new Innuendo.Models.AddressModel())
        </div>
        <div class="editor-label">
            @Html.LabelFor(model => model.LogoPath)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.LogoPath)
            @Html.ValidationMessageFor(model => model.LogoPath)
        </div>

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

编辑模板_Address

@model Innuendo.Models.AddressModel
<div class="editor-label">
    @Html.LabelFor(model => model.HouseName)
</div>
<div class="editor-field">
    @Html.EditorFor(model => model.HouseName)
    @Html.ValidationMessageFor(model => model.HouseName)
</div>

<div class="editor-label">
    @Html.LabelFor(model => model.Street)
</div>
<div class="editor-field">
    @Html.EditorFor(model => model.Street)
    @Html.ValidationMessageFor(model => model.Street)
</div>

<div class="editor-label">
    @Html.LabelFor(model => model.Town)
</div>
<div class="editor-field">
    @Html.EditorFor(model => model.Town)
    @Html.ValidationMessageFor(model => model.Town)
</div>

<div class="editor-label">
    @Html.LabelFor(model => model.County)
</div>
<div class="editor-field">
    @Html.EditorFor(model => model.County)
    @Html.ValidationMessageFor(model => model.County)
</div>

公司控制器

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(FirmModel firmmodel)
{
    if (ModelState.IsValid)
    {

        firmmodel.FirmId = Guid.NewGuid();    
        db.Firms.Add(firmmodel);
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    return View(firmmodel);
}

公司模型

[Table("Firms")]
public class FirmModel
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public Guid FirmId { get; set; }

    [Display(Name = "Firm Name")]
    [Required]
    [StringLength(250)]
    public string Name { get; set; }

    [Required]
    public virtual AddressModel Address { get; set; }

    [StringLength(250)]
    public string LogoPath { get; set; }
}

地址模型

[Table("Addresses")]
public class AddressModel
{
    [Key]
    [HiddenInput(DisplayValue = false)]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public Guid AddressId { get; set; }

    [Required]
    [Display(Name = "House Name/Number")]

    [StringLength(250)]
    public string HouseName { get; set; }

    [StringLength(250)]
    [Required]
    public string Street { get; set; }

    [StringLength(250)]
    [Required]
    public string Town { get; set; }

    [StringLength(250)]
    [Required]
    public string County { get; set; }
}

1 个答案:

答案 0 :(得分:1)

您正在使用编辑器模板作为部分视图,因此MVC会为input生成错误的ID,并且模型绑定器无法绑定地址的属性。要解决此问题,请先将_Address.cshtml重命名为Address.cshtml以匹配类型名称。第二次替换

@Html.Partial("~/Views/shared/EditorTemplates/_Address.cshtml", new Innuendo.Models.AddressModel())

@Html.EditorFor(model=>model.Address)

或者,如果您的视图名称与类型名称不匹配。您也可以显式设置模板名称:

@Html.EditorFor(model=>model.Address,"_Address")

正如您所看到的,您不需要编写模板或视图的完整路径,因为MVC知道在哪里可以找到它们。

如果AddressId生成模型状态错误,并且您不想使用不带AddressId的视图模型,则可以编写自定义模型绑定器以在绑定时注入新的GUID。

public class AddressBinder:DefaultModelBinder
{
    protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor)
    {
        if (propertyDescriptor.PropertyType == typeof(Guid))
            ((Address)bindingContext.Model).ID = Guid.NewGuid();
        else
            base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
    }
}

Global.asax.cs

中注册您的模型活页夹
protected void Application_Start()
{
    // other codes

    ModelBinders.Binders.Add(typeof(Address), new AddressBinder());
}