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>