ASP.NET MVC 5,如何在JSON无效时获取原始JSON / request-body-content?

时间:2018-01-31 03:07:21

标签: asp.net-mvc asp.net-mvc-5

我有以下代码在我的动作方法中获取原始JSON

 var stream = new MemoryStream();

 var context = (HttpContextBase)request.Properties["MS_HttpContext"];
 if (context.Request.InputStream != null)
 {
     context.Request.InputStream.Seek(0, SeekOrigin.Begin);
     context.Request.InputStream.CopyTo(stream);
 }

只要JSON有效并绑定到我的模型,它就能完美运行。直到我发送无效的JSON,如下所示

{
  "firstName" : "John",
  "lastName" : "Doe",
  "address" : {
    street" : "123 Hey Where is the opening quote parkway",
    "city" : "Boston",
    "state" : "MA",
    "zip" : 03051
    }
}

在这种情况下,以下行失败

if (context.Request.InputStream != null)

确切地说,InputStream属性的getter会抛出InvalidOperationException

我在调试器下进一步调查,发现有一个备用流没有抛出异常,显示我的流的长度为201字节(与上面的内容相匹配)并且它有数据。所以我决定改为阅读。

var stream = new MemoryStream();
var task = request.Content.CopyToAsync(stream);
task.Wait();
stream.Seek(0, SeekOrigin.Begin);

上面的代码确实给了我原始的JSON,但它开始将它复制到我的流中,而不是从头开始,但是从我错过了开头的引用。所以我只得到以下部分。

street" : "123 Hey Where is the opening quote parkway",
    "city" : "Boston",
    "state" : "MA",
    "zip" : 03051
    }
}

事实证明,这是绑定器实际使用的流,并且放弃了它无法解析的位置,因此位置设置为字节#72。现在我可以使用Seek方法并将其倒回,但请求.Content实际上不是Stream类型,并且没有公开属性来公开我可以回放的流。

无论我的JSON是否是有效的JSON,如何在我的操作方法中获取原始JSON?

1 个答案:

答案 0 :(得分:0)

在调试器中摆弄上下文之后,我找到了一个在JSON无效的情况下可以工作的流。我不是很高兴以这种方式做到这一点,但是直到有人发布了更好的答案,以下内容对我有用。

Stream stream = null;
try
{
    var context = (HttpContextBase)request.Properties["MS_HttpContext"];
    // The following getter call throws an exception, hence the try-block hack
    stream = context.Request.InputStream;
}
catch (System.Exception)
{
    var context = (OwinContext)request.Properties["MS_OwinContext"];

    stream = context.Request.Body;
}
stream.Seek(0, SeekOrigin.Begin);
var myJson = new StreamReader(stream).ReadToEnd();