MVC - 具有多个模型类型/视图或单个控制器操作的一个控制器操作?

时间:2012-02-06 21:35:05

标签: asp.net-mvc

在我的项目中,我有一个控制器,允许您创建多个不同类型的字母。所有这些字母类型都存储在数据库中,但每种字母类型都有不同的必填字段和不同的视图。

现在我为以下网址设置了路线:/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);

或者有没有办法让我有一个控制器动作并轻松返回正确的模型/视图?

1 个答案:

答案 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")
    }
}

每个模型类型仍然有一个编辑器模板。

另一种选择是根据隐藏字段中的某个值,使用自定义模型绑定器计算出类型,然后使用该类型对其进行序列化。

第一种方法更受欢迎,因为默认的模型绑定器开箱即用,构建自定义模型绑定器需要大量维护。