WebAPI 2 [FromBody]参数未设置

时间:2016-02-14 06:54:02

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

我应该是一个非常基本的场景......我觉得我曾经做过100次,但由于某种原因,它决定不工作,浪费我的时间在一些微不足道的事情......

我正在使用带有属性路由的WebAPI(喜欢它们)。

我正在尝试传递两个参数,一个来自Body,另一个来自Uri。它们都是基本类型...一个是布尔,另一个是赞助商ID。

非常简单的服务签名......

[HttpPut]
[Route("adminAPI/sponsors/{sponsorID:long}/Enable")]
public HttpResponseMessage EnableSponsor([FromBody]Boolean enabled, [FromUri] Int64 sponsorID)
{
    HttpResponseMessage ret = null;
    // does stuff and populates the response
    return ret;
}

使用邮递员和高级REST客户端和JQuery / Chrome我一直收到“错误请求”错误......

var request = function () {

    $.ajax({
        type: 'PUT',
        url: 'http://localhost:50865/adminAPI/Sponsor/23/Enable',
        data: { "enabled": true },
        contentType: "application/json"
    })
    .done(function (data, textStatus, jqXHR) {

        if ([200, 204, 304].indexOf(data.StatusCode) === -1) {

        } else {

        }
    })
    .fail(function (jqXHR, textStatus, errorThrown) {
    });
};

我收到以下错误...

  

参数字典包含参数的空条目   'enabled'的非可空类型'System.Boolean'用于方法   'System.Net.Http.HttpResponseMessage EnableSponsorBanner(布尔,   Int64)'在'WEB.Admin.api.SponsorAPIController'中。可选参数   必须是引用类型,可空类型,或声明为   可选参数。“

由于某种原因,[FromBody]参数未与请求一起传递,从而导致错误。当我使参数为nullable时,请求会通过但是,正如预期的那样,enabled参数是NULL?

我在墙上敲我的头......有什么想法吗?

我尝试从Web Service调用中删除密钥,但没有成功。相反,我创建了一个数据传输对象(DTO),其中包含我可能单独发送给服务的基本数据类型。我可以使用它来传递此模型,以便为此以及将来发出的任何其他请求传递简单的值引用。

//
// The Data Transfer Object
    public class APIValueTypes
    {
        public Boolean booleanValue { get; set; }

        public Int64 longValue { get; set; }

        public String stringValue { get; set; }

        public DateTime dateValue { get; set; }
    }

由于服务知道它正在寻找什么价值,它可以获取它所需要的任何价值。

[HttpPut]
[Route("adminAPI/sponsors/{sponsorID:long}/Enable")]
public HttpResponseMessage EnableSponsor([FromBody]APIValueTypes enabled, [FromUri] Int64 sponsorID)
{
    HttpResponseMessage ret = null;
    Boolean isEnabled = enabled.booleanValue;
    // does stuff and populates the response
    return ret;
}

CAVEAT

我现在必须承认,虽然我在我的REST工具中工作,但我无法让它在我的JQuery实现中工作。所以,虽然我的帖子已经回答了我有另一个问题与JQuery ajax $ ...即使我发送DTO对象服务方法仍然收到null而不是对象...(我怀疑的另一篇文章... - 叹气)

var request = function () {

    $.ajax({
        type: 'PUT',
        url: 'http://localhost/adminAPI/Sponsor/23/Enable',
        data: { "booleanValue": false },
        contentType: "application/json",

    })
    .done(function (data, textStatus, jqXHR) {

        console.log(data);

        if ([200, 204, 304].indexOf(data.StatusCode) === -1) {

        } else {

        }
    })
    .fail(function (jqXHR, textStatus, errorThrown) {
    });
};

CAVEAT SOLUTION

我发现只是将JSON对象作为数据有效负载发送不起作用。我必须“字符串化”数据,以便将其序列化回APIValueTypes参数数据类型。所以现在从JQuery调用服务看起来......注意数据赋值......

var request = function () {

    $.ajax({
        type: 'PUT',
        url: 'http://localhost/adminAPI/Sponsor/23/Enable',
        data: JSON.stringify({ "booleanValue": false }),
        contentType: "application/json",

    })
    .done(function (data, textStatus, jqXHR) {

        console.log(data);

        if ([200, 204, 304].indexOf(data.StatusCode) === -1) {

        } else {

        }
    })
    .fail(function (jqXHR, textStatus, errorThrown) {
    });
};

我希望有人能发现这个小旅程有用,当我在6个月内忘记它时,这篇文章仍然会在这里提醒我!再次感谢!

2 个答案:

答案 0 :(得分:6)

您遇到此问题是因为您没有以ASP.Net Web API期望的格式发送数据。 ASP.net Web API在处理像字符串和值类型(int,bool等)参数的值时需要一些特殊的格式参数标有FromBody属性。

您的ASP.Net Web API需要一个原始类型,但您要发送一个对象{ enabled: true },然后它不会将它绑定到您不是对象的enabled参数。

要使其工作,您必须使用以下代码作为jQuery ajax请求中的数据:

data: { "": true }

请注意,属性名称为空,这将告诉jQuery以此格式=true发送数据。使用该格式,ASP.Net Web API可以将其绑定到您的布尔参数。

要防止该问题,请始终使用ViewModel。

答案 1 :(得分:1)

我遇到了同样的问题,我从请求中删除了密钥,并且已经在我的变量中设置了。

只需删除启用状态:

var request = function () {
$.ajax({
    type: 'PUT',
    url: 'http://localhost:50865/adminAPI/Sponsor/23/Enable',
    data: { "": true },
    contentType: "application/json"
})
.done(function (data, textStatus, jqXHR) {

    if ([200, 204, 304].indexOf(data.StatusCode) === -1) {

    } else {

    }
})
.fail(function (jqXHR, textStatus, errorThrown) {
});

};

或者你可以创建一个像这样的模型:

    public class Model
    {
        public bool Enabled { get; set; }
    }

然后:

[HttpPut]
[Route("adminAPI/sponsors/{sponsorID:long}/Enable")]
public HttpResponseMessage EnableSponsor([FromBody]Model model, [FromUri] Int64 sponsorID)
{
    HttpResponseMessage ret = null;
    // does stuff and populates the response
    return ret;
}

希望,它适用于你。