无法在WebAPI中读取动态对象FromBody

时间:2019-01-24 14:00:05

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

我找到了很多有关该主题的信息,但是这些站点和文章都无法解决我的问题。我有一个非常简单的方法:

[HttpPost, Route("Diagnosis/{lkNo}/Tree/{nodeID:int}/Answer")]
public List<TreeNode> AnswerTreeNode(string lkNo, int nodeID, 
[FromBody] dynamic data) {
    // So some stuff
}

当我调用该方法时,它会填充前两个参数,但数据始终为null。这是服务器收到的我的测试请求:

POST /Diagnosis/LK-28084453/Tree/0/Answer HTTP/1.1
Cache-Control: no-cache
Connection: keep-alive
Accept: */*
Accept-Encoding: gzip, deflate
Cookie: ASP.NET_SessionId=*****; __RequestVerificationToken=*****
Host: localhost:51124
User-Agent: PostmanRuntime/7.6.0
Postman-Token: *****
Content-Length: 5
Content-Type: application/x-www-form-urlencoded

=Test

将参数发送为json会得到相同的结果:

...
Content-Length: 25
Content-Type: application/json

{ "value": "some value" }

无论我尝试什么,数据始终为空。这是我的路线配置:

// WebAPI
GlobalConfiguration.Configure(config => {
    config.MapHttpAttributeRoutes();

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

    // Default return JSON
    config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("text/html"));
    config.Formatters.JsonFormatter.SerializerSettings.ContractResolver =
        new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver();

    config.MessageHandlers.Add(new MyHandler());
});

public class MyHandler : System.Net.Http.DelegatingHandler {
    protected override async System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> SendAsync(
                                             System.Net.Http.HttpRequestMessage request,
                                                System.Threading.CancellationToken token) {
        System.Net.Http.HttpMessageContent requestContent = new System.Net.Http.HttpMessageContent(request);
        string requestMessage = requestContent.ReadAsStringAsync().Result; // This one contains the raw requests as posted abve

        return await base.SendAsync(request, token);
    }
}

您有个主意吗,这是怎么回事?

2 个答案:

答案 0 :(得分:0)

我的建议是不要在方法签名中使用动态类型。

将其更改为字符串,并确保您还要序列化要发送到api的内容。

一旦看到数据输入,就可以使用Newtonsoft Json之类的东西将字符串解析为动态对象,然后从那里获取它。

您的方法将变为:

public List<TreeNode> AnswerTreeNode(string lkNo, int nodeID, 
[FromBody] string data) {
    // parse data into dynamic here
}

答案 1 :(得分:0)

我通过删除临时消息处理程序解决了该问题。另外,我将data属性更改为Newtonsoft的JObject类型。现在,我可以轻松实现自己的例程来解释接收到的数据。例如:

char *recur(char *prefix, int k, int n)
{
    //if base case (have already added all letters), return string
    if (k == 0)
    {
        return prefix;
    }
    //otherwise, add character from CHARS to string
    else
    {
        //make a new array called newPrefix, copy current prefix into it and add new letter from CHARS
        int prefLen = strlen(prefix);
        char newPrefix[prefLen + 2];
        strcpy(newPrefix, prefix);
        newPrefix[prefLen] = CHARS[k-1];
        newPrefix[prefLen + 1] = '\0';
        return recur(newPrefix, k-1, n);
    }
}

这是我的Javascript代码:

if (data["result"].Type == JTokenType.Boolean && data["result"].Value<bool>())

像魅力一样工作!