Дважды возвращает одни и те же ViewData с контроллера для просмотра результата с нулевым значением

#c# #asp.net-core-mvc

#c# #asp.net-core-mvc

Вопрос:

Привет, ребята, я все еще новичок в Asp.net и C #. Я пишу систему управления, контролирующую деятельность office. Я столкнулся с проблемой, когда я передаю объект ViewModel, который содержит список, регистр и значение int, в представление из контроллера. Если вновь созданный case имеет тот же идентификатор, он вернет тот же объект ViewModel обратно в POST-контроллер, но когда объект передается из view в post-контроллер, каждый объект list равен null, за исключением примитивных типов и Case . Я не понимаю, почему передается один и тот же объект, но когда он передается контроллеру из представления, весь список, который только что использовался для заполнения html, равен нулю, это из-за инъекции или просто из-за того, как работает привязка модели? Большое спасибо

В представлении просто есть цикл for, отображающий каждый элемент в TopTenList. вверху есть оператор привязки @model. Вот представление

 @model LabManager.InputModels.CaseInputModel
@inject LabManager.Data.ApplicationDbContext _dbContext
@using LabManager.ModelExtensions

@{
    ViewData["Title"] = "Overview";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

@section Stylesheet{
    <link rel="stylesheet" href="~/css/Case/index.css" />
}

<div id="home-view">
    <div class="card">
        <div class="card-header">
            <a class="card-link" data-toggle="collapse" href="#topTen">
                Top Ten Priority Cases
            </a>
        </div>
        <div id="topTen" class="collapse show" data-parent="#home-view">
            <div class="card-body">
                <table class="table">
                    <thead>
                        <tr>bunch of names</tr>
                    </thead>
                    <tbody>
                        @{int i = 1;}
                        @foreach (var item in Model.TopTenList)
                        {
                            show somethings.
                        }
  

Вот контроллер.

 public ActionResult Create(int setPriority)
{
    CaseInputModel input = new CaseInputModel {
        SelectedPriority = setPriority,
    };
    input.SetTopTenList(_dbContext);
    return View(input);
}

// POST: Takes info from the input model and creates a new case in the db
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(CaseInputModel inputs)
{
    //if case id already exist in the database, return view()
    if (DbContext.Cases.Any(m => m.CaseId == inputs.NewCase.CaseId))
    {
        inputs.ErrorMessage = "Error: Case ID already exists";
        return View(inputs);
    }
  

Ее модель:

    public class Case
    {
        [Required]
        [RegularExpression("[^0-9]")]
        public int Id { get; set; }
        public int CaseId { get; set; }
        public Status Status { get; set; }
        public string Notes { get; set; }
    }
  

Вот CaseInputModel(объект ViewModel)

 public class CaseInputModel
    {
        public CaseInputModel()
        {
            NewCase = new Case();
            RegularCaseList = new List<Case>();
        }
        public string ErrorMessage { get; set; }
        public int SelectedPriority { get; set; }
        public Case NewCase { get; set; }
        public List<Case> RegularCaseList { get; set; }
        public List<Case> TopTenList { get; set; }

        public void SetTopTenList(ApplicationDbContext dbContext)
        {
            TopTenList = PriorityNodeExtensions.ToSortedList(dbContext.TopTens, 
            dbContext);
        }
  

Комментарии:

1. Не могли бы вы поделиться своей моделью и представлением razor? И причина, по которой ваше представление заполняет нулевой объект, заключается в том, что объект имеет значение null при отправке на контроллер. И когда вы возвращаете view с model, он будет отображать нулевые данные в html.

2. Я добавлю это. Вы правы в том, что когда он отправляется на контроллер. Запрос get к контроллеру возвращает представление (ввод), в котором содержится список топ10 случаев. Но когда он передается обратно из представления в post controller, сохраняются только 2 атрибута объектов (Case, int), остальные равны нулю.

3. То, что вы предоставили, не помогает воспроизвести вашу проблему. Вам необходимо предоставить представление rest razor о том, как вы моделируете привязку. И вы могли бы получить только Case и int, пожалуйста, сообщите нам конкретное имя свойства двух объектов в InputModel. В вашем коде есть некоторые errors:1.In вы получаете метод, вы возвращаете входную модель, но вашему представлению razor требуется IEnumerable<Case> , вы пропустили другое представление razor? 2.In в вашем методе get вы устанавливаете только два значения свойства, убедитесь, что ваш razor view имеет HTML-код других свойств и заполняет данные, в противном случае вы не смогли бы передать все данные контроллеру.

4. @Rena, Привет, я прошу прощения за то, что не ответил раньше. На самом деле у меня все еще есть проблема. Я обновлю свой вопрос, пытаясь получить больше изображений. Большое спасибо за продолжение.

Ответ №1:

Во-первых, вам нужно знать, что для каждого свойства сложного типа привязка модели просматривает источники для шаблона имени prefix.property_name . Если ничего не найдено, он ищет только property_name без префикса.

Ссылка:

https://learn.microsoft.com/en-us/aspnet/core/mvc/models/model-binding?view=aspnetcore-3.1#complex-types

Вот простая демонстрация о том, как передать данные контроллеру:

Вид:

 @model InputModel

<form asp-action="Create">
    <table class="table">
        <thead>
            <tr>bunch of names</tr>
        </thead>
        <tbody>
            <tr>
                <td>SelectedPriority</td>
                <td><input asp-for="@Model.SelectedPriority" /></td>
            </tr>
            <tr>
                <td>New Case</td>
                <td><input asp-for="@Model.NewCase.Id" /></td>
                <td><input asp-for="@Model.NewCase.CaseId" /></td>
                <td><input asp-for="@Model.NewCase.Notes" /></td>
            </tr>
            @{int i = 0;}
            @foreach (var item in Model.TopTenList)
            {
                <tr>
                    <td>TopTenList_@i</td>
                    <td><input name="TopTenList[@i].Id" asp-for="@item.Id" /></td>
                    <td><input name="TopTenList[@i].CaseId" asp-for="@item.CaseId" /></td>
                    <td><input name="TopTenList[@i].Notes" asp-for="@item.Notes" /></td>
                </tr>
                i  ;
            }
        </tbody>
    </table>
    <input type="submit" value="create" />
</form>
            
  

Результат:

введите описание изображения здесь

Обновить:

возврат view с model он может успешно отобразить модель, но вы не смогли отобразить TopTenList.Убедитесь, что вы создали входные данные для свойств модели и отладили действие, чтобы проверить, передали ли вы TopTenList методу post.Если вы только визуализируете данные, используя @Model.Property их, они не будут переданы на серверную часть.

Вид:

  @model CaseInputModel
<form asp-action="Create">
    <table class="table">
        <thead>
            <tr>bunch of names</tr>
        </thead>
        <tbody>
            @if (Model.ErrorMessage != null)
            {
                @Model.ErrorMessage
            }
            <tr>
                <td>SelectedPriority</td>
                <td><input asp-for="@Model.SelectedPriority" /></td>
            </tr>
            <tr>
                <td>New Case</td>
                <td><input asp-for="@Model.NewCase.Id" /></td>
                <td><input asp-for="@Model.NewCase.CaseId" /></td>
                <td><input asp-for="@Model.NewCase.Notes" /></td>
            </tr>
            @{int i = 0;}
            @foreach (var item in Model.TopTenList)
            {
                <tr>
                    <td>
                        @item.Id
                        <input name="TopTenList[@i].Id" asp-for="@item.Id" hidden />
                    </td>
                    <td>
                        @item.CaseId
                        <input name="TopTenList[@i].CaseId" asp-for="@item.CaseId" hidden />
                    </td>
                    <td>
                        @item.Notes
                        <input name="TopTenList[@i].Notes" asp-for="@item.Notes" hidden />
                    </td>
                </tr>
                i  ;
            }
        </tbody>
    </table>
    <input type="submit" value="create" />
</form>
  

Результат:

введите описание изображения здесь

Комментарии:

1. Возможно, я не очень хорошо объяснил проблему. Пожалуйста, потерпите меня. Страница создания работает нормально регулярно, заполните toptenlist в методе Create Controller и передайте его в представление. Однако, если я введу тот же идентификатор обращения #, который уже есть в базе данных, он вернет тот же вид той же ViewModel с сообщением об ошибке, это вызывает проблему, поскольку это «обновит» страницу, и TopTenList будет потерян. Когда вызывается метод Get Create, он создает TopTen и переходит к представлению. Представление заполняет все и передает тот же объект ViewModel обратно в метод HTTP Create .

2. Теперь, когда метод http создает get эту ViewModel, в данном случае «input». он имеет только приоритет переменной int, объект case, а toptenlist равен null. таким образом, когда этот ввод затем возвращается в представление, toptenlist не может быть заполнен, поскольку он равен null.

3. Привет @HeChuan, извините за поздний ответ. Пожалуйста, проверьте мой обновленный ответ.