ASPNET MVC - 为什么 ModelState.IsValid false “The x field is required”该字段什么时候有值?

发布于 2024-08-31 22:36:43 字数 1981 浏览 4 评论 0原文

我有一个这样的模型:

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,并显示错误:“订单号字段是必须的。”但是这个字段是有值的(??为什么)

为什么它有值的时候会说“value is required”?我错过了什么吗?是因为$.post而不是submit吗?我能做些什么?

调试器如下所示:

alt 文本 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。 compotoValidator.Validate() 返回 0 个错误。我认为这表明模型没有绑定,但我仍然不知道为什么。

控制器方法实际上看起来像这样(我最初写这个问题时错过了过滤器)

[JsonFilter(Param = "order", JsonDataType = typeof(PurchaseOrder))] 
public JsonResult Save(PurchaseOrder order) { //  etc ... }

并且JsonFilter这样做是为了从json提交的数据中提取POCO:

filterContext.ActionParameters[Param] 
    = jsSerializer.Deserialize(inputContent, JsonDataType);

我在这一行上放置了一个断点,并且顺序有效,加上顺序。 OrderNumber 具有正确的值。

所以仍然悬而未决,但希望这些额外的信息将有助于找到解决方案

I have a model like this:

public PurchaseOrder 
{
    [Required] [StringLength(15)]
    public virtual string OrderNumber {get;set;}
    // etc.        
}

When I submit an order from the view (using $.post, not input type=submit) it goes to my controller class:

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 always returns false, with the error: "The Order Number field is required." But there is a value in this field (?? why)

Why would it say "value is required" when it does have a value? Have I missed something? Is it because of the $.post instead of the submit? What can I do?

This is what the debugger looks like:

alt text http://www.freeimagehosting.net/uploads/f734f3d95d.png

EDIT: Extra info....

I really think that for some reason the model binding is not happening. When I try this code found here: )

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

Then ModelState.IsValid = true. compositeValidator.Validate() returns 0 errors. I think this indicates the model was not bound, but I still don't know why.

The controller method actually looks like this (I missed out the filter when originally writing this question)

[JsonFilter(Param = "order", JsonDataType = typeof(PurchaseOrder))] 
public JsonResult Save(PurchaseOrder order) { //  etc ... }

And the JsonFilter does this to extract the POCO from the json submitted data:

filterContext.ActionParameters[Param] 
    = jsSerializer.Deserialize(inputContent, JsonDataType);

I put a breakpoint on this line, and order is valid, plus order.OrderNumber has the correct value.

So still unresolved, but hopefully this extra info will help with finding a solution

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

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

发布评论

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

评论(3

☆獨立☆ 2024-09-07 22:36:43

您确定错误来自 OrderNumber 字段吗?

奇怪的是,错误消息中的订单号只有两个字。

尝试更改字段的名称或删除所需的标记,以确保这是错误的来源。

Are you sure that the error is coming from the OrderNumber field?

It seems strange that the error message has Order Number in 2 words.

Try changing the name of the field or removing the required tag to make sure that this is where the error is coming from.

寂寞清仓 2024-09-07 22:36:43

您的 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 进行快速检查应该能够告诉您是否发生了这种情况。

There is a chance that your jQuery post is not posting in the right way back to the controller. You may be posting just the order number rather than an object that accurately represents the model. I'd have to see your javascript to be absolutely certain.

The correct way to post to that method would be (assuming your order number is stored in a javascript variable called "orderNumber":

$.post([url to method], 
       { order: { OrderNumber: orderNumber } }, 
       function(json) {
       //Insert code for actions to take after AJAX post returns.
       },
       'json');

If this is the case, then the next step I'd take is to double check that the javascript is indeed capturing the value of your order number and posting it as part of the request. A quick examination through Firebug should be able to tell you if that's happening or not.

软的没边 2024-09-07 22:36:43

好吧,我已经“解决”了它,但我不太明白为什么我所做的改变有帮助。

我必须做三件事:

  1. 删除 json 过滤器(过滤器不绑定)

  2. 将 contentType 更改为 application/json

    $.ajaxSetup({
    内容类型:“application/json;字符集=utf-8”
    });

  3. 使用 MVC futures 下载 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 - 它们似乎只有在内容类型是 application/x 的默认值时才起作用-www-form-urlencoded

所以我问了 2 个后续问题:

  1. 是否可以在 $.post() 调用中设置内容类型?那么我就不需要全局设置它
    Jquery - 如何使 $.post() 使用 contentType=application/json ?

  2. 如果内容类型是application/json,jqrid是否可以工作?
    Jquery - 如何使 $.post() 使用 contentType=application/json ?

Well I have "solved" it, but I do not really understand why the changes I made have helped.

I had to do three things:

  1. Remove the json filter (filters don't bind)

  2. Change the contentType to application/json

    $.ajaxSetup({
    contentType: "application/json; charset=utf-8"
    });

  3. Use the MVC futures download Microsoft.Mvc.dll as described here: http://haacked.com/archive/2010/04/15/sending-json-to-an-asp-net-mvc-action-method-argument.aspx. Where is says to add this to Application_Start() in Global.asax.cs:

    ValueProviderFactories.Factories.Add(new JsonValueProviderFactory());

Now I dont know exactly why that has worked, but it has.

Unfortunately it has had a negative side effect: the contenttype is applied to all $.get() and $.post() methods, and broken all my jqgrids - they only seem to work if the content type is the default of application/x-www-form-urlencoded

So I've asked 2 follow on questions:

  1. Is it possible to set the content type in a $.post() call? Then I wouldn't need to set it globally
    Jquery - How to make $.post() use contentType=application/json?

  2. Is it possible to make jqrid work if the contenttype is application/json?
    Jquery - How to make $.post() use contentType=application/json?

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