在自定义Html Helper中获取Action的MvcHtmlString

时间:2015-03-22 15:02:38

标签: c# asp.net-mvc

我正在尝试构建一个自定义html帮助程序,它将根据传递给此html帮助程序的Action显示动态内容,这是我目前所拥有的

// the Area helper class
public static class AreaHelper
{
      public static AreaBuilder CustomArea(this HtmlHelper helper)
      {
           return new AreaBuilder();
      }
}
// the area builder class
public class AreaBuilder: IHtmlString
{
    private string name;
    private string caption;
    private string action;
    private string controller;
    private object routeData;

    public AreaBuilder Name(string name)
    {
        this.name=name;
        return this;
    }

    public AreaBuilder Action(string action,string controller,object routeData)
    {
        this.action=action;
        this.controller=controller;
        this.routeData=routeData;
        return this;
    }

    public string ToHtmlString()
    {
         var html=new StringBuilder();
         html.AppendFormat(@"<div id=""{0}"" class=""area"">",name);
         html.AppendFormat(@"<div class=""area-caption"">{0}</div>",caption);
         html.AppendFormat(@"<div class=""area-content"">{0}</div>",**what should i do here**);
         html.Append("</div>");
         return html.ToString();
    }
}

我无法执行正确的步骤以获取ActionResult的内容,即我拥有它的url(action,controller,routeData)

换句话说,我如何将Action作为mvchtmlstring?

感谢任何帮助

2 个答案:

答案 0 :(得分:3)

您可以使用以下

解决方案I

  1. Add reference to System.Web.Mvc.Html;
  2. ChildActionExtensions.Action(YourHtmlHelper, action,controller,routeData);
  3. 所以你的代码会变得像

    // the area builder class
    public class AreaBuilder: IHtmlString
    {
        private string name;
        private string caption;
        private string action;
        private string controller;
        private object routeData;
        private HtmlHelper htmlHelper;
    
        public AreaBuilder Name(string name)
        {
            this.name=name;
            return this;
        }
    
        public AreaBuilder HtmlHelper(HtmlHelper helper)
        {
            this.htmlHelper=helper;
            return this;
        }
    
        public AreaBuilder Action(string action,string controller,object routeData)
        {
            this.action=action;
            this.controller=controller;
            this.routeData=routeData;
            return this;
        }
    
        public string ToHtmlString()
        {
             var html=new StringBuilder();
             html.AppendFormat(@"<div id=""{0}"" class=""area"">",name);
             html.AppendFormat(@"<div class=""area-caption"">{0}</div>",name);
             html.AppendFormat(@"<div class=""area-content"">{0}</div>",ChildActionExtensions.Action(htmlHelper, action,controller,routeData));
             html.Append("</div>");
             return html.ToString();
        }
    }
    

    和你的区域Html助手

    // the Area helper class
    public static class AreaHelper
    {
          public static AreaBuilder CustomArea(this HtmlHelper helper)
          {
               return new AreaBuilder().HtmlHelper(helper);
          }
    }
    

    解决方案II

    还有另一种方法可以实现您的目标,您可以制作以下内容

    // the area builder class
    public class AreaBuilder: IHtmlString
    {
        private string name;
        private string caption;
        private MvcHtmlString content; // to allow the use to add html content
    
        public AreaBuilder Name(string name)
        {
            this.name=name;
            return this;
        }
    
        public AreaBuilder Content(Func<object, HelperResult> html)
        {
            var detail=html.Invoke(null);
            this.content=MvcHtmlString.Create(detail.ToHtmlString());
            return this;
        }
    
        public string ToHtmlString()
        {
             var html=new StringBuilder();
             html.AppendFormat(@"<div id=""{0}"" class=""area"">",name);
             html.AppendFormat(@"<div class=""area-caption"">{0}</div>",caption);
             html.AppendFormat(@"<div class=""area-content"">{0}</div>",content.ToHtmlString());
             html.Append("</div>");
             return html.ToString();
        }
    }
    

    并在您的代码中执行以下操作,即使我认为该名称应该是CustomArea而不是CustomButton。

    @Html.CustomArea().Name("MyArea").Content(@<text>@Html.Action("YourAction","YourController",...your routing data)</text>)
    

    希望这会对你有所帮助

答案 1 :(得分:2)

据我所知,您可能最好在HtmlHelper上构建扩展方法,如下所示:

public static MvcHtmlString AreaButton(this HtmlHelper htmlHelper, string areaName, string linkText, string actionName, string controllerName, object routeData = null, object htmlAttributes = null)
{
    var div = new TagBuilder("div");
    div.AddCssClass("area");
    div.GenerateId(areaName);

    var caption = new TagBuilder("div");
    caption.AddCssClass("area-caption");
    caption.InnerHtml = areaName;

    div.InnerHtml = caption.ToString();

    var content = new TagBuilder("div");
    content.AddCssClass("area-content");
    content.InnerHtml = htmlHelper.ActionLink(linkText, actionName, controllerName, routeData, htmlAttributes).ToHtmlString();

    div.InnerHtml += content.ToString();

    return MvcHtmlString.Create(div.ToString());
}

这个方法需要在静态类中定义,我已经省略了。扩展HtmlHelper允许您利用框架中已有的工具(如TagBuilder),并利用辅助类中已有的所有工具(如ViewContext)。要使用,请执行以下操作:

@Html.AreaButton("admin", "Administration", "index", "home", new { area="admin" }, new { /* attributes to add the link itself */ })

如果您正在尝试构建指向某个区域的链接,则需要将“area”值添加到您传递给ActionLink帮助程序方法的路径字典中,如上所示。