更改Post中显示的路由

本文关键字:路由 显示 Post 更改 | 更新日期: 2023-09-27 18:18:08

我在http://localhost/Some有一个页面,当我发布Url更改到http://localhost/Some/Method时。如何保留ModelStateViewModel的原始Url ?

下面是我当前的代码:

[HttpPost]
public ActionResult Method(SomeMethodViewModel model)
{
    if(HasError(model))
    {
        var viewModel = GetViewModel();
        viewModel.SomeMethod = model;
        return View("Index", viewModel);
    }
    return RedirectToAction("Index");
}

更改Post中显示的路由

参见使用RedirectToAction时如何维护ModelState错误。

TempData可以用来保存ModelStateViewModel的数据。

public class SomeController : Controller
{
    protected override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        var modelState = TempData["ModelState"];
        if (modelState != null && !ModelState.Equals(modelState))
        {
            ModelState.Merge((ModelStateDictionary)modelState);
        }
        base.OnActionExecuted(filterContext);
    }
    private void SetModelState(ModelStateDictionary modelState)
    {
        TempData["ModelState"] = modelState;
    }
    private void SetViewModel(SqlAdminViewModel viewModel)
    {
        TempData["ViewModel"] = viewModel;
    }
    private SomeViewModel GetViewModel()
    {
        var viewModelTempData = TempData["ViewModel"];
        var viewModel = viewModelTempData != null
                            ? (SomeViewModel) TempData["ViewModel"]
                            : BuildSomeViewModel();
        return viewModel;
    }
    public ActionResult Index()
    {
        var viewModel = GetViewModel();
        return View(viewModel);
    }
    [HttpPost]
    public ActionResult Method(SomeMethodViewModel model)
    {
        if(HasError(model))
        {
            var viewModel = GetViewModel();
            viewModel.SomeMethod = model;
            SetViewModel(viewModel);
            return RedirectToAction("Index");
        }
        return RedirectToAction("Index");
    }
    privare bool HasError(SomeMethodViewModel model)
    {
        var hasError = false;
        // Model validation logic
        if(hasError)
        {
            SetModelState(ModelState);
        }
        return hasError;
    }
}

可以进一步解耦:

public interface IViewModelValidator<in TViewModel>
{
    bool HasError(TViewModel viewModel, ModelStateDictionary modelState);
    bool HasError(TViewModel viewModel, ModelStateDictionary modelState, Action<ModelStateDictionary> callBack);
}
public abstract class ViewModelValidatorBase<TViewModel> : IViewModelValidator<TViewModel>
{
    public abstract bool HasError(TViewModel viewModel, ModelStateDictionary modelState);
    public virtual bool HasError(TViewModel viewModel, ModelStateDictionary modelState, Action<ModelStateDictionary> callBack)
    {
        var hasError = HasError(viewModel, modelState);
        if (hasError && callBack != null)
        {
            callBack(modelState);
        }
        return hasError;
    }
}

用法:

[HttpPost]
public ActionResult Method(SomeMethodViewModel model)
{
    if(_someMethodViewModelValidator.HasError(model, ModelState, SetModelState))
    {
        var viewModel = GetViewModel();
        viewModel.SomeMethod = model;
        return RedirectToAction("Index");
    }
    return RedirectToAction("Index");
}