在 MVC5 中使用表单发布数据时模型状态无效
Invalid model state in Posting data with form in MVC5
我是 Asp.net MVC 的新手
我想填写一个表格并post它到数据库,但我的模型 Binder 验证是错误的。我的模型中的错误没有显示
抱歉,我不知道是什么问题,我无法缩短它:
这是我的模型:
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>
}
我省略了一些表单组,它们允许 shorthand 为空。
这是我在请求控制器中的创建操作:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Id,TourId,FirstName,LastName,Email,Phone,Comment,FrequentTraveler,TravelersCount,Date,ContactTimePreference,Country,Archived")] Request request)
{
if (ModelState.IsValid)
{
db.Requests.Add(request);
db.SaveChanges();
return RedirectToAction("Index");
}
return View();
}
如果有人告诉我制作我的请求对象有什么问题,我将不胜感激 valid.and 如果可能的话,如何向用户发送错误,例如当他们将 null 放入其所需的名字中时服务器。
您不应使用与参数相同的名称作为模型名称,这会在返回时中断绑定过程。尝试从
更改签名
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 上放置一个断点,你会看到错误是什么,但我很确定这是因为你使用的名称没有正确的绑定(事实上我会更改名称 Request for something其他完全但那只是我)。
希望对您有所帮助。
ModelState
将无效,因为您的视图正在为与您在 POST 方法中期望的模型不同的模型生成表单控件。例如
@Html.EditorFor(model => model.Request.FirstName, ...)
正在发电
<input type="text" name="Request.FirstName" .... />
但是 POST 方法中的模型是 Request
,它没有一个名为 Request
的 属性 - 它只有一个名为 FirstName
所以由于 [Required]
验证属性,绑定失败并且 ModelState
无效。
为了绑定到 Request
模型,html 需要
<input type="text" name="FirstName" .... />
此外,您的 [Bind]
属性也排除了正确绑定的值,因为它确实包含 "Request"
.
删除 [Bind]
属性(您似乎想要绑定所有内容,这是默认设置)并更改 POST 方法中的模型以匹配您在视图中声明的模型, 或者使用 BindAttribute
的 Prefix
属性
public ActionResult Create([Bind(Prefix= "Request")] Request model)
最后删除隐藏输入的手动 html 并使用 @Html.HiddenFor(m => m.Request.TourId)
等,以便名称属性一致并正确绑定。
最后,推荐大家阅读What is ViewModel in MVC?。在您的视图中使用数据模型,尤其是在编辑表单时是一种糟糕的做法。
旁注:您可以在 POST 方法中使用以下查询来轻松检查存在验证错误的模型属性
var errors = ModelState.Keys.Where(k => ModelState[k].Errors.Count > 0).Select(k => new
{
propertyName = k,
errorMessage = ModelState[k].Errors[0].ErrorMessage
});
我是 Asp.net MVC 的新手
我想填写一个表格并post它到数据库,但我的模型 Binder 验证是错误的。我的模型中的错误没有显示
抱歉,我不知道是什么问题,我无法缩短它:
这是我的模型:
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>
}
我省略了一些表单组,它们允许 shorthand 为空。
这是我在请求控制器中的创建操作:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Id,TourId,FirstName,LastName,Email,Phone,Comment,FrequentTraveler,TravelersCount,Date,ContactTimePreference,Country,Archived")] Request request)
{
if (ModelState.IsValid)
{
db.Requests.Add(request);
db.SaveChanges();
return RedirectToAction("Index");
}
return View();
}
如果有人告诉我制作我的请求对象有什么问题,我将不胜感激 valid.and 如果可能的话,如何向用户发送错误,例如当他们将 null 放入其所需的名字中时服务器。
您不应使用与参数相同的名称作为模型名称,这会在返回时中断绑定过程。尝试从
更改签名
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 上放置一个断点,你会看到错误是什么,但我很确定这是因为你使用的名称没有正确的绑定(事实上我会更改名称 Request for something其他完全但那只是我)。
希望对您有所帮助。
ModelState
将无效,因为您的视图正在为与您在 POST 方法中期望的模型不同的模型生成表单控件。例如
@Html.EditorFor(model => model.Request.FirstName, ...)
正在发电
<input type="text" name="Request.FirstName" .... />
但是 POST 方法中的模型是 Request
,它没有一个名为 Request
的 属性 - 它只有一个名为 FirstName
所以由于 [Required]
验证属性,绑定失败并且 ModelState
无效。
为了绑定到 Request
模型,html 需要
<input type="text" name="FirstName" .... />
此外,您的 [Bind]
属性也排除了正确绑定的值,因为它确实包含 "Request"
.
删除 [Bind]
属性(您似乎想要绑定所有内容,这是默认设置)并更改 POST 方法中的模型以匹配您在视图中声明的模型, 或者使用 BindAttribute
Prefix
属性
public ActionResult Create([Bind(Prefix= "Request")] Request model)
最后删除隐藏输入的手动 html 并使用 @Html.HiddenFor(m => m.Request.TourId)
等,以便名称属性一致并正确绑定。
最后,推荐大家阅读What is ViewModel in MVC?。在您的视图中使用数据模型,尤其是在编辑表单时是一种糟糕的做法。
旁注:您可以在 POST 方法中使用以下查询来轻松检查存在验证错误的模型属性
var errors = ModelState.Keys.Where(k => ModelState[k].Errors.Count > 0).Select(k => new
{
propertyName = k,
errorMessage = ModelState[k].Errors[0].ErrorMessage
});