自定义ASP.NET MVC Html标签辅助方法
原文:https://blog.csdn.net/a497785609/article/details/50184779
在ASP.NET MVC中,Html辅助方法给我们程序员带来很多方便,其重要性也就不言自明。有时候,我们不想重复地写一些HTML代码,或者MS没有提供我们想要的那个HTML标签的Html辅助方法,那么,我们就可以通过自己定义一个Html扩展方法来达到这个目的。
比如,到目前为止,Html扩展方法中没有关于<input type="file" />这类标签的辅助方法,那么我们就可以自已实现一个。本文以实现<input type="file" />标签为例,演示如何实现自定义Html扩展方法。
一、实现自定义弱类型Html扩展方法
其实实现自定义Html扩展方法并不难,有兴趣的同学可以去看下MVC源代码,关于Html扩展方法部分。要用到System.Web.Mvc命名空间下的TagBuilder类,MvcHtmlString类。TagBuilder类为Html辅助方法生成HTML标签,MvcHtmlString代表HTML编码的字符串。扩展方法代码如下所示:
public static class MyInputExtensions
{
public static MvcHtmlString Input(this HtmlHelper htmlHelper, string name)
{ TagBuilder tagBuilder = new TagBuilder("input");//设置标签类型为input tagBuilder.Attributes.Add("type", "file");//为标签添加type属性及值 tagBuilder.Attributes.Add("name", name);//为标签添加name属性及值 tagBuilder.GenerateId(name);//为标签生成Id,name参数代码Id的值 //创建经过HTML加密的字符串 //TagRenderMode.SelfClosing枚举值代表当前标签是自动关闭的 return MvcHtmlString.Create(tagBuilder.ToString(TagRenderMode.SelfClosing));
}
}
需要特别提醒的是,扩展方法类所在的命名空间最好设置为System.Web.Mvc,这样,我们在View中可以通过智能感知轻易找到,也不容易出错或者无法通过VS智能感知找到我们自定义的Html辅助方法,可以为我们省去很多不必要的麻烦。将上面代码编译,我们即可在View中通过智能感知看到我们自定义的Html辅助方法。如下图所示:
使用方法和其它Html辅助方法一样,如下代码所示:
<%: Html.Input("Path") %> //字符串参数Path代表生成标签的name属性和id属性的值
需要说明的是,本例所示是为了生成<input type="file">标签,是不用设置值的,读者可以通过自身情况定义扩展方法。然后运行,通过浏览器查看HTML源代码,如下图所示:
二、实现自定义强类型Html辅助方法
强类型辅助方法的一个好处是,我们可以通过编译器为我们检测一些错误,为我们节省一些排错的时间与精力。所以,强类型Html辅助方法是不可缺少的。代码如下:
public static class MyInputExtensions { public static MvcHtmlString Input<TModel, TValue>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TValue>> expression) { string modelName = ExpressionHelper.GetExpressionText(expression);//从Lambda表达式中获取模型对应属性的名称 TagBuilder tagBuilder = new TagBuilder("input");//设置标签类型为input tagBuilder.Attributes.Add("type", "file");//为标签添加type属性及值 tagBuilder.Attributes.Add("name", modelName);//为标签添加name属性及值 tagBuilder.GenerateId(modelName);//为标签生成Id,name参数代码Id的值 //创建经过HTML加密的字符串 //TagRenderMode.SelfClosing枚举值代表当前标签是自动关闭的 return MvcHtmlString.Create(tagBuilder.ToString(TagRenderMode.SelfClosing)); } }
然后我们编译,在View中,我们就可以通过智能感知看到我们新扩展的强类型Html辅助方法了。如下图所示:
我们可以通过如下代码使用新扩展的Html辅助方法:
<%: Html.Input(model => model.Path) %>//Path代表model的Path属性,生成标签的name和id的属性值均会是Path
运行,我们通过浏览器查看生成的Html源代码如下图所示:
三、为标签错误输入添加CSS支持
对于要求输入的标签,如Text,如果用户输入错误内容,我们可以为当前标签添加CSS错误提示,为用户提供一个更加友好、人性化的界面。代码如下所示:
ModelState modelState; if (htmlHelper.ViewData.ModelState.TryGetValue(name, out modelState)) { if (modelState.Errors.Count > 0) { //添加错误提示CSS tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName); } }
将以上代码复制到我们自定义的扩展方法的返回MvcHtmlString字符串之前即可。
四、总结
本文通过演示如果实现自定义<input type="file" />标签的Html辅助方法,展示了如何在ASP.NET MVC中实现自定义Html辅助方法。对于ASP.NET MVC程序员来说,这是非常实用的。
五、补充
一个完整的扩展示例方法:
public static MvcHtmlString InputText<TModel, TValue>(this HtmlHelper<TModel> html,
Expression<Func<TModel, TValue>> expression, IDictionary<string, object> htmlAttributes)
{
TagBuilder tagBuilder = new TagBuilder("input"); var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData); //第1步:获取模型字段的显示文本
string text = metadata.DisplayName ?? metadata.PropertyName; //第2步:获取模型字段的字段名
var name = ExpressionHelper.GetExpressionText(expression); //第3步:获取模型字段的值
#region 模型字段的值 string value;
ModelState modelState;
string fullName = html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
if (html.ViewData.ModelState.TryGetValue(fullName, out modelState) && modelState.Errors.Count > 0)
{
tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName);
}
if (modelState != null && modelState.Value != null)
{
value = modelState.Value.AttemptedValue;
}
else if (metadata.Model != null)
{
value = metadata.Model.ToString();
}
else
{
value = String.Empty;
} #endregion tagBuilder.Attributes.Add("type", "text");
tagBuilder.Attributes.Add("name", name);
tagBuilder.Attributes.Add("value", value);
//第4步:填充其他自定义属性
tagBuilder.MergeAttributes(htmlAttributes, true);
tagBuilder.GenerateId(name); return MvcHtmlString.Create(tagBuilder.ToString(TagRenderMode.SelfClosing));
}
另外一个例子
public static class FileUploadExtension
{ private const string CanReadExts = ".doc;.docx;.rtf;.xml;.html;.htm;.odt;.xls;.xlsx;.ppt;.pptx;.pdf;.txt;.mpp";
private const string ImgExts = ".jpg;.jpeg;.png;.bmp;.gif";
private const string CanEditExts = ".doc;.docx"; /// <summary>
/// 上传文件扩展,绑定到模型字段
/// </summary>
/// <typeparam name="TModel">模型</typeparam>
/// <typeparam name="TProperty">模型对应属性</typeparam>
/// <param name="helper"></param>
/// <param name="pathsExpr">保存上传文件路径的属性表达式</param>
/// <param name="multi">是否多文件上传(false时为单文件)</param>
/// <param name="fileTypeExts">上传文件扩展名,用“分号”分割不同扩展名(如: '.jpg','.png')</param>
/// <param name="htmlAttributes">html属性集合对象</param>
/// <param name="editMode">是否为编辑模式</param>
/// <param name="onlineView">是否可以在线阅读</param>
/// <param name="onlineEdit">是否可以在线编辑</param>
/// <param name="callBack">上传成功的回掉函数</param>
/// <returns></returns>
public static MvcHtmlString FileUploadFor<TModel, TProperty>
(this HtmlHelper<TModel> helper,
Expression<Func<TModel, TProperty>> pathsExpr,
bool multi = true,
string fileTypeExts = null,
object htmlAttributes = null,
bool editMode = true,
bool onlineView = true,
bool onlineEdit = false, string callBack = "")
{
//检查model是否存在
if (helper.ViewData != null && null == helper.ViewData.Model)
throw new NoNullAllowedException("View Model 不能为空! 请确保 View Model 被创建了并且传输到当前视图."); //从model中获得数据
if (helper.ViewData != null)
{
var model = helper.ViewData.Model; //检查是否绑定到了model的属性上
var name = ExpressionHelper.GetExpressionText(pathsExpr);
if (String.IsNullOrEmpty(name))
throw new ArgumentException("名称不能为空!", "pathsExpr"); //获得已经上传文件名称列表
var pathsFunc = pathsExpr.Compile();
var nameStr = "";
if (pathsFunc(model) != null)
{
nameStr = pathsFunc(model).ToString();
} var metadata = ModelMetadata.FromLambdaExpression(pathsExpr, helper.ViewData);
var isRequired = metadata.IsRequired;
var displayName = isRequired ? metadata.DisplayName : ""; return FileUpload(helper, name, nameStr, multi, fileTypeExts, htmlAttributes, editMode, onlineView,
onlineEdit, isRequired, displayName, callBack);
}
else
{
return new MvcHtmlString("");
}
} /// <summary>
/// 上传文件,指定name和value不需要绑定到字段
/// </summary>
/// <param name="helper">上下文</param>
/// <param name="name">后台接收时使用的名称</param>
/// <param name="value">值,上传文件的标识串</param>
/// <param name="multi">是否可以上传多个</param>
/// <param name="fileTypeExts">文件类型扩展名列表</param>
/// <param name="htmlAttributes">附加的html属性</param>
/// <param name="editMode">是否为编辑模式</param>
/// <param name="onlineView">是否可以在线阅读</param>
/// <param name="onlineEdit">是否允许在线编辑</param>
/// <param name="isRequired">是否非空验证</param>
/// <param name="displayName">非空时提示名称</param>
/// <param name="callBack">上传成功的回掉函数</param>
/// <returns></returns>
public static MvcHtmlString FileUpload<TModel>
(
this HtmlHelper<TModel> helper,
string name,
string value,
bool multi = true,
string fileTypeExts = null,
object htmlAttributes = null,
bool editMode = true,
bool onlineView = true,
bool onlineEdit = false,
bool isRequired = false,
string displayName = "",
string callBack = ""
)
{
var id = Utils.CreateTagId("fine-uploader"); return FileUpload(helper, id, name, value, multi, fileTypeExts, htmlAttributes, editMode, onlineView, onlineEdit, isRequired: isRequired, displayName: displayName, callBack: callBack);
} /// <summary>
/// 上传文件,指定name和value不需要绑定到字段
/// </summary>
/// <param name="helper">上下文</param>
/// <param name="id">容器ID</param>
/// <param name="name">后台接收时使用的名称</param>
/// <param name="value">值,上传文件的标识串</param>
/// <param name="multi">是否可以上传多个</param>
/// <param name="fileTypeExts">文件类型扩展名列表</param>
/// <param name="htmlAttributes">附加的html属性</param>
/// <param name="editMode">是否为编辑模式</param>
/// <param name="onlineView">是否可以在线阅读</param>
/// <param name="onlineEdit">是否允许在线编辑</param>
/// <param name="width">上传文件内容显示宽度</param>
/// <param name="isRequired">是否非空验证</param>
/// <param name="displayName">非空时提示名称</param>
/// <param name="callBack">上传成功的回掉函数</param>
/// <returns></returns>
public static MvcHtmlString FileUpload<TModel>
(this HtmlHelper<TModel> helper,
string id,
string name,
string value,
bool multi = true,
string fileTypeExts = null,
object htmlAttributes = null,
bool editMode = true,
bool onlineView = true,
bool onlineEdit = false,
int width = 722,
bool isRequired = false,
string displayName = "",
string callBack = "")
{
//内容容器
var div = new TagBuilder("div");
div.MergeAttribute("id", id);
div.MergeAttribute("data-multi", multi.ToString().ToLower());
div.MergeAttribute("data-filetypeexts", fileTypeExts);
div.MergeAttribute("data-editmode", editMode.ToString().ToLower());
div.MergeAttribute("data-onlineView", onlineView.ToString().ToLower());
div.MergeAttribute("data-onlineEdit", onlineEdit.ToString().ToLower());
div.MergeAttribute("data-canReadExts", CanReadExts.ToLower());
div.MergeAttribute("data-canEditExts", CanEditExts.ToLower()); div.MergeAttributes(HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
if (width <= 0) width = 692;
var widthStr = "width:" + width + "px";
div.MergeAttribute("style", widthStr);
//值保存位置
var input = new TagBuilder("input");
input.MergeAttribute("type", "text");
input.MergeAttribute("id", id + "-hidden");
input.MergeAttribute("name", name);
input.MergeAttribute("value", value);
input.MergeAttribute("style", "visibility: hidden;height: 0;width: 0;position:absolute;");
if (isRequired)
{
input.MergeAttribute("data-val", "true");
input.MergeAttribute("data-val-required", displayName + "不能为空");
} //产生上传文件的区域代码
var uploadedFileStr = CreateUploadedTag(helper, value, editMode, onlineView, onlineEdit); //隐藏已上传文件的html内容
var hidDiv = new TagBuilder("div");
hidDiv.AddCssClass("fileUploaderedHidDiv");
hidDiv.MergeAttribute("style", "display:none");
hidDiv.InnerHtml = uploadedFileStr; div.InnerHtml += hidDiv.ToString(); //初始化脚本
var script = new TagBuilder("script");
script.InnerHtml += "jQuery(function(){createUploader('" + id + "'," + editMode.ToString().ToLower() + ",'" +
uploadedFileStr + "'," + multi.ToString().ToLower() + ",'" + fileTypeExts + "','" + callBack + "');});"; return MvcHtmlString.Create(div + input.ToString() + script);
}
}
自定义ASP.NET MVC Html标签辅助方法的更多相关文章
- MVC 之HTML辅助方法
顾名思义,HTML辅助方法(HTML Helper)就是用来辅助产生HTML之用,在开发View的时候一定会面对许多HTML标签,处理这些HTML的工作非常繁琐,为了降低View的复杂度,可以使用HT ...
- 【未完待续】MVC 之HTML辅助方法
顾名思义,HTML辅助方法(HTML Helper)就是用来辅助产生HTML之用, 在开发View的时候一定会面对许多HTML标签,处理这些HTML的工作非常繁琐,为了降低View的复杂度,可以使用H ...
- ASP.NET MVC 5 - 验证编辑方法(Edit method)和编辑视图(Edit view)
在本节中,您将验证电影控制器生成的编辑方法(Edit action methods)和视图.但是首先将修改点代码,使得发布日期属性(ReleaseDate)看上去更好.打开Models \ Movie ...
- [转]ASP.NET MVC 5 - 验证编辑方法(Edit method)和编辑视图(Edit view)
在本节中,您将验证电影控制器生成的编辑方法(Edit action methods)和视图.但是首先将修改点代码,使得发布日期属性(ReleaseDate)看上去更好.打开Models \ Movie ...
- [转]自定义ASP.NET MVC JsonResult序列化结果
本文转自:http://blog.163.com/luckcq@yeah/blog/static/17174770720121293437119/ 最近项目中前台页面使用EasyUI的jQuery插件 ...
- vs 2013下自定义ASP.net MVC 5/Web API 2 模板(T4 视图模板/控制器模板)
vs 2013下自定义ASP.net MVC 5/Web API 2 模板(T4 视图模板/控制器模板): Customizing ASP.NET MVC 5/Web API 2 Scaffoldi ...
- 转:自定义ASP.NET MVC Html辅助方法
在ASP.NET MVC中,Html辅助方法给我们程序员带来很多方便,其重要性也就不言自明.有时候,我们不想重复地写一些HTML代码,或者MS没有提供我们想要的那个HTML标签的Html辅助方法,那么 ...
- 【MVC】自定义ASP.NET MVC Html辅助方法
在ASP.NET MVC中,Html辅助方法给我们程序员带来很多方便,其重要性也就不言自明.有时候,我们不想重复地写一些HTML代码,或者MS没有提供我们想要的那个HTML标签的Html辅助方法,那么 ...
- [转载]自定义ASP.NET MVC Html辅助方法 TagBuilder
在ASP.NET MVC中,Html辅助方法给我们程序员带来很多方便,其重要性也就不言自明.有时候,我们不想重复地写一些HTML代码,或者MS没有提供我们想要的那个HTML标签的Html辅助方法,那么 ...
随机推荐
- 使用.NET 6开发TodoList应用(11)——使用FluentValidation和MediatR实现接口请求验证
系列导航及源代码 使用.NET 6开发TodoList应用文章索引 需求 在响应请求处理的过程中,我们经常需要对请求参数的合法性进行校验,如果参数不合法,将不继续进行业务逻辑的处理.我们当然可以将每个 ...
- WHT, SLANT, Haar
目录 基本 酉变换 WALSH-HADAMARD TRANSFORMS sequency-ordered WHT SLANT TRANSFORM Haar Transform Gonzalez R. ...
- <数据结构>XDOJ332.二叉排序树的判定
问题与解答 问题描述 给定一个二叉树,判断其是否是一个有效的二叉排序树. 假设一个二叉排序树具有如下特征: 结点的左子树只包含小于当前结点的树. 结点的右子树只包含大于当前结点的树. 所有左子树和右子 ...
- 中华古诗词知识图谱之实体关系构建&导入neo4j数据库
实体分析 诗名实体 属性 包含:作诗时间,诗名,内容,翻译,背景. 关系 实体1 关系 实体2 诗名 形式 诗词形式 诗名 作者 诗人 诗名 分类 类别 诗名 词牌名 词牌名 诗名 曲牌名 曲牌名 诗 ...
- 【工具】Java转换exe
一.导出jar包 eclipse中对着要转换的项目,右键,导出 搜索jar,选择jar文件,下一步 选择要输出的项目 继续下一步 选择主程序 完成 二.下载及安装exe4j,并转换jar文件为exe文 ...
- Zookeeper基础教程(六):.net core使用Zookeeper
Demo代码已提交到gitee,感兴趣的更有可以直接克隆使用,地址:https://gitee.com/shanfeng1000/dotnetcore-demo/tree/master/Zookeep ...
- Linux下如何部署FTP服务器
FTP 是 File Transfer Protocol 的缩写,即文件传输协议,它通过网络在服务器和客户端之间传输文件,现在已经成为一种广泛使用的标准工具 vsftpd 是 very secure ...
- Unity3D开发入门教程(二)—— Lua入门
五邑隐侠,本名关健昌,12年游戏生涯. 本教程以 Unity 3D + VS Code + C# + tolua 为例. 如果你还没有编程基础,建议你先学习一些编程基础.本文不是完全菜鸟教程,主要针对 ...
- linux 下安装minconda3
一.关于bashrc目录,此文件是隐藏的,如果要打开此文件需要用: vim /root/.bashrc 二.linux下关于防火墙的命令 1.查看防火墙状态 firewall-cmd --state ...
- Nginx 添加防爬虫
include agent_deny.conf; conf下添加 #禁止Scrapy|curl等工具的抓取 if ($http_user_agent ~* (Scrapy|Curl|HttpClien ...