【问题标题】:Reusable components in ASP.NET MVCASP.NET MVC 中的可重用组件
【发布时间】:2011-05-07 16:05:14
【问题描述】:

我的网站上有一些我希望能够在多个页面上重复使用的功能(一些 UI 和相关功能)。就这个问题而言,假设它是一个“评论”功能。

在我的组件应用程序中有一个区域,该区域内有一个控制器:/Controllers/CommentController,以及两个部分视图:/Views/Comment/Index.ascx(用于列出 cmets)和 /Views/Comment/Create.ascx(用于创建 cmets)。

CommentController 看起来像这样:

public class CommentController : Controller
{      
  [ChildActionOnly]
  public ActionResult Index()
  {
      return PartialView(GetComments());
  }

  [HttpGet]
  [ChildActionOnly]
  public ActionResult Create()
  {
      return PartialView(); //this is wrong.
  }

  [HttpPost]
  [ChildActionOnly]
  public ActionResult Create(FormCollection formValues)
  {
      SaveComment(formValues);

      return RedirectToAction("Index"); //this is wrong too.
  }
}

索引局部视图:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<dynamic>" %>

<div>
  <% foreach (var item in Model) { %>    
      <div>
          <%: item.Comment %>
      </div>
  <% } %>

  <%: Html.ActionLink("Add a Comment", "Create", "Comment", new { area = "Components" }, null) %>
</div>

创建局部视图:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<dynamic>" %>
<div>
    <% using (Html.BeginForm())
       {%>
        Enter your comment:
        <div>
            <input type="text" name="comment" />
        </div>
        <p>
            <input type="submit" value="Create" />
            <% //also render a cancel button and redirect to "Index" view  %>
        </p>
    <% } %>
</div>

Index 部分视图包含在带有RenderAction 的视图中,如下所示:

<% Html.RenderAction("Index", "Comment", new { area = "Components" }); %>

此代码不起作用,因为部分视图中的表单提交给 CommentsController 上标记为 [ChildActionOnly] 的操作(这是设计使然,我不希望独立于主机请求“组件”页)。

我怎样才能使这种“组件”方法发挥作用,即有一个提交表单以更改页面内组件状态而不丢失托管页面本身的部分视图?

编辑: 澄清一下,[ChildActionOnly] 的使用不是我的问题。如果我从我的操作方法中删除该属性,我的代码只会“起作用”,因为它不会引发异常。提交表单时,我的“组件”仍然会跳出其托管页面(因为我告诉表单提交到部分视图的 URL!)。

【问题讨论】:

  • 如果您不提供有效路由,则无法单独请求这些组件。执行 RenderAction 不需要有效的路由。
  • 关于您的编辑:您只能将整个页面提交到 URL,而不仅仅是部分视图,除非您想对部分进行 ajaxy 处理。 Ajax 是这个网站发布 cmets 的方式。

标签: asp.net-mvc asp.net-mvc-2 partial-views renderaction


【解决方案1】:

您通过要求表单以标记为 ChildActionOnly 的操作为目标,从而使 MVC 自我对抗。

当我设计一个高度可重用的向导框架时,我对这个问题的解决方案是不将动作标记为 ChildActionOnly,而是检测请求是 ajax 请求还是只是普通的 vanilla 请求。

所有这些的代码都被打包到一个基本控制器类中。在您的派生控制器中,您可以执行以下操作:

[WizardStep(4, "Illness Details")]
public ActionResult IllnessDetails()
{            
    return Navigate();
}

基础控制器的 Navigate() 方法决定是返回完整视图还是仅返回部分视图,具体取决于它是否是 ajax 请求。这样一来,您就永远无法单独返回局部视图。

为了确定它是否是 Ajax 请求,我使用了 Request.IsAjaxRequest() 和 TempData 的组合。需要 TempData 是因为我的向导框架实现了开箱即用的 PRG 模式,所以我需要坚持原来的帖子是 ajax 的事实。

我想这只是一种解决方案,需要经过反复试验才能正确解决。但现在我像 JK 罗琳一样开发了巫师后,过着幸福的生活……

【讨论】:

    【解决方案2】:

    使用 Ajax 发布部分内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-14
      • 1970-01-01
      • 2013-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-05
      • 2010-09-09
      相关资源
      最近更新 更多