Reputation: 1241
I get an exception when I try to read multi part content from the request saying the content may have already been read by another component.
if (MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
{
// Used to accumulate all the form url encoded key value pairs in the
// request.
var formAccumulator = new KeyValueAccumulator();
var boundary = Request.GetMultipartBoundary();
var reader = new MultipartReader(boundary, HttpContext.Request.Body);
var section = await reader.ReadNextSectionAsync();
while (section != null)
{
ContentDispositionHeaderValue contentDisposition;
var hasContentDispositionHeader =
ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out contentDisposition);
}
}
Upvotes: 22
Views: 40102
Reputation: 49
In addition to disabling form value model binding, I had to update the anti-forgery middleware to stop generating the token when using file upload, by leveraging the Http request "Endpoint Feature".
public async Task InvokeAsync(HttpContext context)
{
var endpoint = context.Features?.Get<Microsoft.AspNetCore.Http.Features.IEndpointFeature>();
if (context.User?.Identity != null &&
context.User.Identity.IsAuthenticated &&
endpoint?.Endpoint?.Metadata.GetMetadata<DisableFormValueModelBindingAttribute>() == null)
{
var tokenSet = antiforgery.GetAndStoreTokens(context);
var requestToken = tokenSet.RequestToken;
if (requestToken != null)
{
context.Response.Cookies.Append(
"XSRF-TOKEN",
requestToken,
new () { HttpOnly = false, Path = "/", Secure = true, SameSite = SameSiteMode.Strict, });
}
}
await next(context);
}
Upvotes: 0
Reputation: 272236
In my case the issue was the payload... the Content-Length
of the request was different from the actual length of the payload. The JavaScript code that was creating the HTTP POST was fixed to get rid of this issue.
Background: The original code looked similar to the Next.js code in this question except that it also included a Content-Length
header that was different from the length of the body. And it was because the body was corrupted by body parser function. The solution is in that question.
Upvotes: 0
Reputation: 1
In my case I forgot IResourceFilter in DisableFormValueModelBindingAttribute. work fine in .Net7
Upvotes: 0
Reputation: 361
In my case, I had to remove the [ValidateAntiForgeryToken]
attribute.
Upvotes: 1
Reputation: 1668
I have this error when send invalid form-data from client. This is valid format: NOTE: two minuses and new line in the end
<empty>
------------------------------8dac95867d24bd1
Content-Disposition: form-data; name="user_login"
<data or empty>
------------------------------8dac95867d24bd1
Content-Disposition: form-data; name="user_password"
<data or empty>
------------------------------8dac95867d24bd1
Content-Disposition: form-data; name="user_session"
<data or empty>
------------------------------8dac95867d24bd1--
<empty>
Upvotes: 1
Reputation: 1499
In my case I had added another filter which was intercepting the file. Even with the filters mentioned above I still got the issue. Removing the honey pot removed the error finally.
.AddMvc(options =>
{
options.Filters.Add(new AuthorizeFilter());
// .... etc
options.AddHoneyPot(); // This was causing the problem
})
Upvotes: 1
Reputation: 101
If you are using MultipartFormDataContent to send the file, at the other side you will receive a mediaTypeHeader.Boundary.Value
with an escaped " at the start & end (eg "\"BoundaryValue\""
).
So by removing it, it started working for me.
The fix for me was to add this at receiver side: .Replace("\"", "")
mediaTypeHeader.Boundary.Value.Replace("\"", "")
Upvotes: 0
Reputation: 11
Just in case someone else is chasing ghosts regarding this error: using net5 web api I had a controller with
[HttpPost]
[Route("api/fileupload/{reportId}")]
[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
public async Task<IActionResult> FileUpload(int reportId)
That wasn't a good idea. It gave the abovementionned error and I remembered having to pass on additional data via file attributes. That solved it for me. Just for completeness. This worked off course
[HttpPost]
[Route("api/fileupload")]
[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
public async Task<IActionResult> FileUpload()
Upvotes: 1
Reputation: 51
This worked for me for netcore 3.1
You need to add
factories.RemoveType<FormFileValueProviderFactory>();
on this method
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class DisableFormValueModelBindingAttribute : Attribute, IResourceFilter
{
public void OnResourceExecuting(ResourceExecutingContext context)
{
var factories = context.ValueProviderFactories;
factories.RemoveType<FormValueProviderFactory>();
factories.RemoveType<FormFileValueProviderFactory>();
factories.RemoveType<JQueryFormValueProviderFactory>();
}
public void OnResourceExecuted(ResourceExecutedContext context)
{
}
}
Upvotes: 5
Reputation: 605
In my specific case, I was using a multipart boundary value which didn't exist in the payload being parsed by the MultipartReader:
// multipartBoundary is not in the contents of httpResponseContentStream.
var multipartBoundary = "batchresponse_63d0e4c7-4d49-4961-a294-3902d1730c44";
var multipartReader = new MultipartReader(multipartBoundary, httpResponseContentStream);
// Unexpected end-of-stream error used to occur here:
var multipartSection = await multipartReader.ReadNextSectionAsync(cancellationToken);
Once the multipartBoundary was updated to reflect an actual boundary value present in the content being parsed, the code worked as expected.
Upvotes: 7
Reputation: 2649
In asp.net core 3, You have to add factories.RemoveType<FormFileValueProviderFactory>();
to your DisableFormValueModelBindingAttribute
attribute.
Code
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class DisableFormValueModelBindingAttribute : Attribute, IResourceFilter
{
public void OnResourceExecuting(ResourceExecutingContext context)
{
var factories = context.ValueProviderFactories;
factories.RemoveType<FormValueProviderFactory>();
factories.RemoveType<FormFileValueProviderFactory>();
factories.RemoveType<JQueryFormValueProviderFactory>();
}
public void OnResourceExecuted(ResourceExecutedContext context)
{
}
}
Upvotes: 39
Reputation: 8539
In my case it was "postman" issue. I sent the file to the REST endpoint. And at some point I started to get this error, but the code was not changed.
I re-selected this file again in "postman" and everything worked as before.
Upvotes: 0
Reputation: 536
There is bug about that in Microsoft.AspNetCore.App 2.1.4
. I updated this package to 2.1.12
version and it resolved.
Upvotes: 0
Reputation: 45
I used [DisableFormValueModelBinding]
but still got error, then i also use:
if (Request.ContentLength == 0)
return BadRequest();
Upvotes: 2
Reputation: 1241
It turns out that I had to disable form value model binding by using the attribute below.
[HttpPost]
[Route("")]
[DisableFormValueModelBinding]
public async Task<IActionResult> Post()
The attribute implementation is below
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class DisableFormValueModelBindingAttribute : Attribute, IResourceFilter
{
public void OnResourceExecuting(ResourceExecutingContext context)
{
var factories = context.ValueProviderFactories;
factories.RemoveType<FormValueProviderFactory>();
factories.RemoveType<JQueryFormValueProviderFactory>();
}
public void OnResourceExecuted(ResourceExecutedContext context)
{
}
}
Upvotes: 24