Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
707 views
in Technique[技术] by (71.8m points)

model view controller - Forms inside foreach loop MVC

I have situation where MVC controller has sent list of records. Those records are displayed in view in order that every single record is a form, so it can be posted record by record.

@model IList<FMS.Application.Models.TransferLineUpdateResponse>

@{
    ViewData["Title"] = "Transfer Lines Page";
}
<div class="row">
    <div class="col-12">

        @foreach (var item in Model)
        {
            <form method="post" class="form-inline">
                <div class="form-group">
                    <input type="hidden" asp-for="@item.Id" readonly class="form-control" />
                    <input type="hidden" asp-for="@item.TransferHeaderId" readonly class="form-control" />
                </div>
                <div class="form-group">
                    <label asp-for="@item.Item"></label>
                    <input asp-for="@item.Item" readonly class="form-control" />
                </div>
                <div class="form-group">
                    <label asp-for="@item.ToLocationId"></label>
                    <select class="form-control" asp-for="@item.ToLocationId" asp-items="ViewBag.ToLocations"></select>
                </div>
                <div class="form-group">
                    <input type="submit" asp-route-status="Accepted" class="btn btn-success" /> |
                    <input type="submit" asp-route-status="Rejected" class="btn btn-danger" />
                </div>
            </form>

        }
    </div>
</div>

When one of two buttons is clicked and form submission is called, as parameter in controller all my records like Id, ToLocationId are null or empty guids in case if property has type guid. Why it is not taken data which has been actually changed in view ? Regards

P.S.here is the code of controller

[HttpGet("Transfer/Details/{id}")]
public async Task<IActionResult> Details(Guid id)
{
    var lines = await _transferLineService.GetTransferLines(id);
    var locations = await _locationService.GetLocations();
    var customLocations = locations
        .Where(w=>w.Code != "Tranzit")
        .Select(s => new
    {
        Id = s.Id,
        Description = $"{s.Code} - {s.Description}"
    });
    ViewBag.ToLocations = new SelectList(customLocations, "Id", "Description");
    return View(lines);
}

[HttpPost("Transfer/Details/{transferHeaderId}")]
public async Task<IActionResult> AcceptDetails(Guid transferHeaderId, TransferLineUpdateResponse update)
{
    var result = await _transferLineService.UpdateTransferLine(update);
    await _transferHeaderService.UpdateTransferHeaderStatus(update.TransferHeaderId);
    return RedirectToAction("Details",new { transferHeaderId = update.TransferHeaderId });
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Why it is not taken data which has been actually changed in view ?

Model binding looks through the sources for the name pattern prefix.property_name. If nothing is found, it looks for just property_name without the prefix.In your code,the asp-for tag helper will generate the name like:item_propertyName.It could not match with backend model.You could use [Bind(Prefix ="item")] to specify the prefix.

Change like below:

[HttpPost("Transfer/Details/{transferHeaderId}")]
public async Task<IActionResult> AcceptDetails(Guid transferHeaderId,[Bind(Prefix ="item")] TransferLineUpdateResponse update)
{
    //do your stuff...
    //_context.Update(update);
    //await _context.SaveChangesAsync();

    //your get method used [HttpGet("Transfer/Details/{id}")]
    //so,it should be id not transferHeaderId
    return RedirectToAction("Details", new { id = update.TransferHeaderId });//also change here...
}

Result: enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...