WebApi 2使用单个字符串参数的POST方法无法正常工作

40

我有以下控制器:

public class ValuesController : ApiController
{
    // POST api/values
    public IHttpActionResult Post(string filterName)
    {
        return new JsonResult<string>(filterName, new JsonSerializerSettings(), Encoding.UTF8, this);

    }
}

WebApi配置

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional });

我使用这段js代码调用API。

$.ajax(
{
    url: "/api/values/",
    type: "POST",
    dataType: 'json',
    data: { filterName: "Dirty Deeds" },
    success: function (result) {
        console.log(result);
    },
    error: function (xhr, status, p3, p4) {
        var err = "Error " + " " + status + " " + p3;
        if (xhr.responseText && xhr.responseText[0] == "{")
            err = JSON.parse(xhr.responseText).message;
        console.log(err);
    }
});

我收到了一个405方法不允许(post)


2
如果您正在通过HTTP消息(而不是URL)发送数据,则应在方法签名中添加[FromBody]([FromBody] string filterName) - Igor
2
你的控制器方法期望一个字符串,但你传递了一个对象 { filterName: "Dirty Deeds" }。这是一个带有一个 filterName 属性的 JavaScript 对象。你的控制器不期望一个带有 filterName 属性的对象,而只需要一个字符串。 - peinearydevelopment
当我使用FromBody时,参数filterName为空。 - Danny
当我设置数据为:"Dirty deeds"时,它也无法工作。 - Danny
@peinearydevelopment 这对我来说很有意义。 - Sachin Pakale
显示剩余4条评论
2个回答

45

c#

public class ValuesController : ApiController
{
    // POST api/values
    [HttpPost] // added attribute
    public IHttpActionResult Post([FromBody] string filterName) // added FromBody as this is how you are sending the data
    {
        return new JsonResult<string>(filterName, new JsonSerializerSettings(), Encoding.UTF8, this);
    }

JavaScript

$.ajax(
{
    url: "/api/Values/", // be consistent and case the route the same as the ApiController
    type: "POST",
    dataType: 'json',
    data: "=Dirty Deeds", // add an = sign
    success: function (result) {
        console.log(result);
    },
    error: function (xhr, status, p3, p4) {
        var err = "Error " + " " + status + " " + p3;
        if (xhr.responseText && xhr.responseText[0] == "{")
            err = JSON.parse(xhr.responseText).message;
        console.log(err);
    }
});

解释

因为你只发送一个单一值,所以在它前面加上=号,这样它就会被视为表单编码。如果你想要让ajax调用更加清晰明了,也可以添加内容类型。

contentType: 'application/x-www-form-urlencoded'

或者您也可以通过URL发送内容,或在服务器上将内容包装在一个对象中,并在ajax调用中对其进行字符串化。

public class Filter {
    public string FilterName {get;set;}
}

public class ValuesController : ApiController
{
    // POST api/values
    [HttpPost] // added attribute
    public IHttpActionResult Post([FromBody] Filter filter) // added FromBody as this is how you are sending the data
    {
        return new JsonResult<string>(filter.FilterName, new JsonSerializerSettings(), Encoding.UTF8, this);
    }

JavaScript

$.ajax(
{
    url: "/api/Values/", // be consistent and case the route the same as the ApiController
    type: "POST",
    dataType: 'json',
    contentType: 'application/json',
    data: JSON.stringify({FilterName: "Dirty Deeds"}), // send as json
    success: function (result) {
        console.log(result);
    },
    error: function (xhr, status, p3, p4) {
        var err = "Error " + " " + status + " " + p3;
        if (xhr.responseText && xhr.responseText[0] == "{")
            err = JSON.parse(xhr.responseText).message;
        console.log(err);
    }
});

嗨,这对我也有效。三个问题:为什么需要[FormBody]?当传递一个对象时,这也是必需的吗?为什么ContentType是'application/x-www-form-urlencoded'?为什么是“=Dirty Deeds”? - Danny
当我传递一个字符串和一个对象时,我该如何处理?同样的方式吗? - Danny
你的最后一个示例给了我一个空值,过滤器属性FilterName。 JSON.stringify({FilterName: "Dirty Deeds"}) - Danny
如果我必须传递一个整数怎么办?我无法发送整数。我必须更改我的Web API方法以接受“字符串”参数而不是“int”,然后在我的ajax调用中使用data:'“'+ ID +'”'。为什么我无法发送整数?为什么它总是null? - Sachin Pakale
@SachinPakale - 评论区不是提出新问题的正确位置。请使用“提问”按钮提出新问题,并确保包含所有相关细节。 - Igor
显示剩余11条评论

11
[FromBody]添加到 API 方法签名中,例如public IHttpActionResult Post([FromBody]string filterName),并用引号包装ajax数据参数:data: '"' + bodyContent + '"'
虽然不太直观,但这样做可以使它正常工作。

2
@SachinPakale,你可以通过更改参数类型来以同样的方式进行操作。(int filterNumber) Controller 应该自动将传递的值转换为 String - Curiosity

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接