ModelBinder 中未通过的某些字段

发布于 2024-08-09 02:56:54 字数 5177 浏览 10 评论 0原文

以下是我的控制器的代码:

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Edit(int id, Actor actor)
    {

        try
        {
            actorRepository.Save(actor);
            return RedirectToAction("Index");
        }
        catch
        {
            return View("Edit");
        }
    }

调用的视图有一个强类型化到 Actor 类的分部视图。由于某种原因,有一些字段没有绑定到该类。有问题的字段是 Address、Address2 和 ZipCode。它们已填充在页面上,但返回为空。其他所有领域都存在,只是这些领域没有。

有什么想法吗?另外,我如何编写单元测试来复制这种行为?

更新 公开课演员 { 公共字符串中间名{获取;放;}

    [Required(ErrorMessage = "First Name is Required")]
    [RegularExpression(@"\w*", ErrorMessage = "Last Name Contains Illegal Characters")]
    public string FirstName { get; set; }

    [Required(ErrorMessage = "Last Name is Required")]
    [RegularExpression(@"\w*", ErrorMessage = "Last Name Contains Illegal Characters")]
    public string LastName { get; set; }

    [DataType(DataType.PhoneNumber, ErrorMessage = "Please Enter a Valid Phone Number")]
    [Required(ErrorMessage = "Phone Number is Required")]
    public string PhoneNumber { get; set; }

    [Required(ErrorMessage = "Address is Required")]
    [RegularExpression(@"\w*", ErrorMessage = "Address Contains Illegal Characters")]
    public string Address { get; set; }

    [RegularExpression(@"\w*", ErrorMessage = "Address2 Contains Illegal Characters")]
    public string Address2 { get; set; }

    [RegularExpression(@"\w*",ErrorMessage = "State Contains Illegal Characters")]
    [Required(ErrorMessage = "State is Required")]
    public string State { get; set; }

    [Required(ErrorMessage = "Zip Code is Required")]
    [RegularExpression("\b[0-9]{5}(?:-[0-9]{4})?\b",ErrorMessage = "Please Enter a Valid Zip Code")]
    public string ZipCode { get; set; }

    [Required(ErrorMessage = "Even in theater, you have to choose a gender")]
    public bool? Gender { get; set; }

    [Required(ErrorMessage = "Cell Phone Number is Required")]
    public string CellPhone { get; set; }

    public int ActorId { get; set; }

    [DataType(DataType.MultilineText, ErrorMessage = "Illegal Characters in Notes")]
    public string Notes { get; set; }

    [Required(ErrorMessage = "Email Address is Required")]
    [DataType(DataType.EmailAddress)]
    public string EMail { get; set; }

    [Required(ErrorMessage = "City Is Required")]
    public string City {get; set;}
}

<fieldset>
<legend>Fields</legend>
<p>
    <label for="MiddleName">MiddleName:</label>
    <%= Html.EditorFor(m=>m.MiddleName) %>
    <%= Html.ValidationMessage("MiddleName", "*") %>
</p>
<p>
    <label for="FirstName">FirstName:</label>
    <%=Html.EditorFor(m=>m.FirstName) %>
    <%= Html.ValidationMessage("FirstName", "*") %>
</p>
<p>
    <label for="LastName">LastName:</label>
    <%= Html.TextBox("LastName", Model.LastName) %>
    <%= Html.ValidationMessage("LastName", "*") %>
</p>
<p>
    <label for="PhoneNumber">PhoneNumber:</label>
    <%= Html.TextBox("PhoneNumber", Model.PhoneNumber) %>
    <%= Html.ValidationMessage("PhoneNumber", "*") %>
</p>
<p>
    <label for="Address">Address:</label>
       <%=Html.EditorFor(m=>m.Address) %>
       <%= Html.ValidationMessage("Address", "*") %>
</p>
<p>
    <label for="Address2">Address2:</label>
       <%=Html.EditorFor(m=>m.Address2) %>
    <%= Html.ValidationMessage("Address2", "*") %>
</p>
<p>
    <label for="State">State:</label>
    <%= Html.TextBox("State", Model.State) %>
    <%= Html.ValidationMessage("State", "*") %>
</p>
<p>
    <label for="ZipCode">ZipCode:</label>
    <%= Html.TextBox("ZipCode", Model.ZipCode) %>
    <%= Html.ValidationMessage("ZipCode", "*") %>
</p>
<p>
    <label for="Gender">Gender:</label>
    <%= Html.TextBox("Gender", Model.Gender) %>
    <%= Html.ValidationMessage("Gender", "*") %>
</p>
<p>
    <label for="CellPhone">CellPhone:</label>
    <%= Html.TextBox("CellPhone", Model.CellPhone) %>
    <%= Html.ValidationMessage("CellPhone", "*") %>
</p>
<p>
    <label for="ActorId">ActorId:</label>
    <%= Html.TextBox("ActorId", Model.ActorId) %>
    <%= Html.ValidationMessage("ActorId", "*") %>
</p>
<p>
    <label for="Notes">Notes:</label>
    <%= Html.TextBox("Notes", Model.Notes) %>
    <%= Html.ValidationMessage("Notes", "*") %>
</p>
<p>
    <label for="EMail">EMail:</label>
    <%= Html.TextBox("EMail", Model.EMail) %>
    <%= Html.ValidationMessage("EMail", "*") %>
</p>
<p>
    <label for="City">City:</label>
    <%= Html.TextBox("City", Model.City) %>
    <%= Html.ValidationMessage("City", "*") %>
</p>
<p>
    <input type="submit" value="Save" />
</p>
</fieldset>

The following is the code for my controller:

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Edit(int id, Actor actor)
    {

        try
        {
            actorRepository.Save(actor);
            return RedirectToAction("Index");
        }
        catch
        {
            return View("Edit");
        }
    }

The view that calls has a partial view that is strongly typed to the Actor class. For some reason, there are a few fields that are not being bound to the class. The fields in question are Address, Address2, and ZipCode. They are populated on the page, but they come back null. Every other field is there, just not these.

Any ideas? Also, how could I write a unit test to duplicate this behavior?

Update
public class Actor
{
public string MiddleName{ get; set;}

    [Required(ErrorMessage = "First Name is Required")]
    [RegularExpression(@"\w*", ErrorMessage = "Last Name Contains Illegal Characters")]
    public string FirstName { get; set; }

    [Required(ErrorMessage = "Last Name is Required")]
    [RegularExpression(@"\w*", ErrorMessage = "Last Name Contains Illegal Characters")]
    public string LastName { get; set; }

    [DataType(DataType.PhoneNumber, ErrorMessage = "Please Enter a Valid Phone Number")]
    [Required(ErrorMessage = "Phone Number is Required")]
    public string PhoneNumber { get; set; }

    [Required(ErrorMessage = "Address is Required")]
    [RegularExpression(@"\w*", ErrorMessage = "Address Contains Illegal Characters")]
    public string Address { get; set; }

    [RegularExpression(@"\w*", ErrorMessage = "Address2 Contains Illegal Characters")]
    public string Address2 { get; set; }

    [RegularExpression(@"\w*",ErrorMessage = "State Contains Illegal Characters")]
    [Required(ErrorMessage = "State is Required")]
    public string State { get; set; }

    [Required(ErrorMessage = "Zip Code is Required")]
    [RegularExpression("\b[0-9]{5}(?:-[0-9]{4})?\b",ErrorMessage = "Please Enter a Valid Zip Code")]
    public string ZipCode { get; set; }

    [Required(ErrorMessage = "Even in theater, you have to choose a gender")]
    public bool? Gender { get; set; }

    [Required(ErrorMessage = "Cell Phone Number is Required")]
    public string CellPhone { get; set; }

    public int ActorId { get; set; }

    [DataType(DataType.MultilineText, ErrorMessage = "Illegal Characters in Notes")]
    public string Notes { get; set; }

    [Required(ErrorMessage = "Email Address is Required")]
    [DataType(DataType.EmailAddress)]
    public string EMail { get; set; }

    [Required(ErrorMessage = "City Is Required")]
    public string City {get; set;}
}

<fieldset>
<legend>Fields</legend>
<p>
    <label for="MiddleName">MiddleName:</label>
    <%= Html.EditorFor(m=>m.MiddleName) %>
    <%= Html.ValidationMessage("MiddleName", "*") %>
</p>
<p>
    <label for="FirstName">FirstName:</label>
    <%=Html.EditorFor(m=>m.FirstName) %>
    <%= Html.ValidationMessage("FirstName", "*") %>
</p>
<p>
    <label for="LastName">LastName:</label>
    <%= Html.TextBox("LastName", Model.LastName) %>
    <%= Html.ValidationMessage("LastName", "*") %>
</p>
<p>
    <label for="PhoneNumber">PhoneNumber:</label>
    <%= Html.TextBox("PhoneNumber", Model.PhoneNumber) %>
    <%= Html.ValidationMessage("PhoneNumber", "*") %>
</p>
<p>
    <label for="Address">Address:</label>
       <%=Html.EditorFor(m=>m.Address) %>
       <%= Html.ValidationMessage("Address", "*") %>
</p>
<p>
    <label for="Address2">Address2:</label>
       <%=Html.EditorFor(m=>m.Address2) %>
    <%= Html.ValidationMessage("Address2", "*") %>
</p>
<p>
    <label for="State">State:</label>
    <%= Html.TextBox("State", Model.State) %>
    <%= Html.ValidationMessage("State", "*") %>
</p>
<p>
    <label for="ZipCode">ZipCode:</label>
    <%= Html.TextBox("ZipCode", Model.ZipCode) %>
    <%= Html.ValidationMessage("ZipCode", "*") %>
</p>
<p>
    <label for="Gender">Gender:</label>
    <%= Html.TextBox("Gender", Model.Gender) %>
    <%= Html.ValidationMessage("Gender", "*") %>
</p>
<p>
    <label for="CellPhone">CellPhone:</label>
    <%= Html.TextBox("CellPhone", Model.CellPhone) %>
    <%= Html.ValidationMessage("CellPhone", "*") %>
</p>
<p>
    <label for="ActorId">ActorId:</label>
    <%= Html.TextBox("ActorId", Model.ActorId) %>
    <%= Html.ValidationMessage("ActorId", "*") %>
</p>
<p>
    <label for="Notes">Notes:</label>
    <%= Html.TextBox("Notes", Model.Notes) %>
    <%= Html.ValidationMessage("Notes", "*") %>
</p>
<p>
    <label for="EMail">EMail:</label>
    <%= Html.TextBox("EMail", Model.EMail) %>
    <%= Html.ValidationMessage("EMail", "*") %>
</p>
<p>
    <label for="City">City:</label>
    <%= Html.TextBox("City", Model.City) %>
    <%= Html.ValidationMessage("City", "*") %>
</p>
<p>
    <input type="submit" value="Save" />
</p>
</fieldset>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一抹淡然 2024-08-16 02:56:54

有一个名为 ConvertEmptyStringsToNull(默认 = true),将 ASP.MVC 的 DefaultModelBinder 类中的空字符串转换为 NULL。

您可以通过每个属性上的 DataAnnotation 来更改此设置,如下所示:

[DisplayFormat(ConvertEmptyStringToNull=false)]

或者您可以创建自己的 ModelBinder 并从 DefaultModelBinder 继承,然后重写 GetPropertyValue 方法以忽略此设置,如下所示:

ModelBinders.Binders.DefaultBinder = new Delphi.Mvc.KeepStringsBinder ();
ModelBinders.Binders.Add(typeof(ObjectBase), new Delphi.Mvc.KeepStringsBinder());

There's a ModelMetaData property called ConvertEmptyStringsToNull (default = true) that converts empty strings to NULL in the DefaultModelBinder class of ASP.MVC.

You can either change this via a DataAnnotation on each property like this:

[DisplayFormat(ConvertEmptyStringToNull=false)]

or you can create your own ModelBinder and inherit from DefaultModelBinder and just override the GetPropertyValue method to ignore this setting like this:

ModelBinders.Binders.DefaultBinder = new Delphi.Mvc.KeepStringsBinder();
ModelBinders.Binders.Add(typeof(ObjectBase), new Delphi.Mvc.KeepStringsBinder());

今天小雨转甜 2024-08-16 02:56:54

以下是测试模型绑定程序的方法:

如何测试自定义ASP.NET MVC 中的模型绑定器?

只有您会测试 DefaultModelBinder。

至于字段,您还没有显示 Actor 源代码。但既然您谈论了字段,我猜您确实使用了字段 - 但 ASP.NET MVC 模型绑定器不会绑定到字段 - 只会绑定到属性。因此,如果您有,

public class Actor
{
   public string ZipCode;
}

则需要更改为

public class Actor
{
   public string ZipCode { get; set; }
}

另一个原因可能是您有

public class Actor
{
   public Address Address { get; set; }
}

并且使用部分来显示地址;因此它被命名为“ZipCode”,但必须命名为“Address.ZipCode”。或者您的 Address 可能没有无参数构造函数...换句话说,在没有看到源代码的情况下,有太多的猜测。

有了更新信息,这是没有意义的。坏字段看起来和好字段一样。但尝试 Html.TextBox 而不是 EditorFor。尝试使用 FireBug(或 IE Dev)查看 POST 数据,检查字段名称和值是否正确。如果他们这样做 - 问题出在模型绑定器上,如果他们坏/不存在 - 页面有问题。另外,尝试检查控制器操作中的 ModelState.IsValid 以及 ModelState 错误。

Here's how you can test model binders:

How to test custom Model Binders in ASP.NET MVC?

Only you will test DefaultModelBinder.

As for fields, you haven't shown the Actor source code. But since you talk about fields, I'd guess that you really use fields - but ASP.NET MVC model binders won't bind to fields - only to properties. So if you have

public class Actor
{
   public string ZipCode;
}

you'll need to change to

public class Actor
{
   public string ZipCode { get; set; }
}

Another reason may be that you have

public class Actor
{
   public Address Address { get; set; }
}

and you use partial to show Address; so it's named "ZipCode" but it has to be named "Address.ZipCode". Or maybe your Address doesn't have parameterless constructor... In other words, without seeing the source code there's too much to guess.

With update info, this is non-sense. Bad fields look the same as good ones. But try Html.TextBox instead of EditorFor. Try to look at POST data using FireBug (or IE Dev), check that fields names and values come correctly. If they do - the problem is with model binder, if they're bad/absent - something's wrong with the page. Also, try to check ModelState.IsValid in your controller action, as well as ModelState errors.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文