Редактирането на елемент на линия в индексния изглед изхвърля обвързването на модела. Как да го накарам да работи?

Опитвам се да направя система, в която потребителят може да щракне върху елемент в списък и след това да редактира този елемент, докато все още остава в Index-изгледа.

Моят опит е просто смесица между Index.cshtml и Edit.cshtml:

@model IEnumerable<MyStore.Models.ProductIdentifier>
@{int primary_id = (this.ViewContext.RouteData.Values["primary_id"] != null
        ? int.Parse(this.ViewContext.RouteData.Values["primary_id"].ToString())
        : 0);
}
@foreach (var item in Model)
{
    if (item.Id == primary_id)
    {
        // This list-item is editable (copied from Edit.cshtml):
        <form asp-action="Edit">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <input type="hidden" asp-for="@item.Id" />
            <div class="form-group col-lg-4">
                <input asp-for="@item.Label" class="form-control" />
                <span asp-validation-for="@item.Label" class="text-danger"></span>
            </div>
            <div class="form-group col-lg-6">
                <input asp-for="@item.Description" class="form-control" />
                <span asp-validation-for="@item.Description" class="text-danger"></span>
            </div>
            <div class="form-group col-lg-1">
                <input asp-for="@item.SortOrder" class="form-control" />
                <span asp-validation-for="@item.SortOrder" class="text-danger"></span>
            </div>
            <div class="form-group col-lg-1">
                <button type="submit" value="Save" class="btn btn-primary">
                    <span class="glyphicon glyphicon-floppy-disk"></span> Save
                </button>
            </div>
        </form>
    }
    else
    {
        // This list-item is just a plain list-item:
        <div class="row table">
            <div class="col-lg-4">
                <a asp-action="Index" asp-route-primary_id="@item.Id">
                    @Html.DisplayFor(modelItem => item.Label)
                </a>
            </div>
            <div class="col-lg-6">
                @Html.DisplayFor(modelItem => item.Description)
            </div>
            <div class="col-lg-1">
                @Html.DisplayFor(modelItem => item.SortOrder)
            </div>
            <div class="col-lg-1">
                <a asp-action="Delete" asp-route-id="@item.Id" class="btn btn-xs btn-danger">
                    <span class="glyphicon glyphicon-trash"></span>
                </a>
            </div>
        </div>
    }
}

Данните на формуляра трябва да бъдат публикувани в метода за редактиране в контролера:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Label,Description,SortOrder")] ProductIdentifier productIdentifier)
{
    if (id != productIdentifier.Id) { return NotFound(); }
    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(productIdentifier);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!ProductIdentifierExists(productIdentifier.Id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(productIdentifier);
}

... но тъй като трябваше да добавя @item. пред елементите във формуляра (тъй като моделът е IEnumerable и искам да публикувам само един обект), обвързването на модела вече не работи и обект null се публикувано.

Как мога да го накарам да работи?


person Stian    schedule 22.02.2018    source източник


Отговори (1)


Направих го!

Първо, създадох ViewModel, който съдържа както ICollection идентификатори, така и единичен екземпляр на идентификатор:

public class ViewModelEditIdentifierInIndexView
{
    public ViewModelProductIdentifier SingleItem { get; set; }
    public ICollection<ViewModelProductIdentifier> ListOfItems { get; set; }
}

Трябваше да направя някои промени в метода Index в контролера, за да се погрижа за модела на изглед:

public async Task<IActionResult> Index(int? primary_id)
    {
        ProductIdentifier pi = await _context.ProductIdentifiers
                                .Where(i => i.Id == primary_id)
                                .SingleOrDefaultAsync();
        ViewModelEditIdentifierInIndexView ViewModel = new ViewModelEditIdentifierInIndexView
        {
            SingleItem = _mapper.Map<ViewModelProductIdentifier>(pi),
            ListOfItems = _mapper.Map<ICollection<ViewModelProductIdentifier>>(await _context.ProductIdentifiers.ToListAsync())
        };
        return View(ViewModel);
    }

След това промених модела в индексния изглед:

@model MyStore.Models.ViewModels.ViewModelEditIdentifierInIndexView

След това промених формата за редактиране. Най-важната промяна е добавянето на name-тагове към всяко input-поле:

<form asp-action="Edit">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
    <input type="hidden" asp-for="SingleItem.Id" name="Id" />
    <div class="form-group col-lg-4" style="padding-left:0px;">
        <input asp-for="SingleItem.Label" name="Label" class="form-control" />
        <span asp-validation-for="SingleItem.Label" class="text-danger"></span>
    </div>
    <div class="form-group col-lg-6" style="padding-left:0px;">
        <input asp-for="SingleItem.Description" name="Description" class="form-control" />
        <span asp-validation-for="SingleItem.Description" class="text-danger"></span>
    </div>
    <div class="form-group col-lg-1" style="padding-left:0px;">
        <input asp-for="SingleItem.SortOrder" name="SortOrder" class="form-control" />
        <span asp-validation-for="SingleItem.SortOrder" class="text-danger"></span>
    </div>
    <div class="form-group col-lg-1" style="padding-left:0px;">
        <button type="submit" value="Save" class="btn btn-xs btn-success">
            <span class="glyphicon glyphicon-floppy-disk"></span>
        </button>
        <a href="/bg/Admin/ProductIdentifiers" class="btn btn-xs btn-warning">
            <span class="glyphicon glyphicon-chevron-left"></span>
        </a>
    </div>
</form>

Не трябваше да правя промени в метода Edit в контролера.

person Stian    schedule 22.02.2018