0

I have a page at http://localhost/Some and when I post the Url changes to http://localhost/Some/Method. How do I keep preserve the original Url with the ModelState and ViewModel?

Here is my current code:

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

    return RedirectToAction("Index");
}
4

1 回答 1

0

请参阅使用 RedirectToAction 时如何维护 ModelState 错误?.

TempData用于保存ModelState数据ViewModel

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");
}
于 2013-06-12T16:02:29.117 回答