MVC Api控制器与JSON.stringify混淆

时间:2015-05-08 12:13:51

标签: jquery ajax json asp.net-mvc umbraco

我知道如何发布到Umbraco的Api控制器,这不是问题。

问题:

我们说我们有(2)Api方法:

    [HttpPost]
    public string Test1(string time, string activityType)
    {
        return time;
    }

    [HttpPost]
    public string Test2(SomeModel model)
    {
        return model.SomeProperty;
    }

在第一个方法/ ajax调用中,如果我将" time"和" activityType",我收到此错误:

url: '/Umbraco/api/SomeApi/Test1',
type: 'POST',
dataType: 'json',
data: JSON.stringify({time: '10', activityType: 'test'}),

UmbracoApiController - 未找到与请求URI匹配的HTTP资源

相反,我必须将(2)参数作为查询字符串附加,并且它可以工作。但是,在第二个Api方法中,我有一个模型,我可以使用stringify方法用于JSON,它可以工作。

为什么呢?这与普通的MVC一样吗?

我们有(2)ajax调用,这些都有效:

// you can see that I have to append via querystring in this instance
$.ajax({
        url: '/Umbraco/api/SomeApi/Test1?time=' + time + '&activityType=' + activityType,
        type: 'POST',
        dataType: 'json',
        data: '',
        // doesn't work ****
        // url: '/Umbraco/api/SomeApi/Test1',
        // data: JSON.stringify({time: '10', activityType: 'test'}),
        // **********************
        processData: false,
        async: false,
        contentType: 'application/json; charset=utf-8',
        complete: function (data) {
            var test= $.parseJSON(data.responseText);
            console.log(test);
        },
        error: function (response) {
            console.log(response.responseText);
        }
    });

var post = {
   SomeProperty : 'test',
   AnotherProperty: 'blahblah'
};

$.ajax({
        url: '/Umbraco/api/SomeApi/Test2',
        type: 'POST',
        dataType: 'json',
        data: JSON.stringify(post),
        processData: false,
        async: false,
        contentType: 'application/json; charset=utf-8',
        complete: function (data) {
            var test= $.parseJSON(data.responseText);
            console.log(test);
        },
        error: function (response) {
            console.log(response.responseText);
        }
    });

2 个答案:

答案 0 :(得分:4)

WebAPI的模型绑定器在绑定“简单”类型(如字符串)时默认查找查询字符串。这与MVC不同。使用[FromBody]属性告诉它它应该在请求正文中查找。

public string Test1([FromBody]string time, [FromBody]string activityType)

编辑:事实证明,WebAPI将主体读取为流而不是像MVC一样缓存它。这意味着[FromBody]只能应用于一个参数。您需要在URI中传递一个,在正文中传递一个,或者创建包含两个参数的复杂类型。

答案 1 :(得分:2)

此行为是设计完好的documented

  
      
  • 如果参数是“简单”类型,则Web API会尝试从URI中获取值。简单类型包括.NET基元类型(int,bool,double等),以及TimeSpan,DateTime,Guid,decimal和string,以及具有可以从字符串转换的类型转换器的任何类型。 (稍后将详细介绍类型转换器。)
  •   
  • 对于复杂类型,Web API会尝试使用媒体类型格式化程序从邮件正文中读取值
  •   

要强制Web API在正文中查找简单类型,可以使用[FromBody]属性修饰参数,例如

public string Test1([FromBody]string time, [FromBody]string activityType)