在我的项目中,我有一个控制器,允许您创建多个不同类型的字母。所有这些字母类型都存储在数据库中,但每种字母类型都有不同的必填字段和不同的视图。
现在我为以下网址设置了路线:/Letters/Create/{LetterType}
。我目前将此映射到以下控制器操作:
public ActionResult Create(string LetterType)
{
var model = new SpecificLetterModel();
return View(model);
}
我还有一个名为Create.cshtml
的视图和一个特定字母类型的EditorTemplate。这一切现在都很好,因为我只实现了一个字母类型。现在我需要继续添加其余部分,但是我设置动作的方式与我实现的特定字母类型相关联。
由于每个Letter都有自己的模型,自己的验证集以及自己的视图,实现这些操作的最佳方法是什么?由于添加新的字母类型需要对模型/验证进行编码并创建视图,因此具有单独的控制器操作更有意义:
public ActionResult CreateABC(ABCLetterModel model);
public ActionResult CreateXYZ(XYZLetterModel model);
或者有没有办法让我有一个控制器动作并轻松返回正确的模型/视图?
答案 0 :(得分:1)
您可以执行以下操作之一:
为每个输入设置不同的操作方法。这是因为mvc框架将看到action方法的输入,并使用默认的模型绑定器轻松绑定该类型的属性。然后,您可以使用公共私有方法进行处理,并返回视图。
假设XYZLetterModel和ABCLetterModel是某些基本模型的子类,您的控制器代码可能如下所示:
public class SomeController : Controller
{
private ISomeService _SomeService;
public SomeController(ISomeService someService)
{
_SomeService = someService;
}
public ViewResult CreateABC(ABCLetterModel abcLetterModel)
{
// this action method exists to allow data binding to figure out the model type easily
return PostToServiceAndReturnView(abcLetterModel);
}
public ViewResult CreateXYZ(XYZLetterModel xyzLetterModel)
{
// this action method exists to allow data binding to figure out the model type easily
return PostToServiceAndReturnView(xyzLetterModel);
}
private ViewResult PostToServiceAndReturnView(BaseLetterModel model)
{
if (ModelState.IsValid)
{
// do conversion here to service input
ServiceInput serviceInput = ToServiceInput(model);
_SomeService.Create(serviceInput);
return View("Success");
}
else
{
return View("Create", model);
}
}
}
View代码可能如下所示:
@model BaseLetterModel
@if (Model is ABCLetterModel)
{
using (Html.BeginForm("CreateABC", "Some"))
{
@Html.EditorForModel("ABCLetter")
}
}
else if (Model is XYZLetterModel)
{
using (Html.BeginForm("CreateXYZ", "Some"))
{
@Html.EditorForModel("XYZLetter")
}
}
每个模型类型仍然有一个编辑器模板。
另一种选择是根据隐藏字段中的某个值,使用自定义模型绑定器计算出类型,然后使用该类型对其进行序列化。
第一种方法更受欢迎,因为默认的模型绑定器开箱即用,构建自定义模型绑定器需要大量维护。