ASP.NET MVC Read Raw JSON Post Data

22.2k views Asked by At

This is driving me crazy. I'm using ASP.NET MVC. I have a controller with an HttpPost action that acts as a callback URL that is called by another server (not under my control). I want to dynamically read JSON posted to it without using WebAPI or Model Binding. The URL also has a query string parameter passed to it.

The callback URL looks something like this:

http://domain.com/callback?secret=1234

I've tried reading the posted input using:

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

    // ...
}

However "jsonData" is always null or empty.

I just want to get the posted input and stick it into JsonFx so I can dynamically access the contents. Any ideas on how to do this the easiest possible way?

UPDATE

I've discovered the following ...

While the above DOES NOT work (jsonData will be null or empty), the following DOES if I configure what little options I have on the calling server so as to omit the "secret" query string parameter, which is about all I can do on that end since it is not my server. In this case, jsonData will have the correct posted JSON string:

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

    // ...
}

This is very frustrating to work around and I don't know an easy way to accept both a query string and posted JSON data on a standard MVC controller.

I have a "callback controller" with Action methods that accept various data (via GET, via form POST, via JSON POST, via JSON POST w/ a Query String, etc.) from different third-party servers. These are merchant-type callbacks where I have no control over the formats or methods used to convey information. I just need to accept the callbacks and process the information that should be there.

All of it works fine in my Controller, except the case of "JSON POST w/ a Query String".

This appears (at least to me) to be a shortcoming in standard ASP.NET MVC controllers. ???

Can anyone suggest a solution to this that can be used in a standard ASP.NET MVC controller?

3

There are 3 answers

2
tpeczek On BEST ANSWER

Your initial approach should work if you take into consideration the fact, that ASP.NET MVC model binding has already read the stream, so you should rewind it:

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

    // ...
}
0
Abhishek7997 On

Reset the position to Zero before reading the stream. Request.InputStream.Position = 0

0
guogangj On

For ASP.NET Core 2,this works for me.

    [HttpPost]
    public ActionResult RawTest() {
        using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8))
        {  
            string content = reader.ReadToEndAsync().Result;
            //...
        }
        //...
    }