ASPNET MVC - 当该字段确实有值时,为啥 ModelState.IsValid false“需要 x 字段”?
Posted
技术标签:
【中文标题】ASPNET MVC - 当该字段确实有值时,为啥 ModelState.IsValid false“需要 x 字段”?【英文标题】:ASPNET MVC - Why is ModelState.IsValid false "The x field is required" when that field does have a value?ASPNET MVC - 当该字段确实有值时,为什么 ModelState.IsValid false“需要 x 字段”? 【发布时间】:2011-02-17 01:38:03 【问题描述】:我有一个这样的模型:
public PurchaseOrder
[Required] [StringLength(15)]
public virtual string OrderNumber get;set;
// etc.
当我从视图提交订单时(使用 $.post,而不是输入 type=submit),它会转到我的控制器类:
public class PurchaseOrderController
public JsonResult Save(PurchaseOrder order)
// TryUpdateModel(order); // commented out since modelstate.isvalid remains false anyway
if (ModelState.IsValid)
// its never valid
ModelState.IsValid 始终返回 false,并出现错误:“订单号字段是必需的。”但是这个字段有一个值(??为什么)
当它确实有值时,为什么会说“需要值”?我错过了什么吗?是因为 $.post 而不是提交?我能做什么?
这是调试器的样子:
alt text http://www.freeimagehosting.net/uploads/f734f3d95d.png
编辑:额外信息....
我真的认为由于某种原因模型绑定没有发生。当我尝试这里找到的代码时:)
if (!ModelState.IsValid)
ModelState.Clear();
ModelMetadata modelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => order, order.GetType());
ModelValidator compositeValidator = ModelValidator.GetModelValidator(modelMetadata, base.ControllerContext);
foreach (ModelValidationResult result in compositeValidator.Validate(null))
this.ModelState.AddModelError(result.MemberName, result.Message);
那么 ModelState.IsValid = true。 CompositeValidator.Validate() 返回 0 个错误。我认为这表明模型没有绑定,但我仍然不知道为什么。
控制器方法实际上是这样的(我最初写这个问题时错过了过滤器)
[JsonFilter(Param = "order", JsonDataType = typeof(PurchaseOrder))]
public JsonResult Save(PurchaseOrder order) // etc ...
JsonFilter 这样做是为了从 json 提交的数据中提取 POCO:
filterContext.ActionParameters[Param]
= jsSerializer.Deserialize(inputContent, JsonDataType);
我在这一行下断点,order有效,加上order.OrderNumber的值正确。
所以仍然没有解决,但希望这些额外的信息将有助于找到解决方案
【问题讨论】:
为什么属性标记为虚拟?您在使用 POCO 更改跟踪吗? 价值是多少?您如何使用$.post
?它可以正常提交吗?
我不知道为什么它是虚拟的,当我开始研究现有的应用程序时就是这样。
是的,它适用于普通输入 type=submit 按钮
手动验证模型的代码在这里找到:digitallycreated.net/Blog/54/…
【参考方案1】:
您确定错误来自 OrderNumber 字段吗?
错误信息中的订单号只有 2 个字,这似乎很奇怪。
尝试更改字段名称或删除必需的标记以确保这是错误的来源。
【讨论】:
我相信 MVC 框架会自动为您处理这些问题。它与您使用 html.LabelFor(model.OrderNumber) 时相同。标签上写着“订单号”,单词之间有一个空格。 如果我删除 [Required] 注释,那么 ModelState.IsValid == true。它也是唯一带有此注释的字段。【参考方案2】:您的 jQuery 帖子有可能没有以正确的方式发布回控制器。您可能只发布订单号,而不是准确代表模型的对象。我必须看到你的 javascript 才能确定。
发布到该方法的正确方法是(假设您的订单号存储在名为“orderNumber”的 javascript 变量中:
$.post([url to method],
order: OrderNumber: orderNumber ,
function(json)
//Insert code for actions to take after AJAX post returns.
,
'json');
如果是这种情况,那么我将采取的下一步是仔细检查 javascript 是否确实在捕获您的订单号的值并将其作为请求的一部分发布。通过 Firebug 进行快速检查应该能够告诉您是否发生了这种情况。
【讨论】:
【参考方案3】:好吧,我已经“解决”了它,但我真的不明白为什么我所做的更改会有所帮助。
我必须做三件事:
移除 json 过滤器(过滤器不绑定)
将 contentType 更改为 application/json
$.ajaxSetup( 内容类型:“应用程序/json;字符集=utf-8” );
使用 MVC 期货下载 Microsoft.Mvc.dll,如下所述:http://haacked.com/archive/2010/04/15/sending-json-to-an-asp-net-mvc-action-method-argument.aspx。据说在 Global.asax.cs 中将其添加到 Application_Start() 的位置:
ValueProviderFactories.Factories.Add(new JsonValueProviderFactory());
现在我不知道为什么会这样,但确实有效。
不幸的是,它产生了负面影响:内容类型适用于所有 $.get() 和 $.post() 方法,并破坏了我所有的 jqgrids - 它们似乎只有在内容类型是默认值的情况下才有效应用程序/x-www-form-urlencoded
所以我问了 2 个后续问题:
是否可以在 $.post() 调用中设置内容类型?然后我不需要全局设置它 Jquery - How to make $.post() use contentType=application/json?
如果 contenttype 是 application/json,是否可以使 jqrid 工作? Jquery - How to make $.post() use contentType=application/json?
【讨论】:
看来我需要将调用控制器方法的 $.post() 更改为 $.ajax()。但是感觉就像我做错了什么,如果 contentType 是 application/x-www-form-urlencoded 的默认值,它应该可以工作。以上是关于ASPNET MVC - 当该字段确实有值时,为啥 ModelState.IsValid false“需要 x 字段”?的主要内容,如果未能解决你的问题,请参考以下文章