12

I've tried to find a solution for this, but all the ones coming up are for previous versions of ASP.Net.

I'm working with the JWT authentication middleware and have the following method:

private async Task GenerateToken(HttpContext context)
{
    var username = context.Request.Form["username"];
    var password = context.Request.Form["password"];
    //Remainder of login code
}

This gets the sent data as if it was form data, but my Angular 2 front end is sending the data as JSON.

login(username: string, password: string): Observable<boolean> {
    let headers = new Headers({ 'Content-Type': 'application/json' });
    let options = new RequestOptions({ headers: headers });
    let body = JSON.stringify({ username: username, password: password });
        return this.http.post(this._api.apiUrl + 'token', body, options)
            .map((response: Response) => {
                
            });
    }

My preferred solution is to send it as JSON, but I've been unsuccessful in retrieving the data. I know it's sending, because I can see it in fiddler, and if I use Postman and just send form data it works fine.

Basically I just need to figure out how to change this line to read the json data

var username = context.Request.Form["username"];
6
  • why don't you just switch you login function to use Content-Type application/x-www-form-urlencoded and just url encode the json Commented Mar 2, 2017 at 17:06
  • I would like the entire front end to be able to send json rather than having some use json and some use form data. I did actually try this route though and was having a hard time getting the data to send correctly as form data. Even with examples I couldn't get the two to talk to each other correctly. Commented Mar 2, 2017 at 17:09
  • shouldn't you just be able to do this? encodeURIComponent(JSON.stringify({ username: username, password: password })); Commented Mar 2, 2017 at 17:12
  • No, it's more complicated than that. Commented Mar 2, 2017 at 17:13
  • 1
    I'm working with IdentityServer4 and as far as I can tell it does the same thing, which is very annoying Id prefer json as well. If I find an answer I'll let you know Commented Mar 2, 2017 at 17:14

1 Answer 1

13

By the time it gets to your middleware the request stream has already been read, so what you can do here is Microsoft.AspNetCore.Http.Internal.EnableRewind on the Request and read it yourself

Site wide :

Startup.cs
using Microsoft.AspNetCore.Http.Internal;

Startup.Configure(...){
...
//Its important the rewind us added before UseMvc
app.Use(next => context => { context.Request.EnableRewind(); return next(context); });
app.UseMvc()
...
}

OR selective :

private async Task GenerateToken(HttpContext context)
    {
     context.Request.EnableRewind();
     string jsonData = new StreamReader(context.Request.Body).ReadToEnd();
    ...
    }
Sign up to request clarification or add additional context in comments.

5 Comments

Why are you calling EnableRewind in both your middleware and in your GenerateToken method?
With the second option you have to add context.Request.Body.Position = 0; between those two lines. Otherwise the reader returns an empty string because the server had already reached the end of the body on its own.
Interesting, I'm using the 2nd option as is and not hitting that issue. Based on net core 1.1
In .Net Core 2 I had to add context.Request.Body.Position = 0; after the StreamReader otherwise my Post's were getting empty Body.
In ASP.NET Core 5 there is an intentional breaking change to avoid the usage of internal methods. Then new API is EnableBuffering So use context.Request.EnableBuffering(); Instead of context.Request.EnableRewind(); More info: github.com/dotnet/aspnetcore/issues/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.