一个ASP.NET MVC陷阱?失意

bur*_*1ce 4 asp.net-mvc

我有一个ASP.NET MVC html帮助器的问题,如TextBoxFor(),HiddenFor()等.如果我有一个模型,如Employee与字符串成员名称和执行Html.TextBoxFor(p => p.Name),是假设ASP.NET MVC 将始终使用 Employee名称中的值,这对我来说是错误的吗?因为它没有.ASP.NET将覆盖该绑定并使用POST中的内容.

例如,让我说我有以下代码:

模型

namespace MvcApplication2.Models
{
    public class Company
    {
        public string Name { set; get; }
        public List<Employee> Employees { set; get; }
    }

    public class Employee
    {
        public string Name { set; get; }
    }
}
Run Code Online (Sandbox Code Playgroud)

调节器

namespace MvcApplication2.Controllers
{
    public class HomeController : Controller
    {
         public ActionResult Company(string Name)
        {
            return View(new Company { 
                Name = Name, 
                Employees = new List<Employee> { 
                    new Employee { Name = "Ralph" }, 
                    new Employee { Name = "Joe" } } 
            });
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

首页/ Company.cshtml

@using MvcApplication2.Models;
@model Company


<h2>Company's Name: @Model.Name</h2>
@foreach (Employee emp in Model.Employees)
{

    Html.RenderPartial("Employee", emp);
}
Run Code Online (Sandbox Code Playgroud)

首页/ Employee.cshtml

@model MvcApplication2.Models.Employee
<b>Employee's Name: </b> @Html.TextBoxFor(p => p.Name);
Run Code Online (Sandbox Code Playgroud)

当我点击相对网址"Home/Company?Name = MSFT"时,我希望Employee.cshtml在文本框中呈现"Ralph"和"Joe",但它会为两个文本框呈现MSFT.我需要做什么才能让"拉尔夫"和"乔"出现在文本框中?我是否必须确保我的POST和GET变量在我的视图模型的所有层中都不会发生冲突(在本例中是公司和员工类)?这看起来很傻.必须有一个简单的解决方法,对吧?

这是结果的屏幕截图: 在此输入图像描述

Sco*_*pey 7

HtmlHelper方法和ModelState

使用MVC HtmlHelper方法需要了解的一件重要事情:
它们总是看ModelState第一,value第二,ViewData第三.

ModelState很重要,因为它包含用户提交的值.如果页面验证失败,ModelState则用于存储先前的值和错误消息.

如果你想POST一个表单,如果一切都有效,你想再次显示表单,你要么必须:

  • 从POST重定向到GET(遵循PRG模式)
  • 清除ModelState: ModelState.Clear();

EditorFor vs RenderPartial

另一个重要的事情是EditorFor/DisplayForvs 之间的区别RenderPartial.

当您使用EditorFor/DisplayFor某个项目(例如.EditorFor(m => m.Person))时,它会在模板中添加一个"命名空间","Person"以便子控件具有唯一的名称.例如,在模板中,.TextBoxFor(p => p.Name)将呈现类似的内容<input name="Person.Name" ....

但是,在使用时RenderPartial,不会创建此类命名空间.因此,.TextBoxFor(p => p.Name)将渲染<input name="Name" ...,如果您有多个编辑器,则不会是唯一的.