当发送超过150个元素时,视图模型未通过

问题描述 投票:0回答:1

与此相关的问题:.NET ViewModel 由于特定的输入字段而未从视图传递到控制器

以前我认为问题出在视图上,但是,由于上一个问题的帮助,我现在有了一个清晰的项目(所以我认为这将是一个可重现的最小解决方案,因为它指向我)添加了元素和视图模型丢失了,而有超过 150 个元素要传递回 POST 方法。没有任何其他错误。

当我设置

i < 100
时,它可以工作,当我将其设置为 150 时,它会丢失视图模型。

当数据来自数据库时,也会出现同样的问题 - 我尝试传递包含 50 个元素集的视图模型(使用

Take
Skip
),并且对于每个元素,都会传递视图模型(因此这不是数据本身的问题)。

是否有某种我找不到的限制?

控制器:

    public IActionResult Edit()
    {
        var r1 = new RecipeDTO() { Id = 1, TotalKcal = 10, TotalGL = 45, RecipeDayId = 1, MealId = 1, Name = "QQ" };
        var c1 = new List<Category>() { new Category() { Id = 1, Name = "AA" }, new Category() { Id = 2, Name = "BB" } };
        var s1 = new List<SelectedCheckboxViewModel>() { 
            new SelectedCheckboxViewModel() { CategoryId = 1, Id = 160, IsChecked = true, Name = "AA", Grams = 1, TotalKcal = 1, GL = 1.0 }, 
            new SelectedCheckboxViewModel() { CategoryId = 1, Id = 162, IsChecked = true, Name = "BB", Grams = 1, TotalKcal = 1, GL = 1.0 }
        };

        for (var i = 0; i < 150; i++)
        {
            s1.Add(new SelectedCheckboxViewModel() { CategoryId = 1, Id = i + 1, IsChecked = true, Name = $"AA{i}", Grams = 5, TotalKcal = 5, Amount = 0 });
        }

        var model = new RecipeViewModel() { Recipe = r1, Categories = c1, SelectedCheckboxes = s1 };
        return View("Create", model);
    }

    [HttpPost]
    public IActionResult Edit(RecipeViewModel model) 
    {
        return View("Create", model);
    }

食谱DTO:

public class RecipeDTO
{
    public int Id { get; set; }
    [Required]
    public string Name { get; set; }
    public int MealId { get; set; }
    public int RecipeDayId { get; set; }

    public List<IngredientDTO> Ingredients { get; set; } = new List<IngredientDTO>();
    public IEnumerable<Recipe_Ingredients> Recipe_Ingredients { get; set; } = new List<Recipe_Ingredients>();

    [DisplayName("Selected amount of kcals")]
    public double TotalKcal
    {
          get
          {
              double totalKcal = 0;
              Ingredients.ForEach(item =>
              {
                  totalKcal += item.Kcals;
              });
              return totalKcal;
          }
          set { }
    }

    public double TotalGL
    {
          get
          {
              double totalGL = 0;
              Ingredients.ForEach(item =>
              {
                  totalGL += item.GL;
              });
              return totalGL;
          }
          set { }
    }
}

类别

public class Category
{
    public int Id { get; set; }
    public string Name { get; set; }
}

选定的CheckboxViewModel

public class SelectedCheckboxViewModel
{
    public int? Id { get; set; }
    public bool IsChecked { get; set; }
    public string Name { get; set; }
    public int CategoryId { get; set; }
    public int Grams { get; set; }
    public double Amount { get; set; }
    public Product Product { get; set; } = new Product();
    public int ProductId { get; set; }
    public int TotalKcal
    {
        get
        {
            return Product.KcalPer100g * (Grams / 100);
        }
        set { }
    }
    public double GL
    {
        get
        {
            return Math.Floor((Product.GI * (Product.CarbsPer100g * (Grams / 100)) / 100));
        }
        set { }
    }
}

食谱视图模型

public class RecipeViewModel
{
    public RecipeDTO Recipe { get; set; } = new RecipeDTO();
    public List<RecipeDTO> Recipes { get; set; } = new List<RecipeDTO>();
    public List<SelectedCheckboxViewModel> SelectedCheckboxes { get; set; }
    public IEnumerable<Category> Categories { get; set; }
    public bool IsIngredientBeingSwitched { get; set; } = false;
}

查看

@model RecipeViewModel

@{
    var url = Model.Recipe.Id == 0 ? Url.Action("Edit", "Home") : Url.Action("Edit", "Home");
    url = Model.IsIngredientBeingSwitched && Model.Recipe.Id != 0 ? Url.Action("Edit", "Home") : URL;
}

<div class="container">
    <form method="post" action="@url">
        <div class="mb-3 row">
            <label asp-for="@Model.Recipe.TotalKcal"></label>
            <input id="totalRecipe" asp-for="@Model.Recipe.TotalKcal" class="form-control" readonly />
            <label asp-for="@Model.Recipe.TotalGL"></label>
            <input id="totalRecipeGL" asp-for="@Model.Recipe.TotalGL" class="form-control" readonly />
        </div>
        <div class="mb-3 row">
            <input hidden asp-for="@Model.Recipe.Id" />
            <input hidden asp-for="@Model.Recipe.MealId" />
            <input hidden asp-for="@Model.Recipe.RecipeDayId" />
            <label asp-for="@Model.Recipe.Name"></label>
            <input asp-for="@Model.Recipe.Name" class="form-control" />
            <span asp-validation-for="@Model.Recipe.Name" class="text-danger"></span>
        </div>

        @foreach (Category category in Model. Categories)
        {
            <text>
                <div class="m-2"><h3>@category.Name</h3></div>
                <div class="row">
                    @for (var i = 0; i < Model.SelectedCheckboxes.Count(); i++)
                    {
                        if (Model.SelectedCheckboxes[i].CategoryId == category.Id)
                        {
                            <text>
                                <div class="col-auto">
                                    <div>
                                        <input class="form-number-input" asp-for="@Model.SelectedCheckboxes[i].IsChecked" type="checkbox">
                                        <input hidden asp-for="@Model.SelectedCheckboxes[i].Id" />
                                        <label class="form-check-label" asp-for="@Model.SelectedCheckboxes[i].IsChecked">@Model.SelectedCheckboxes[i].Name</label>
                                    </div>
                                    <div>
                                        <div>
                                            <label class="form-check-label" asp-for="@Model.SelectedCheckboxes[i].Grams">Amount: </label>
                                            <input class="form-control-sm" asp-for="@Model.SelectedCheckboxes[i].Grams" />
                                        </div>
                                        <div>
                                            <label class="form-check-label" asp-for="@Model.SelectedCheckboxes[i].TotalKcal">Selected kcals: </label>
                                            <input class="form-control-sm total-kcal" asp-for="@Model.SelectedCheckboxes[i].TotalKcal" readonly>
                                        </div>
                                        <div>
                                            <label class="form-check-label" asp-for="@Model.SelectedCheckboxes[i].GL">Load: </label>
                                            <input class="form-control-sm total-gl" asp-for="@Model.SelectedCheckboxes[i].GL" readonly>
                                        </div>
                                    </div>
                                </div>
                            </text>
                        }
                    }
                </div>
            </text>
        }
        <button type="submit" class="btn btn-primary mt-5">Save</button>
    </form>
</div>
asp.net-mvc asp.net-core
1个回答
0
投票

我的测试代码TotalKcal,TotalGL和GL就像

public double TotalGL { get; set; }
然后我将其设置为150它可以得到如下视图模型:

也许问题在于

{ get; set; }
,即单个表单值的长度限制。默认为 4,194,304 字节,大约为 4MB。尝试设置您的 FormOptions.ValueLengthLimit 属性,如下所示:

在您的program.cs中添加以下代码:

builder.Services.Configure<KestrelServerOptions>(options =>
{
    options.Limits.MaxRequestBodySize = int.MaxValue; // if don't set default value is: 30 MB
});
builder.Services.Configure<FormOptions>(options =>
{
    options.MultipartBodyLengthLimit = int.MaxValue;
    options.ValueLengthLimit = int.MaxValue;
});
© www.soinside.com 2019 - 2024. All rights reserved.