3

我正在使用 ApiController 类在 ASP.NET MVC4 中使用 Web API。API 将根据签名验证进行身份验证检查。每个请求都必须使用 POST 正文和一些密钥进行签名。

我还想使用从 JSON 到对象的模型绑定。

现在我有一个问题。我可以发送 JSON,.net 将它很好地绑定到对象,但我无法进行验证。

当 POST 的 Contenttype 为 application/json 时,如何获取 POST 内容(以发送的确切形式)?

例子

发布内容(应用程序/json):

{message: "blah"}

型号类:

public class RequestModel
{
    public String Message { get; set; }
}

如何在 ApiController 中获取 JSON?

4

4 回答 4

2

您可以使用 将请求正文作为字符串读取request.Content.ReadAsStringAsync();。但是,这在操作方法或过滤器中不起作用。

在 ASP.NET Web API 管道中,模型绑定发生在操作过滤器运行之前,然后操作方法执行。模型绑定器将读取请求正文(这是一个只读流)并清空内容。相反,如果您从在模型绑定之前运行的组件(例如消息处理程序)读取内容,则可以读取请求正文(在您的情况下为 JSON)。

public class MyHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(
                                HttpRequestMessage request,
                                    CancellationToken cancellationToken)
    {
        var messageBody = await request.Content.ReadAsStringAsync();

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

在这里,messageBody 将具有 JSON。最好在此处实现检查,因为处理程序在管道中运行得更早,您将希望尽早强制执行身份验证。

于 2013-07-13T02:38:52.487 回答
0

从 Request 中读取确切的正文还不够吗?:)

Request.InputStream // <--
于 2013-07-12T23:51:48.450 回答
0

与上面@Badri 的回答类似,当您使用 ReadAsStreamAsync() 时,您必须将流的“读取头”返回为零,否则模型绑定将失败,因为流已被消耗

public class MyHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(
                                HttpRequestMessage request,
                                CancellationToken cancellationToken)
    {
        using(var sha = System.Security.Cryptography.SHA256.Create())
        {
            var requestStream = await request.Content.ReadAsStreamAsync();
            var shaHash = sha.ComputeHash(requestStream);
            requestStream.Position = 0; // <-Important!!
        }


        return await base.SendAsync(request, cancellationToken);
    }
}
于 2014-03-28T00:13:12.843 回答
0

请注意,您的 json 消息应该与您的模型完全相同。(消息属性不是消息)

邮政:

{Message: "blah"}

型号类:

public class RequestModel
{
    public String Message { get; set; }
}

控制器:

[System.Web.Http.HttpPost]
public RequestModel PostUser(RequestModel model)
{
  //code
}
于 2013-07-12T18:24:40.133 回答