发布JSON到控制器 [英] Posting JSON to Controller

查看:229
本文介绍了发布JSON到控制器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的控制器得到这个:

I've got this in my controller:

    [HttpPost]
    public void UpdateLanguagePreference(string languageTag)
    {
        if (string.IsNullOrEmpty(languageTag))
        {
            throw new ArgumentNullException("languageTag");
        }

        ...
    }

和有这个jQuery的code张贴到控制器:

And have this jQuery code POSTing to the controller:

           jQuery.ajax({
                type: 'POST',
                url: '/Config/UpdateLanguagePreference',
                contentType: 'application/json; charset=utf-8',
                data: '{ "languageTag": "' + selectedLanguage + '" }'
            });

当我尝试在code,但是,我得到的错误:

When I try to the code, however, I get the error:

Server Error in '/' Application.
Value cannot be null.
Parameter name: languageTag

这是什么问题?这难道不是如何发布JSON到一个MVC控制器?我可以使用招检查POST,看到该请求是正确的。出于某种原因, UpdateLanguage preference()是得到一个空或空字符串。

What's the problem? Isn't this how to POST JSON to an MVC Controller? I can examine the POST using Fiddler and see that the request is correct. For some reason, UpdateLanguagePreference() is getting a null or empty string.

推荐答案

非常重要的警告,即使是在MVC3,关于MVC3的方式工作。

Very important caveat, even in MVC3, about the way MVC3 works.

如果您传递一个对象喜欢说:

If you pass an object like say:

​{
    Test: 'Hi'
}

和接收类是:

public class MyModel
{
    public string Test { get; set; }
}

通过一个接收器的方法,如:

With a receiving Controller method like:

[HttpPost]
public JsonResult Submit(MyModel model)
{
    . . .

这会工作。但是如果你的控制器方法有这种非常小的,看似无害的变化:

It will work. But if your Controller method has this very minor, seemingly harmless change:

[HttpPost]
public JsonResult Submit(MyModel test)
{
    . . .

这将失败。这是因为MVC框架消耗与上述JSON成一个字典,并看到其中的一个参数具有相同的名称,不区分大小写的,因为它的键(测试/测试)中的一个。那么它需要字符串值分配给测试,并传递这样的说法测试,尽管这显然不是作者的意图。

It will fail. This is because the MVC framework consumes the JSON into a Dictionary as mentioned above, and sees that one of the parameters has the same name, case-insensitive, as one of its keys ("Test"/"test"). It then takes the string value "Hi", assigned to Test, and passes that to this argument "test" even though this is obviously not what the author intended.

什么是最容易出问题的这个是,框架不会抛出一个错误尝试将一个字符串赋值给类型为MyModel的阿根廷,这将至少给你一个关于什么地方出了错线索。它并不认为这是错误的类型,并退回到其替代行为(这将有追求过这些ARG /性能在名称不匹配)。它只是默默地失败并分配空你的说法,让你没有线索,这是怎么回事。

What's most problematic about this is that the framework doesn't throw an error trying to assign a string to an arg of type MyModel, which would at least give you a clue about what went wrong. It doesn't see this was the wrong type and fallback to its alternative behavior (that it would have pursued had these arg/properties not matched in name). It simply fails silently and assigns null to your argument, leaving you with no clue as to what's going on.

我碰到的这个问题多次,终于发现,使事情似乎随机停止在MVC工作毛刺......我希望这可以帮助别人。

I've run into this problem repeatedly and finally found the glitch that makes things seem to randomly stop working in MVC... I hope this helps someone else.

由于此操作参数的合理名称是一个潜在的合理的属性名称(模型,数据等),因为它是不区分大小写的,以prevent它最安全的方式,而无需编写自己的模型粘合剂是规范的之一,疯狂的,极不可能到永远是-A-属性名称参数名称,例如:

Since any reasonable name for this Action argument is a potentially reasonable property name (model, data, etc) and since it's case-insensitive, the safest way to prevent it without writing your own model binder is to standardize on one, crazy, very-unlikely-to-ever-be-a-property-name argument name, like:

[HttpPost]
public JsonResult Submit(MyModel _$_$twinkleTwinkleLittleFuckIt)
{

但是,如果你有时间,修复ModelBinder的/ JsonValueProviderFactory所以在十年没有人能够到达的底部有0风险,而不是一个古怪的bug。

But if you have the time, fix the ModelBinder/JsonValueProviderFactory so there's 0 risk instead of that one weird bug in a decade no one can ever get to the bottom of.

这篇关于发布JSON到控制器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆