带有可选参数的ASP.NET MVC操作

时间:2010-02-01 11:13:42

标签: asp.net asp.net-mvc routing

我的抽象BaseControlller 上有一个MVC操作(这个操作在所有继承控制器中都很常见):

    //
    // GET: /controller/RenderForm/{formType}
    [Authorize(Roles = "Administrators")]
    public ActionResult RenderForm(FormType formType, BaseContentObject contentObject)
    {
        string constructPartialViewName = RouteData.Values["controller"] + "-" + formType + "Form";
        return PartialView(constructPartialViewName, contentObject);
    }

用这条路线:

        routes.MapRoute(
            "ContentObjectsFormRendering",
            RouteType.Regular,
            "{controller}/RenderForm/{formType}",
            new {controller = "", action = "RenderForm", formType = ""}, null
            );

当我发出以下浏览器请求时会出现问题:

〜/页/ RenderForm /创建

这是呈现创建表单的请求。 这是通过浏览器完成的 - 例如,输入网址。这里没有BaseContentObject实例(请注意,永远不能通过浏览器为Create提供,因为在编辑的情况下它总是从数据存储区中拉出来)并且我认为这是困扰他的。

(例外情况是:无法创建抽象类。)

但是当像这样执行RenderAction时:

    <%
        Html.RenderAction("RenderForm", ViewData.Model.ContentType.ToString(), new {formType = FormType.Edit, contentObject = ViewData.Model}); %>

它使用BaseContentObject实例(通过ViewData提供)中的详细信息呈现编辑表单

如果我从动作中删除 BaseContentObject contentObject参数,那么渲染Create工作正常,但是在第二种情况下我无法提供内容对象参数进行编辑。

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

由于您的RenderForm很常见(在基本控制器中),因此MVC使用此方法的签名来实例化参数。这是这样的:

  • action是RenderForm(FormType formType,BaseContentObject contentObject)
  • 有像“contentObject.Property”这样的表单数据,因此MVC需要实例化contentObject
  • contentObject的类型是BaseContentObject
  • BaseContentObject无法实例化,因为它是抽象的

你的问题是你认为如果用不同的/特定的contentObject参数类型覆盖RenderForm,那么将使用新的参数类型 - 但是从我在这里看到的这是错误的。将使用基本方法签名。

解决方案:

  • 覆盖DefaultModelBinder并在那里调整实例化;不过,我不确定你是否可以检测到真实的动作/参数类型;
  • 不要使用共同的基础RenderForm动作;将所需的通用功能提取到受保护的基本方法(例如DoRenderForm)中,并从实际操作中调用它。