3

Consider the custom model binder below:

[ModelBinder(typeof(CustomModelBinder))]
public class StreamModel
{
    public MemoryStream Stream
    {
        get;
        set;
    }
}

public class CustomModelBinder : IModelBinder
{
    public async Task BindModelAsync(ModelBindingContext bindingContext)
    {
        var request = bindingContext.HttpContext.Request;
        var ms = new MemoryStream();
        request.Body.CopyTo(ms);
        bindingContext.Result = ModelBindingResult.Success(new StreamModel
        {
            Stream = ms
        });
    }
}

Value of ms.Length always equals to 0. Are there any ways to read request Body in a ModelBinder?

Also the below scenario seems weird to me:

public class TestController : Controller
{
    [HttpPost]
    public IActionResult Test(string data)
    {
        var ms = new MemoryStream();
        request.Body.CopyTo(ms);
        return OK(ms.Length);
    }
}

It always returns 0. But when removing parameter string data, it returns actual length of posted body.

Nkosi
  • 235,767
  • 35
  • 427
  • 472
Ashkan Nourzadeh
  • 1,922
  • 16
  • 32
  • Possible duplicate of [Read request body twice](https://stackoverflow.com/questions/31389781/read-request-body-twice) – ctyar Jan 18 '18 at 09:39

1 Answers1

2

The problem is you are trying to read the request body multiple times.

For a workaround and more information, you should take a look at this question: Read request body twice

ctyar
  • 931
  • 2
  • 10
  • 22
  • using `app.Use(next => context => { context.Request.EnableRewind(); return next(context); });` works but I didn't read the request.Body multiple times. (I think mvc does this internally). (gonna create an issue for this in mvc repo on github) – Ashkan Nourzadeh Jan 17 '18 at 09:53