验证错误后的RedirectToAction

时间:2011-05-26 16:44:25

标签: asp.net-mvc-3

如果我有通常的编辑操作,一个用于GET通过它的ID检索对象并以编辑形式显示它。 POST的下一个用于获取ViewModel中的值并更新数据库中的对象。

public virtual ActionResult Edit(int id)

[HttpPost]
public ActionResult Edit(VehicleVariantEditSaveViewModel viewModel)

如果在POST操作中的模型绑定期间发生错误,我理解我可以将RedirectToAction返回到GET操作并通过将其复制到TempData并在GET操作中重定向之后检索它来保留ModelState验证错误。

if (TempData["ViewData"] != null)
{
    ViewData = (ViewDataDictionary)TempData["ViewData"];
}

如何将包含先前无效ModelState的ViewData转换为新模型以发送到视图,以便用户看到带有验证警告的无效输入?奇怪的是,如果我将从数据库中检索到的ViewModel的新实例(带有原始有效数据)传递给View(),则会忽略它,并显示ViewData中的(无效)数据!

由于

2 个答案:

答案 0 :(得分:3)

我遇到了类似的问题,并决定使用以下模式:

public ActionResult PersonalRecord(Guid id)
{
    if (TempData["Model"] == null)
    {
        var personalRecord = _context.PersonalRecords.Single(p => p.UserId == id);
        var model = personalRecord.ToPersonalRecordModel();
        return View(model);
    }
    else
    {
        ViewData = (ViewDataDictionary) TempData["ViewData"];
        return View(TempData["Model"]);
    }
}

[HttpPost]
public ActionResult PersonalRecord(PersonalRecordModel model)
{
    try
    {
        if (ModelState.IsValid)
        {
            var personalRecord = _context.PersonalRecords.Single(u => u.UserId == model.UserId);
            personalRecord.Email = model.Email;
            personalRecord.DOB = model.DOB;
            personalRecord.PrimaryPhone = model.PrimaryPhone;
            _context.Update(personalRecord);
            _context.SaveChanges();
            return RedirectToAction("PersonalRecord");
        }
    }
    catch (DbEntityValidationException ex)
    {
        var errors = ex.EntityValidationErrors.First();
        foreach (var propertyError in errors.ValidationErrors)
        {
            ModelState.AddModelError(propertyError.PropertyName, propertyError.ErrorMessage);
        }
    }

    TempData["Model"] = model;
    TempData["ViewData"] = ViewData;

    return RedirectToAction("PersonalRecord", new { id = model.UserId });
}

希望这有帮助。

答案 1 :(得分:1)

我注意到Model包含在ViewData中,因此除了ViewData之外你不需要传递它,我不明白你是如何得到它然后将它返回到视图。

    public ViewResult Edit(int id)
    {
        // Check if we have ViewData in the session from a previous attempt which failed validation
        if (TempData["ViewData"] != null)
        {
            ViewData = (ViewDataDictionary)TempData["ViewData"];
        }

        VehicleVariantEditViewModel viewModel = new VehicleVariantControllerViewModelBuilder()
            .BuildForEdit(id);

        return View(viewModel);      
    }

以上工作但显然它正在对数据库进行不必要的调用以构建一个新模型(使用传递的ViewData中的模型中的无效值自动覆盖)

混淆。