一个ASP.NET MVC陷阱?失意

时间:2011-12-22 22:51:01

标签: asp.net-mvc

我有一个ASP.NET MVC html帮助程序的问题,如TextBoxFor(),HiddenFor()等。如果我有一个模型,如Employee,字符串成员名称和执行Html.TextBoxFor(p => p。名称),我认为ASP.NET MVC 将始终使用员工姓名中的值是不对的?因为它没有。 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; }
    }
}

控制器

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" } } 
            });
        }
    }
}

主/ Company.cshtml

@using MvcApplication2.Models;
@model Company


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

    Html.RenderPartial("Employee", emp);
}

主/ Employee.cshtml

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

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

以下是结果的屏幕截图: enter image description here

2 个答案:

答案 0 :(得分:7)

HtmlHelper方法和ModelState

使用MVC HtmlHelper方法需要了解的重要事项:
他们总是先ModelStatevalue秒,ViewData第三。

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

如果您想张贴表单,如果一切都有效,您想再次显示表单,您必须:

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

EditorFor vs RenderPartial

另一个重要的事情是EditorFor/DisplayForRenderPartial之间的区别。

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

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

答案 1 :(得分:0)

我理解这种行为可能令人沮丧,而且看起来似乎不合逻辑。但是,您的挫败感是由于未完全理解模型绑定的工作原理。在绑定过程中会发生一系列逻辑事件,如果您了解它是如何工作的,那么它将有助于避免这些错误。

正如Scott所说,MVC将始终首先查看ModelState。您可以通过确保没有任何与模型中任何属性同名的查询字符串参数来避免此问题。