天天看点

自定义ASP.NET MVC Html辅助方法

在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辅助方法。如下图所示:

自定义ASP.NET MVC Html辅助方法

使用方法和其它html辅助方法一样,如下代码所示:

      <%: html.input("path") %> //字符串参数path代表生成标签的name属性和id属性的值 

需要说明的是,本例所示是为了生成<input type="file">标签,是不用设置值的,读者可以通过自身情况定义扩展方法。然后运行,通过浏览器查看html源代码,如下图所示:

自定义ASP.NET MVC 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辅助方法了。如下图所示:

  

自定义ASP.NET MVC Html辅助方法

我们可以通过如下代码使用新扩展的html辅助方法:

       <%: html.input(model

=> model.path) %>//path代表model的path属性,生成标签的name和id的属性值均会是path

运行,我们通过浏览器查看生成的html源代码如下图所示:

自定义ASP.NET MVC 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));

        }

继续阅读