HtmlHelper详细介绍
解决:
直接写HTML的话如果语句有语法错误,如缺少结尾标记</b>,编译器不会报错,出来的页面可能会很乱且难以查出错误在哪。如果用HtmlHelper在编译的时候就会指出错误,可以及时修改
View中的页面一般都是动态页面,也就是说如果没有HtmlHelper,我们经常会写如<input type="text" value="@id">这样的服务器端代码和HTML代码的混合代码。这样写不仅形式混乱、执行顺序不好判断,而且出错也不容易发现,不如全部用HtmlHelper写成服务器端代码。而且用HtmlHelper做数据绑定更方便。
HtmlHelper和HTML语言的关系,我觉得跟Linq和SQL语言的关系差不多。就是说微软给你提供了一种方式让你在不熟悉HTML或SQL这种非.NET语言的时候,使用.NET框架内的与之等价的类来帮助你更好的解决问题。
自定义HtmlHelperExtensions
namespace DVM.WebSite.Common { /// <summary> /// URL访问检查器 /// </summary> public class UrlAccessChecker { /// <summary> /// 检查当前用户是否具备访问特定Action权限 /// </summary> /// <param name="actionName">Action名字</param> /// <param name="controllerName">Controller名字</param> /// <returns>具备访问权限返回True,否则返回False</returns> public static Boolean HasAccess(String actionName, String controllerName) { //......... return false; } } public static class HtmlHelperExtensions { public static MvcHtmlString DictDropDownListFor<TModel,TValue>(this HtmlHelper<TModel> htmlHelper, String category, Expression<Func<TModel, TValue>> expression, string optionLabel=null, object htmlAttributes=null) where TModel:class { var dict = SystemDictionaryCache.Instance.GetNodesByRoot(category); var value = expression.Compile()(htmlHelper.ViewData.Model); var selectList = new SelectList(dict, "Key", "Value", value); return htmlHelper.DropDownListFor(expression, selectList, optionLabel, htmlAttributes); } public static MvcHtmlString DictSubDropDownListFor<TModel, TValue>(this HtmlHelper<TModel> htmlHelper, String category,int pvalue,Expression<Func<TModel, TValue>> expression, string optionLabel = null, object htmlAttributes = null) where TModel : class { var dict = pvalue<=0?new Dictionary<string, string>():SystemDictionaryCache.Instance.GetSubNodes(category,pvalue); var value = expression.Compile()(htmlHelper.ViewData.Model); var selectList = new SelectList(dict, "Key", "Value", value); return htmlHelper.DropDownListFor(expression, selectList, optionLabel, htmlAttributes); } /// <summary> /// 生成对象的Json字符串 /// </summary> /// <param name="helper">helper</param> /// <param name="o">目标对象</param> /// <returns>Html字符串</returns> public static MvcHtmlString MvcJson(this HtmlHelper helper, object o) { JavaScriptSerializer serializer = new JavaScriptSerializer(); StringBuilder builder = new StringBuilder(); serializer.Serialize( o, builder); return new MvcHtmlString(builder.ToString()); } /// <summary> /// 创建指定的a元素,如果用户没有权限访问,则返回空串 /// </summary> /// <param name="htmlHelper">htmlHelper</param> /// <param name="linkText">链接文本</param> /// <param name="actionName">Action名称</param> /// <returns>HTML内容</returns> public static MvcHtmlString ActionLinkACL( this HtmlHelper htmlHelper, string linkText, string actionName ) { var result = new MvcHtmlString(String.Empty); var controllerName = htmlHelper.ViewContext.RouteData.Values["Controller"].ToString(); if (UrlAccessChecker.HasAccess(actionName, controllerName)) { return htmlHelper.ActionLink(linkText, actionName, controllerName); } return result; } /// <summary> /// 创建指定的a元素,如果用户没有权限访问,则返回空串 /// </summary> /// <param name="htmlHelper">htmlHelper</param> /// <param name="linkText">链接文本</param> /// <param name="actionName">Action名称</param> /// <param name="routeValues">路由参数</param> /// <returns>Html内容</returns> public static MvcHtmlString ActionLinkACL( this HtmlHelper htmlHelper, string linkText, string actionName, Object routeValues ) { var result = new MvcHtmlString(String.Empty); var controllerName = htmlHelper.ViewContext.RouteData.Values["Controller"].ToString(); if (UrlAccessChecker.HasAccess(actionName, controllerName)) { return htmlHelper.ActionLink(linkText, actionName, controllerName, routeValues); } return result; } /// <summary> /// 创建AjaxLink,默认Update对象为#wrap /// 默认替代模式为replace,默认请求方式为Get /// </summary> /// <param name="htmlHelper">htmlHelper</param> /// <param name="linkText">链接文本</param> /// <param name="controllerName">Area和Controller名称,含area则使用/链接</param> /// <param name="htmlAttributes">html属性列表</param> /// <param name="innerHtml">内部Html</param> /// <returns>Html内容</returns> public static MvcHtmlString AjaxLink2ACL( this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, IDictionary<string, Object> htmlAttributes, string innerHtml, string method = "GET" ) { TagBuilder tb = new TagBuilder("a"); var defaultAttributes = new Dictionary<String, Object> { { "data-ajax-update","#wrap" }, { "data-ajax-mode","replace" }, { "data-ajax-method","GET" }, { "data-ajax-complete","closeWaitingDialog" }, { "data-ajax-begin","waitingDialog" }, { "data-ajax-success","onRequestSuccess" }, { "data-ajax-failure","onRequestFailed" }, { "data-ajax","true" }, }; if (!String.IsNullOrEmpty(method)) { defaultAttributes["data-ajax-method"] = method; } if (htmlAttributes != null) { foreach (var kp in htmlAttributes) { defaultAttributes[kp.Key] = kp.Value; } } foreach (var attr in defaultAttributes) { tb.MergeAttribute(attr.Key, Convert.ToString(attr.Value)); } var linkUrl = String.Format("{0}/{1}/{2}",HttpRuntime.AppDomainAppVirtualPath,controllerName,actionName); linkUrl = linkUrl.Replace("//", "/"); tb.MergeAttribute("href", linkUrl); tb.InnerHtml = innerHtml+linkText; return new MvcHtmlString(tb.ToString(TagRenderMode.Normal)); } } }
前台页面调用:
@using DVM.WebSite.Common;
<li> <div> @Html.AjaxLink2ACL(subMenu.Name, subMenu.ActionName, String.IsNullOrEmpty(subMenu.AreaName) ? subMenu.ControllerName : subMenu.AreaName + "/" + subMenu.ControllerName,new Dictionary < String, Object >{{ "class","" }}, "")</div> @*<div> @Url.Action(subMenu.ControllerName, subMenu.ActionName)</div> <div>@Ajax.RouteLink(subMenu.Name, new { controller = String.IsNullOrEmpty(subMenu.AreaName) ? subMenu.ControllerName : subMenu.AreaName + "/" + subMenu.ControllerName, action = subMenu.ActionName }, ajaxOptions)</div>*@ </li>