在MVC5中使用表单发布数据时模型状态无效

时间:2016-06-28 11:00:32

标签: asp.net-mvc forms modelbinder

我在Asp.net MVC中是全新的

我想填写一个表单并将其发布到数据库,但我的模型Binder验证是错误的。而我在模型中的错误并没有显示

对不起,因为我不知道问题是什么,我无法缩短它:

这是我的模特:

function isEmpty(map) {
   for(var key in map) {
      if (map.hasOwnProperty(key)) {
         return false;
      }
   }
   return true;
}

这是我的形式:

public class Request
{
    //pkey
    public virtual int Id { get; set; }
    //Fkey
    public virtual int TourId { get; set; }

    [Required]
    [MaxLength(150, ErrorMessageResourceType = typeof(ErrorResource), ErrorMessageResourceName = "CheckLenght")]
    public virtual string FirstName { get; set; }


    [Required]
    [MaxLength(150, ErrorMessageResourceType = typeof(ErrorResource), ErrorMessageResourceName = "CheckLenght")]
    public virtual string LastName { get; set; }

    [Required]
    [EmailAddress(ErrorMessageResourceType = typeof(ErrorResource), ErrorMessageResourceName = "Email")]
    [MaxLength(150, ErrorMessageResourceType = typeof(ErrorResource), ErrorMessageResourceName = "CheckLenght")]
    public virtual string Email { get; set; }

    [Required]
    public virtual string Phone { get; set; }

    [MaxLength(100000000, ErrorMessageResourceType = typeof(ErrorResource), ErrorMessageResourceName = "CheckLenght")]
    public virtual string Comment { get; set; }


    public virtual bool FrequentTraveler { get; set; }

    [Required]
    [Range(1, 500000)]
    public virtual int TravelersCount { get; set; }


    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}")]
    public virtual string Date { get; set; }


    public virtual bool ContactTimePreference { get; set; }

    [MaxLength(150, ErrorMessageResourceType = typeof(ErrorResource), ErrorMessageResourceName = "CheckLenght")]
    public virtual string Country { get; set; }


    public virtual bool Archived { get; set; }

我省略了一些表格组,它们允许以速记为空。

这是我在请求控制器中的创建操作:

@using (Html.BeginForm("Create", "Request"))
{
  <div class="form-group">
   <input  type="hidden" name="TourId" value="4"/>
  </div>

 <div class="form-group">
 @Html.EditorFor(model => model.Request.FirstName, new { htmlAttributes = new { @class = "form-control" } })
 @Html.ValidationMessageFor(model => model.Request.FirstName, "", new { @class = "text-danger" , placeholder = "FirstName" })

 </div>



<div class="form-group">
 @Html.EditorFor(model => model.Request.LastName, new { htmlAttributes = new { @class = "form-control" } })
 @Html.ValidationMessageFor(model => model.Request.LastName, "", new { @class = "text-danger" })
</div>


<div class="form-group">                                       
@Html.EditorFor(model => model.Request.Email, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Request.Email, "", new { @class = "text-danger" })
</div>

<div class="form-group">
 @Html.EditorFor(model => model.Request.Phone, new { htmlAttributes = new { @class = "form-control" } })
 @Html.ValidationMessageFor(model => model.Request.Phone, "", new { @class = "text-danger" })
</div>


 <div class="form-group ft">
 @Html.EditorFor(model => model.Request.FrequentTraveler)
 @Html.ValidationMessageFor(model => model.Request.FrequentTraveler, "", new { @class = "text-danger" })
    </div>


<div class="form-group">
   <input type="hidden" name="TravelersCount" value="3" />
</div>

  <div class="form-group">
    <input type="hidden" name="TravelersCount" value="3" />
  </div>



}

我很感激,如果有人告诉我使我的请求对象有效的问题是什么。如果它可能做什么来向用户发送错误,例如他们将名字中的null放在服务器所需的名字中。

2 个答案:

答案 0 :(得分:1)

ModelState将无效,因为您的视图正在为模型生成表单控件,该模型与您在POST方法中所期望的模型不同。例如

@Html.EditorFor(model => model.Request.FirstName, ...)

正在生成

<input type="text" name="Request.FirstName" .... />

但是POST方法中的模型是Request,它没有名为Request的属性 - 它只有一个名为FirstName,因此绑定失败,ModelState无效因为[Required]验证属性。

为了绑定到Request模型,html必须是

<input type="text" name="FirstName" .... />

此外,您的[Bind]属性也会排除正确绑定的值,因为它包含"Request"

删除[Bind]属性(您似乎想要绑定所有内容,这是默认设置)并更改POST方法中的模型以匹配您在视图中声明的模型,或使用{{ 1}} Prefix

的属性
BindAttribute

最后删除隐藏输入的手动html并使用public ActionResult Create([Bind(Prefix= "Request")] Request model) 等,以便名称属性一致并正确绑定。

最后,我建议您阅读What is ViewModel in MVC?。在视图中使用数据模型,尤其是在编辑表单时,这种做法很糟糕。

附注:您可以在POST方法中使用以下查询来轻松检查具有验证错误的模型属性

@Html.HiddenFor(m => m.Request.TourId)

答案 1 :(得分:0)

您不应该使用与参数相同的名称作为模型名称,这将在返回途中破坏绑定过程。尝试从

更改签名
  

public ActionResult Create(Request request)

  

public ActionResult Create(Request req)

要检查ModelState错误,请使用以下代码:

foreach (ModelState modelState in ViewData.ModelState.Values)
{
 foreach (ModelError error in modelState.Errors)
 {
    var xx = error.ErrorMessage;
 }
}

如果你在var xx上设置一个断点,你会看到错误是什么,但我很确定这是因为没有正确的绑定因为你使用的名字(实际上我会更改名称请求完全不同于其他内容)但那只是我。)

希望这有帮助。