Ядро aspnet как разместить данные из View, если модель сложная - PullRequest
0 голосов
/ 25 апреля 2018

У меня есть некоторые проблемы с использованием методов Post в контроллерах ASP.NET Core MVC. Может быть, я использую неправильную архитектуру.

У меня есть 2 модели из БД.

     public class RecipeTable
    {
        public int Id { get; set; }
        public string MetrologyRecipe { get; set; }
        public string MetrologyTool { get; set; }
        //other properties
    }


    public class ParamTable
    {
        public int AupId { get; set; }
        public string ParamName{ get; set; }
        public string RecipeName { get; set; }
        public int? ParamOrderAuto { get; set; }
        //other properties
    }

И коробка для них. Потому что одна запись в RecipeTable связана с несколькими записями из ParamTable.

 public class FullModel
{
    public List<ParamTable> ParamRows ;
    public RecipeTable RecipeRow { set; get; }

    public FullModel()
    {
        ParamRows = new List<ParamTable> ();
    }

}

Для метода [Get] "Edit" это отлично работает.

[HttpGet]
    public async Task<IActionResult> Edit(int? id, string recipeName)
    {
        var fullModel = new FullModel();
        if (id == null) return NotFound();


        fullModel.RecipeRow = await 
        _context.RecipeTable.SingleOrDefaultAsync(m => m.Id == id);


        foreach (var row in _context.ParamTable)
            if (recipeName == row.RecipeName)
               fullModel.ParamRows.Add(row);



        if (fullModel.RecipeRow.MetrologyRecipe == null) return NotFound();
        return View(fullModel);
    }

Но для [Post] «Edit» это, конечно, не работает. Только часть рецепта обновлена. Я не понимаю, как метод post получить данные из View. Как работать с этими сложными моделями, когда вы не можете изменить базу данных и не можете
указать соединение непосредственно в конструкторе базы данных.

 [HttpPost, ActionName("Edit")]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Edit(int id, FullModel fullModel)
    {
        if (id != fullModel.RecipeRow.Id) return NotFound();

        if (ModelState.IsValid)
        {
            try
            {
                //**Here fullModel.ParamRows.Count = 0**
                _context.Update(fullModel.RecipeRow);
                await _context.SaveChangesAsync();
                foreach (var elem in fullModel.ParamRows)
                {
                    _context.Update(elem);
                    await _context.SaveChangesAsync();
                }

            }
            catch (DbUpdateConcurrencyException)
            {
                if (!RecipeTableExists(fullModel.RecipeRow.Id))
                    return NotFound();
                throw;
            }

            return RedirectToAction(nameof(Index));
        }

        return View(fullModel);

Просмотр части выглядит следующим образом:

@model FullModel

@{
    ViewData["Title"] = "Edit";
}

<div class="row">
    <div class="col-md-4">
        <form asp-action="Edit">
          

 <table class="table" style="margin-left: -50px">
                <thead>
                    <tr>
                        <th>Order</th>
                        <th>Param</th>
                    </tr>
                </thead>
                  <tbody>
                    @for (var i = 0; i < Model.ParamRows.Count; i++)
                    {
                        <tr>
                            <td>
                                <div class="form-group">
                                    <input asp-for="@Model.ParamRows[i].ParamOrderAuto" type="text" class="form-control" />
                                </div>
                            </td>
                            <td>
                                <div class="form-group">
                                    <input  asp-for="@Model.ParamRows[i].ParamName" class="form-control" />
                                </div>
                            </td>
                         </tr>
                          }

                </tbody>
            </table>

            <div class="form-group">
                <input type="submit" value="Save" class="btn btn-default" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="Index">Back to List</a>
</div>

Ответы [ 2 ]

0 голосов
/ 27 апреля 2018

У вас небольшая проблема с FullModel, необходимо добавить get; set; методы.Просто исправьте вот так:

public class FullModel
{
    public List<ParamTable> ParamRows { get; set; };
    public RecipeTable RecipeRow { set; get; }
...
0 голосов
/ 25 апреля 2018

Вы не можете использовать foreach для итерации по ParamRows.Чтобы связыватель модели мог связать это обратно со списком постов, поля должны иметь имена, такие как ParamRows[N].ParamName.Используя foreach, вместо этого вы получите имена типа row.ParamName, которые связыватель моделей не распознает и просто отбросит.

Вместо этого используйте стандартный цикл for:

@for (var i = 0; i < Model.ParamRows.Count; i++)
{
    ...
    <input asp-for="ParamRows[i].ParamName" />
    ...
}

Кроме того, вы можете создать шаблон редактора для ParamTable, то есть ~/Views/Shared/EditorTemplates/ParamTable.cshtml, и поместить в него весь HTML (поля, метки и т. Д.) Для редактирования экземпляра ParamTable.Затем, вместо перебора элементов в ParamRows, вы можете просто сделать:

@Html.EditorFor(m => m.ParamRows)

Razor будет автоматически перебирать каждый элемент и отображать вам шаблон редактора для каждого, давая каждому полю правильное имя дляпереплет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...