2

I have an Asp.Net Core 5 Razor Pages. There's a Razor page with a form that the user uses to edit invoices. When the number of items in the form increases substantially (around 500 items) the application returns an HTTP 400 error. Here's the summary of how I handle items and the form:

Page Model

[DisableRequestSizeLimit]
public class EditModel : PageModel
{
    [BindProperty]
    public OrderCreateViewModel Input { get; set; }
    
    //...rest of the code
}

ViewModel

public class OrderCreateViewModel
{
    public int Id { get; set; }
    public int CustomerId { get; set; }
    public string ReceiverName { get; set; }
    public string Address { get; set; }
    public string PostalCode { get; set; }
    public string Phone { get; set; }
    public string DeliveryDate { get; set; }
    public string CustomerName { get; set; }
    //... other fields

    public int[] ItemIds { get; set; }
    public decimal[] Quantities { get; set; }
    public decimal[] Fees { get; set; }
    public decimal[] Discounts { get; set; }
    public decimal[] Taxes { get; set; }
    public decimal[] Duties { get; set; }
    public string[] ItemComments { get; set; }
    public decimal[] Max { get; set; }
}

Razor

<form method="post" enctype="multipart/form-data">
    <input type="hidden" asp-for="Input.Id" />
    <label asp-for="Input.CustomerName"></label>
    <input asp-for="Input.CustomerName" disabled class="form-control" />
    ...

    <table class="table mt-5 w-100 table-bordered table-responsive" id="quotation-items">
        <thead>
            <tr>
                <td>Quantity</td>
                <td>Fee</td>
                ... rest of items...
            </tr>
        </thead>
        <tbody>
            @for (int i = 0; i < Model.Input.ItemIds.Length; i++)
            {
                <tr>
                    <td>
                        <input type="text" name="Input.Quantities[]" value="@Model.Input.Quantities[i].ToString("0.##")" />
                    </td>
                    <td>
                        <input type="text" name="Input.Fees[]" value="@Model.Input.Fees[i].ToString("0.##")" />
                    </td>
                    ... rest of items ...
                </tr>
            }
        </tbody>
    </table>

    <button class="btn btn-primary btn-lg" id="btn-submit">
        Save
    </button>
</form>

How can this be fixed? I already added the [DisableRequestSizeLimit] attribute to the page model but it didn't work. I also tried increasing the limit by changing the web.config file:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
        <httpRuntime maxRequestLength="500000000"  executionTimeout="120" />
    </system.web>
  <location path="." inheritInChildApplications="false">
    <system.webServer>
      <handlers>
        <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
      </handlers>
      <aspNetCore processPath=".\Project.exe" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess" />
<security>
      <requestFiltering>
        <requestLimits maxAllowedContentLength="1073741824" />
      </requestFiltering>
    </security>
    </system.webServer>
  </location>
</configuration>

Edit1:

I did some debugging. For some reason the form works if the number of items are exactly 144 items. I tried with different items.

Alireza Noori
  • 14,961
  • 30
  • 95
  • 179
  • Have you checked the size of the request that fails and what the logs says when it fails? 500 items, even if they where 10kb each (which from your model seems unlikely) is just 5mb of data which is way below the default limit (which is like 30mb or something). – Karl-Johan Sjögren Jul 17 '21 at 10:48
  • @Karl-JohanSjögren That's what I thought. Is there a limit to the number of items in the form though? (either IIS or Asp.Net)? And no, I didn't see the log. – Alireza Noori Jul 17 '21 at 11:04
  • 1
    Hi @AlirezaNoori, Does the error disappear after you configure FormOptions in the Startup.cs? You could check the [FormReader.cs](https://github.com/dotnet/aspnetcore/blob/main/src/Http/WebUtilities/src/FormReader.cs) and [this thread](https://stackoverflow.com/questions/43305220/), by default the ASP.NET Core enforces key/value limits: 1024/2048. So, you could configure the FormOptions as below: `services.Configure(options => { options.ValueLengthLimit = int.MaxValue; options.MultipartBodyLengthLimit = int.MaxValue; options.MultipartHeadersLengthLimit = int.MaxValue; });` – Zhi Lv Jul 20 '21 at 06:18

1 Answers1

3

Please add this to Startup#ConfigureServices

services.Configure<FormOptions>(options => options.ValueCountLimit = 5000);

This will increase your limit to 5000.

Roar S.
  • 8,103
  • 1
  • 15
  • 37
  • 1
    A quick check in the source code puts the default value for this limit at 1024 and the OP sends a bit over 4 000 values for 500 items so this sounds like the right thing! – Karl-Johan Sjögren Jul 18 '21 at 14:34