0

I have an endpoint that looks like:

public IHttpActionResult SignUp([FromBody] AuthInput input)

Whenever the request body includes an escape character "\" the API fails to bind the data to the model. I have a guess that this is because the JSON would be considered "malformed."

I'd like to format the request body before the API attempts to bind it to the model and change all "\" to "\\"

Request body

{
   "email": "mrsmith@usa.com",
   "password": "badpassword\",
   "firstName": "John",
   "lastName": "Smith"
}

The backspace makes the input object "null"

Using c# ASP.NET 4.6.2

Robert Christopher
  • 4,940
  • 1
  • 20
  • 21
BlabzX
  • 105
  • 3
  • 10

1 Answers1

0

If you're generating the request body yourself:

  • Ideally you should be generating your Request Body JSON payload by serializing an existing DTO class.

  • If you can't do that, then you should safely escape string-values for use in directly-rendered JSON using .NET's built-in JavaScript string-escape utility methods:

    • In the .NET Framework Full Profile (so not .NET Core, .NET Standard, or .NET Framework Client Profile) you can use System.Web.HttpUtility.JavaScriptStringEncode.
    • Otherwise, use System.Text.Encodings.Web.JavaScriptEncoder.

If you're receiving bad input that you have no control over:

Approach 1: Work with the request-body directly:

This is the simplest approach, but requires you to do it for every controller action that receives malformed JSON:

public async Task<IHttpActionResult> SignUp()
{
    String requestBody;
    using( StreamReader rdr = new StreamReader( this.Request.Body ) )
    {
        requestBody = await rdr.ReadToEndAsync();
    }

    //

    // Tweak the raw JSON text to make it parseable:
    String requestBodyTweaked = requestBody.Replace( "\\\",", "\"," );

    // Parse it and pass it on to the original `SignUp` method:
    AuthInput dto = JsonConvert.DeserializeObject<AuthInput>( requestBodyTweaked );

    return this.SignUp( dto );
}

// This is your current SignUp action method, it's unchanged except it's now `private`:
private IHttpActionResult SignUp( AuthInput input)
{

}

Approach 2: Middleware to intercept and modify all request bodies:

You could mitigate this using a middleware layer that intercepts the request body - but be very careful.

See this QA for instructions on how to intercept and modify an incoming request body: ASP NET Core modify/substitute a request body

I assume you'd want to edit the raw JSON text rather than parse it:

Dai
  • 141,631
  • 28
  • 261
  • 374