加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc – 如何使用ASP.NET MVC抽象标记的常见片段

发布时间:2020-12-16 06:43:52 所属栏目:asp.Net 来源:网络整理
导读:我的ASP.NET MVC 2站点中有很多内容丰富的视图.这些包含几个重新出现的 HTML模式.使用ASP.NET Webforms时,从WebControl派生的类可以封装这些模式.我想对MVC这个问题的正确方法提出一些指示. 详细说明 与以下HTML标记不同的模式在这些视图中不断出现.标记呈现
我的ASP.NET MVC 2站点中有很多内容丰富的视图.这些包含几个重新出现的 HTML模式.使用ASP.NET Webforms时,从WebControl派生的类可以封装这些模式.我想对MVC这个问题的正确方法提出一些指示.

详细说明

与以下HTML标记不同的模式在这些视图中不断出现.标记呈现为一个孤立的内容框:

<div class="top container">
    <div class="header">
       <p>The title</p>
       <em>(and a small note)</em>
    </div>
    <div class="simpleBox rounded">
       <p>This is content.</p>
       <p><strong>Some more content</strong></p>
    </div>
</div>

这是一个简单的例子,但有更复杂的重复模式.在ASP.NET Webforms中,我会将这些代码抽象为WebControl(假设我已将其命名为BoxControl),包含在这样的页面中:

<foo:BoxControl runat="server">
  <Header>The title</Header>
  <Note>(and a small note)</Note>
  <Content>
     <p>This is content.</p>
     <p><strong>Some more content</strong></p>
  </Content>
</foo:BoxControl>

通过改变BoxControl源,这种抽象可以很容易地调整整个站点中盒子的构造方式.它还可以将静态HTML内容整齐地保存在View页面中,即使在页面上组合多个BoxControl也是如此.另一个好处是用作内容的HTML被IDE识别,从而提供语法突出显示/检查.

据我了解,在ASP.NET MVC中不鼓励使用WebControl.我可以用局部视图完成抽象,而不是WebControl.然后,这样的视图将包含在视图页面中,如下所示:

<%= Html.Partial("BoxControl",new {
  Header="The Title",Note="(and a small note)",Content="<p>This is content.</p><p><strong>Some more content</strong></p>"});
%>

这并不理想,因为’Content’参数可能会变得很长,并且IDE在传递这种方式时不会将其视为HTML.

考虑的解决方案
强类型ViewModel可以传递给Html.Partial调用,而不是上面显示的冗长参数.但是我必须从其他地方(CMS或资源文件)中提取内容.我希望内容包含在View Page中.

我也考虑过the solution proposed by Jeffrey Palermo,但这意味着很多额外的文件分散在项目周围.我希望任何视图的文本内容仅限于一个文件.

我不想抽出标记吗?或者是否有一种适合MVC的方法,我在这里可以忽略?使用WebControl“犯罪”有什么缺点?

解决方法

有一个解决这个问题的方法,虽然实现这一目标的方式比其他框架(如Ruby on Rails)更加克隆.

我使用这种方法为Twitter Bootstrap的控制组语法创建标记,如下所示:

<div class="control-group">
  <label class="control-label">[Label text here]</label>
  <div class="controls">
    [Arbitrary markup here]
  </div>
</div>

这是如何做:

1)为公共标记片段创建模型.模型应该在构造上写入标记并再次处理:

using System;
using System.Web.Mvc;

namespace My.Name.Space
{
  public class ControlGroup : IDisposable
  {
    private readonly ViewContext m_viewContext;
    private readonly TagBuilder m_controlGroup;
    private readonly TagBuilder m_controlsDiv;

    public ControlGroup(ViewContext viewContext,string labelText)
    {
      m_viewContext = viewContext;
      /*
       * <div class="control-group">
       *  <label class="control-label">Label</label>
       *  <div class="controls">
       *   input(s)
       *  </div>
       * </div>
       */

      m_controlGroup = new TagBuilder("div");
      m_controlGroup.AddCssClass("control-group");
      m_viewContext.Writer.Write(m_controlGroup.ToString(TagRenderMode.StartTag));

      if (labelText != null)
      {
        var label = new TagBuilder("label");
        label.AddCssClass("control-label");
        label.InnerHtml = labelText;
        m_viewContext.Writer.Write(label.ToString());
      }

      m_controlsDiv = new TagBuilder("div");
      m_controlsDiv.AddCssClass("controls");
      m_viewContext.Writer.Write(m_controlsDiv.ToString(TagRenderMode.StartTag));

    }

    public void Dispose()
    {
      m_viewContext.Writer.Write(m_controlsDiv.ToString(TagRenderMode.EndTag));
      m_viewContext.Writer.Write(m_controlGroup.ToString(TagRenderMode.EndTag));
    }
  }
}

2)创建一个漂亮的Html帮助器

using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;

using My.Name.Space

namespace Some.Name.Space
{
  public static class FormsHelper
  {
    public static ControlGroup ControlGroup(this HtmlHelper helper,string labelText)
    {
      return new ControlGroup(helper.ViewContext,labelText);
    }
  }
}

3)在视图中使用它(Razor代码)

@using (Html.ControlGroup("My label"))
{
  <input type="text" />
  <p>Arbitrary markup</p>
  <input type="text" name="moreInputFields" />
}

这也是MVC框架使用Html.BeginForm方法呈现表单的方式

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读