即使ModelState无效或一个必需条目为空,也保留数据

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

每当我在我的控制器上向Edit动作方法提交表单时,没有任何条目或无效条目,它会按预期触发错误消息。但是,我也丢失了所有其他数据。我正在寻找一种方法来保存输入的数据,即使ModelState无效。以下是我的代码:

视图模型

public class EditOrderViewModel
{
    [Required(ErrorMessage = "Must Provide Order Number")]
    public string OrderNumber { get; set; }

    public int OrderId { get; set; }

    public int CustomerId { get; set; }

    public int TrailerId { get; set; }

    public List<SelectListItem> Trailers { get; set; }

    public List<SelectListItem> Customers { get; set; }

    public EditOrderViewModel()
    {
    }

    public EditOrderViewModel(Order orderToEdit, IEnumerable<Trailer> trailers, IEnumerable<Customer> customers)
    {
        OrderNumber = orderToEdit.OrderNumber;
        CustomerId = orderToEdit.CustomerId;
        OrderId = orderToEdit.OrderID;
        TrailerId = orderToEdit.TrailerId;

        Trailers= new List<SelectListItem>();

        foreach (var trailer in trailers)

        {
            Trailers.Add(new SelectListItem

            {
                Value = (trailer.TrailerID).ToString(),
                Text = trailer.TrailerNumber
            });
        };

        Customers = new List<SelectListItem>();

        foreach (var customer in customers)

        {
            Customers.Add(new SelectListItem

            {
                Value = (customer.CustomerID).ToString(),
                Text = customer.CustomerName
            });
        };

    }
}

调节器

public IActionResult Edit(int id)
{
    var orderToEdit = _context.Orders.Include(t => t.Trailer).Include( c => c.Customer).Where(o => o.OrderID == id).SingleOrDefault();

    var trailers = _context.Trailers.Where(x => x.TrailerStatus == "Available" || x.TrailerID == orderToEdit.TrailerId).ToList();

    var customers = _context.Customers.ToList();

    EditOrderViewModel editOrderViewModel = new EditOrderViewModel(orderToEdit, trailers, customers);
    return View(editOrderViewModel);
}

[HttpPost]
public IActionResult Edit(EditOrderViewModel editOrderViewModel)
{
    Order order = _context.Orders.FirstOrDefault(o => o.OrderID == editOrderViewModel.OrderId);
    Trailer newTrailer = _context.Trailers.FirstOrDefault(t => t.TrailerID == editOrderViewModel.TrailerId);
    Trailer oldTrailer = _context.Trailers.FirstOrDefault(t => t.TrailerID == order.TrailerId);

    if (ModelState.IsValid)
    {
        order.OrderNumber = editOrderViewModel.OrderNumber;
        order.CustomerId = editOrderViewModel.CustomerId;

        if (oldTrailer.TrailerID != newTrailer.TrailerID)
        {
            oldTrailer.TrailerStatus = "Available";
            newTrailer.TrailerStatus = "Unavailable";
        }
        order.TrailerId = newTrailer.TrailerID;
        _context.SaveChanges();
        return Redirect("/Order");
    }
    return Redirect("/Order/Edit");
}

剃刀查看页面

@model WebApplication1.ViewModels.EditOrderViewModel

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


<h2>@ViewData["Title"]</h2>

<form asp-controller="Order" asp-action="Edit" method="post">

    <fieldset>
        @Html.HiddenFor(o => o.OrderId)

        <div>
            <label asp-for="@Model.OrderNumber">Order number </label>
            <input asp-for="@Model.OrderNumber" />
            <span asp-validation-for="@Model.OrderNumber"></span>
        </div>


        <div>
            <label asp-for="@Model.TrailerId">Customers Name</label>
            <select asp-for="@Model.TrailerId" asp-items="@Model.Trailers"></select>
            <span asp-validation-for="@Model.TrailerId"></span>
        </div>


        <div>
            <label asp-for="@Model.CustomerId">Customers Name</label>
            <select asp-for="@Model.CustomerId" asp-items="@Model.Customers"></select>
            <span asp-validation-for="@Model.CustomerId"></span>
        </div>


        <div>
            <input type="submit" value="Update" name="submitButton" />
        </div>

    </fieldset>
</form>

<p> <a asp-controller="Order" asp-action="Index">Cancel</a> </p>

我试过用了

 return Page(editOrderViewModel);

 return RedirectToAction(editOrderViewModel);

两种方法都将视图页面返回到原始状态,这不是预期的结果。我希望能够在页面上看到包含所有有效和无效数据的错误消息,以便能够纠正并在必要时重新提交。我怎样才能做到这一点?

c# asp.net-core mvvm modelstate
1个回答
0
投票

我只需要重新填充数据,将其传递给viewmodel,然后将其传递回View

[HttpPost]
        public IActionResult Edit(EditOrderViewModel editOrderViewModel)
        {
            Order order = _context.Orders.FirstOrDefault(o => o.OrderID == editOrderViewModel.OrderId);
            Trailer newTrailer = _context.Trailers.FirstOrDefault(t => t.TrailerID == editOrderViewModel.TrailerId);
            Trailer oldTrailer = _context.Trailers.FirstOrDefault(t => t.TrailerID == order.TrailerId);

            if (ModelState.IsValid)
            {
                order.OrderNumber = editOrderViewModel.OrderNumber;
                order.CustomerId = editOrderViewModel.CustomerId;

                if (oldTrailer.TrailerID != newTrailer.TrailerID)
                {
                    oldTrailer.TrailerStatus = "Available";
                    newTrailer.TrailerStatus = "Unavailable";
                }
                order.TrailerId = newTrailer.TrailerID;
                _context.SaveChanges();
                return Redirect("/Order");
            }


            var orderToEdit = _context.Orders.Include(t => t.Trailer).Include(c => c.Customer).Where(o => o.OrderID == editOrderViewModel.OrderId).SingleOrDefault();

            var trailers = _context.Trailers.Where(x => x.TrailerStatus == "Available" || x.TrailerID == orderToEdit.TrailerId).ToList();

            var customers = _context.Customers.ToList();
            EditOrderViewModel repopulateViewModel = new EditOrderViewModel(orderToEdit, trailers, customers);
            return View(repopulateViewModel);
        }
© www.soinside.com 2019 - 2024. All rights reserved.