【问题标题】:WebApi 2 POST with single string parameter not working带有单个字符串参数的 WebApi 2 POST 不起作用
【发布时间】:2016-10-16 23:16:26
【问题描述】:

我有以下控制器:

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 方法(发布)

【问题讨论】:

  • 在 web api 方法中添加 [HttpPost] 在您的评论下方。另外我认为 URL 是区分大小写的,在 javascript 中它可能应该读为Values,大写为V
  • 试过但同样的错误
  • 此外,如果您通过 http 消息(而不是 url)发送数据,您应该将 [FromBody] 添加到方法签名中。 ([FromBody] string filterName)
  • 您的控制器方法需要一个字符串,但您正在向它传递一个对象 { filterName: "Dirty Deeds" }。那是一个具有 filterName 属性的 javascript 对象。您的控制器不期望具有 filterName 属性的对象,而只是一个字符串。
  • 当我使用 FromBody 时,参数 filterName 为空

标签: javascript c# asp.net-web-api asp.net-web-api2


【解决方案1】:

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

【讨论】:

  • 这没有给出 http 错误但参数 filterName 为空
  • @DannyH - 我更新了 javascript 并对其进行了测试,这行得通。
  • 嗨,它也适用于我。三个问题: 为什么我需要[FormBody] 传递对象时是否也需要这个?为什么 ContentType: 'application/x-www-form-urlencoded' 为什么是 "=Dirty Deeds"
  • 当传递 1 个字符串和 1 个对象时,我该如何处理?同样的方式?
  • @DannyH - Web API 将只允许在消息正文中传递单个对象。因此,您应该创建一个您期望的聚合类型,其中包含您期望的所有数据,并使用我发布的第二个示例将其传递。如果您有简单的类型(int、date 等),您可以将它们作为 FromUri 传递并在查询字符串中传递。
【解决方案2】:

[FromBody] 添加到API 方法签名中,例如public IHttpActionResult Post([FromBody]string filterName),并用引号将ajax 数据参数括起来:data: '"' + bodyContent + '"'

不是很直观,但很有效。

【讨论】:

  • @SachinPakale 您可以通过更改参数类型来执行相同的操作。 (int filterNumber)。 Controller 应该自动将传递的值转换为 String
猜你喜欢
  • 2016-03-30
  • 1970-01-01
  • 2019-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多