【问题标题】:WebAPI 2 [FromBody] parameter not getting setWebAPI 2 [FromBody] 参数未设置
【发布时间】:2016-02-14 06:54:02
【问题描述】:

我有一个非常基本的场景......我觉得我之前已经做过 100 次但由于某种原因它决定不工作并将我的时间浪费在一些琐碎的事情上......

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

我正在尝试传入两个参数,一个来自 Body,一个来自 Uri。它们都是基本类型……一个是Boolean,另一个是Long赞助商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;
}

使用 Postman 和 Advanced REST Client 和 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) {
    });
};

我收到以下错误...

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

由于某种原因,[FromBody] 参数没有随请求一起传递,从而导致错误。当我使参数可以为空时,请求会通过,但正如预期的那样,启用的参数是 NULL?

我的头撞墙了……有什么想法吗?

解决方案

我尝试简单地从 Web 服务调用中删除密钥,但没有成功。相反,我使用可能单独发送到服务的基本数据类型创建了一个数据传输对象 (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;
}

警告

此时我必须承认,虽然我让它在我的 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) {
    });
};

警告解决方案

我发现仅仅将 JSON 对象作为数据负载发送是行不通的。我必须对数据进行“字符串化”,以便将其序列化回 APIValueTypes 参数数据类型。所以从 JQuery 对服务的调用现在看起来像......注意 data 分配......

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 个月后忘记它时,这篇文章仍然会在这里提醒我!!再次感谢!

【问题讨论】:

  • 我一直在研究 [FromBody] 属性的类似问题,结果发现您对 JSON 字符串化的评论似乎是我在尝试将数据填充到时遇到的唯一问题那个参数。感谢您阐明这个小细节。

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


【解决方案1】:

您遇到此问题是因为您没有以 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。

【讨论】:

    【解决方案2】:

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

    只需像这样删除启用:

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

    希望,它对你有用。

    【讨论】:

    • 这也可以工作......虽然我的解决方案在我的 REST 工具中工作,但我仍然无法通过 JQuery(?) 让它工作 - 这只是下一个问题。跨度>
    猜你喜欢
    • 2013-05-15
    • 2021-09-05
    • 1970-01-01
    • 2022-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多