ASP.NET MVC读取原始的JSON POST数据

35
这让我感到疯狂。我正在使用ASP.NET MVC。我有一个控制器,其中包含一个HttpPost操作,作为回调URL被另一个服务器(不在我的控制范围内)调用。我想动态读取发布的JSON,而不使用WebAPI或Model Binding。URL还传递了查询字符串参数。回调URL看起来像这样:http://domain.com/callback?secret=1234。我已尝试使用以下方式之一读取发布的输入:
[HttpPost]
public ActionResult Callback( String secret )
{
    String jsonData = new StreamReader(this.Request.InputStream).ReadToEnd();

    // ...
}

然而 "jsonData" 总是为空或者无内容。

我只想获取已发布的输入并将其放入 JsonFx 中,以便可以动态访问其内容。有什么最简单的方法吗?

更新

我已经发现了以下信息...

虽然上述方式不起作用(jsonData 将为空或无内容),但是如果我在调用服务器端配置了我所拥有的极少数选项,使其省略 "secret" 查询字符串参数,则以下方式可以工作,因为这是我能在那一端做的所有事情,因为那不是我的服务器。在这种情况下,jsonData 将具有正确的已发布 JSON 字符串:

[HttpPost]
public ActionResult Callback( /* String secret */ )
{
    String jsonData = new StreamReader(this.Request.InputStream).ReadToEnd();

    // ...
}

在标准MVC控制器上同时接受查询字符串和已发布的JSON数据是非常棘手的问题,我不知道是否有简单的方法。

我有一个“回调控制器”,其中包含接受来自不同第三方服务器的各种数据的操作方法(通过GET、表单POST、JSON POST、带查询字符串的JSON POST等)。这些都是商家类型的回调,在传递信息的格式或方法方面我没有任何控制权。我只需要接受回调并处理应该存在的信息。

在我的控制器中,所有这些都能很好地运行,除了“带查询字符串的JSON POST”这种情况。

这似乎(至少对我来说)是标准ASP.NET MVC控制器的一个缺陷。 ???

有人能建议一种解决方案,可以在标准ASP.NET MVC控制器中使用吗?


当您发布它时,请确保所有的JSON都等于jsonData。例如:[{jsonData: [{ ... all json stuff ... }]}];我还没有测试过,但可能会起作用。 - mnsr
我无法控制发布信息的服务器。我在上面添加了一个更新。 - lantram
为什么选择名称“jsonData”?JSON数据可能使用不同的名称传递,尝试检查FormCollection以获取名称。 - tkt986
3个回答

64

如果您考虑到ASP.NET MVC模型绑定已经读取了流,那么您的初始方法应该有效,因此您应该将其倒回:

[HttpPost]
public ActionResult Callback(string secret)
{
    Request.InputStream.Seek(0, SeekOrigin.Begin);
    string jsonData = new StreamReader(Request.InputStream).ReadToEnd();

    // ...
}

1
太棒了!非常感谢。我知道一定有一个简单的解决方案。 - lantram
这段代码是可行的,但你有关于这个问题的任何想法吗?http://stackoverflow.com/questions/21441571/get-post-request-parameters-in-custom-authorizeattribute - PUG

3
对于 ASP.NET Core 2,这对我有效。
    [HttpPost]
    public ActionResult RawTest() {
        using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8))
        {  
            string content = reader.ReadToEndAsync().Result;
            //...
        }
        //...
    }

3

在读取流之前,将position重置为ZeroRequest.InputStream.Position = 0


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接