TextBoxFor控件的问题:

1:自带了样式,再用bootstrap样式会有冲突。

2:要加水印,js事件,限制输入长度比较麻烦。

因此需要对textboxfor控件进行扩展。

目标:

1:能使用bootstrap样式。

2:能复用mvc的验证。

3:可以方便的添加水印。

4:能限制输入字符的长度。

5:采用一些命名约定,使用扩展控件。(说白了,就是日期类型的直接给上边加上调用日期控件的调用。)

解决方案

最容易想到的解决办法就是直接写个扩展方法,进行字符串拼接生成控件。使用的时候:@BootStrap.TextBoxFor(u=>u.Email)

最终生成:

 <input class="form-control" data-val="true" data-val-length="字段 邮箱 必须是最大长度为 50 的字符串。" data-val-length-max="50" data-val-regex="字段 邮箱 必须与正则表达式“.+”匹配。" data-val-regex-pattern=".+" data-val-required="邮箱 字段是必需的。" id="Email" maxlength="50" name="Email" type="text" value="taibaizhou@163.com"></input>
<span class="field-validation-valid help-block" data-valmsg-for="Email" data-valmsg-replace="true"></span>

实现时候,悲催了。发现很难直接获取属性的验证信息,难道要自己再写反射,读取特性。生成对应的验证信息。

另一条路,借助mvc的htmlhelper来完成了。

        public static MvcHtmlString BsTextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,string css="", string placeholder="")
{
TagBuilder tagBuilder = new TagBuilder("input");
ModelMetadata metadata = ModelMetadata.FromLambdaExpression<TModel, TProperty>(expression, htmlHelper.ViewData);
//tagBuilder.MergeAttributes(htmlHelper.GetUnobtrusiveValidationAttributes(ExpressionHelper.GetExpressionText(expression), metadata));
string name = ExpressionHelper.GetExpressionText(expression);
//var vas = htmlHelper.GetUnobtrusiveValidationAttributes(name, metadata);
htmlHelper.ValidateFor(expression);
tagBuilder.MergeAttribute("name",name);
tagBuilder.GenerateId(name);
tagBuilder.MergeAttribute("type","text");
       //核心代码,直接通过这个方法可以获取属性上的验证信息,如:“data-val= ....”。有一点要注意,在一个属性上,调用了这个方法完成后。mvc底层代码会自动释放这个验证对象。也就是说,一个属性的输入文本框只会第一个上边会生成相关的验证。
var vas = htmlHelper.GetUnobtrusiveValidationAttributes(name,metadata); 
if (!string.IsNullOrEmpty(placeholder)) { tagBuilder.MergeAttribute("placeholder",placeholder); }
       //string类型,看有没长度限制,如果有,增加maxlength,minlength
if (metadata.ModelType == typeof (string))
{
var len = metadata.ContainerType.GetProperty(name).GetCustomAttribute(typeof(StringLengthAttribute));
if (len != null)
{
var stringlength = (StringLengthAttribute) len;
if (stringlength.MaximumLength > )
{
tagBuilder.MergeAttribute("maxlength", stringlength.MaximumLength.ToString());
}
if (stringlength.MinimumLength > )
{
tagBuilder.MergeAttribute("minlength", stringlength.MinimumLength.ToString());
}
}
}
       //如果model值不为,null,进行赋值。
if (metadata.Model != null)
{
          todo:还要完善。
tagBuilder.MergeAttribute("value",metadata.Model.ToString());
}
tagBuilder.MergeAttributes(vas);
tagBuilder.AddCssClass("form-control");
if (!string.IsNullOrEmpty(css))
{
tagBuilder.AddCssClass(css);
}
       //约定,属性名以day或者date结束的属性为日体,为其增加日期选择功能。
if (name.ToLower().EndsWith("day") || name.ToLower().EndsWith("date"))
{
tagBuilder.MergeAttribute("onclick", "WdatePicker()");
}
return new MvcHtmlString(tagBuilder.ToString());
}

最终实现效果:

View部分代码:

  <div class="form-group">
@Html.BsLabelFor(model => model.Email)
<div class="col-xs-10">
@*@Html.TextBoxFor(model => model.Email, new { @class = "form-control" })*@
@Html.BsTextBoxFor(model=>model.Email)
@Html.ValidationMessageFor(model => model.Email, "", new { @class = "help-block" }) </div>
</div>
<div class="form-group">
@Html.BsLabelFor(model => model.Salary)
<div class="col-xs-2 input-group" >
<div class="input-group-addon">$</div>
@Html.BsTextBoxFor(model => model.Salary)
<div class="input-group-addon">.00</div>
</div><div class="col-xs-8">
@Html.ValidationMessageFor(model => model.Salary, "", new { @class = "help-block" })
</div>
</div>
<div class="form-group">
@Html.BsLabelFor(model => model.Code)
<div class="col-xs-2">
@Html.BsTextBoxFor(model => model.Code)
</div><div class="col-xs-8">
@Html.ValidationMessageFor(model => model.Code, "", new { @class = "help-block" })
</div>
</div>
<div class="form-group">
@Html.BsLabelFor(model => model.BirthDay)
<div class="col-xs-2 input-group">
@Html.BsTextBoxFor(model => model.BirthDay)<div class="input-group-addon" onclick="WdatePicker({ el: 'BirthDay' })">
<span class="glyphicon glyphicon-th"></span>
</div>
</div><div class="col-xs-8">
@Html.ValidationMessageFor(model => model.BirthDay)
</div>
</div>

viewModel代码:

  public class VerifyModel
{
public Guid Id { get; set; }
[DisplayName("用户名")]
[Required]
[StringLength()]
[Remote("CheckName", "Form")]
public string UserName { get; set; }
[DisplayName("密码")]
[Required]
[StringLength(,MinimumLength = )]
[DataType(DataType.Password)]
public string PassWord { get; set; }
[DataType(DataType.Password)]
[System.ComponentModel.DataAnnotations.Compare("PassWord", ErrorMessage = "两次输入密码不一致")]
[DisplayName("确认密码")]
public virtual string ConfirmPassWord { get; set; }
[StringLength()]
[DisplayName("邮箱")]
[Required]
[DataType(DataType.EmailAddress)]
[RegularExpression(@".+")]
public string Email { get; set; }
[RegularExpression(@"1\d{10}", ErrorMessage = "请输入正确的手机号码")]
[DisplayName("手机")]
[Required]
public string Phone { get; set; }
[DisplayName("薪水")]
[Required]
public decimal Salary { get; set; }
[RegularExpression(@"d{6}", ErrorMessage = "邮编为六位数字")]
[DisplayName("邮编")]
[Required]
public string Code { get; set; }
[DisplayName("生日")]
[Required]
public DateTime BirthDay { get; set; }
}

最后:

配合T4模板,采用一些命名约定能更快捷的生成各种表单页面。

TextBoxFor控件的扩展---Bootstrap在mvc上的应用的更多相关文章

  1. MvcPager分页控件以适用Bootstrap

    随笔- 9  文章- 0  评论- 33  修改MvcPager分页控件以适用Bootstrap 效果(含英文版,可下载)   软件开发分页效果必不可少,对于Asp.Net MVC 而言,MvcPag ...

  2. 验证控件插图扩展控件ValidatorCalloutExtender(用于扩展验证控件)和TextBoxWatermarkExtender

    <asp:ScriptManager ID="ScriptManager1" runat="server">  </asp:ScriptMan ...

  3. (转)C# WinForm中 获得当前鼠标所在控件 或 将窗体中鼠标所在控件名显示在窗体标题上

    原文地址:http://www.cnblogs.com/08shiyan/archive/2011/04/14/2015758.html /********************** * 课题:将窗 ...

  4. 使用NeatUpload控件实现ASP.NET大文件上传

    使用NeatUpload控件实现ASP.NET大文件上传 一般10M以下的文件上传通过设置Web.Config,再用VS自带的FileUpload控件就可以了,但是如果要上传100M甚至1G的文件就不 ...

  5. 使用input:file控件在微信内置浏览器上传文件返回未显示选择的文件

    使用input:file控件在微信内置浏览器上传文件返回未显示选择的文件 原来的写法: <input type="file" accept="image/x-png ...

  6. 【C#】使用IExtenderProvider为控件添加扩展属性,像ToolTip那样

    申明: - 本文适用于WinForm开发 - 文中的“控件”一词是广义上的说法,泛指包括ToolStripItem.MenuItem在内单个界面元素,并不特指继承自Control类的狭义控件 用过To ...

  7. WPF中查找控件的扩展类

    在wpf中查找控件要用到VisualTreeHelper类,但这个类并没有按照名字查找控件的方法,于是搜索网络,整理出下面这个类,感觉用起来很是方便. 贴出来,供大家参考. /// <summa ...

  8. WPF之花式控件功能扩展

    文章默认你已经入门WPF了 ​ WPF日常开发,经常遇到默认的控件功能不满足需求,怎么办? No1. 自定义控件模板 ​ 平时开发中,经常遇到比较"俗"的需求,嫌弃控件默认的样子. ...

  9. asp.net ajax控件tab扩展,极品啊,秒杀其它插件

    说明:asp.net ajax控件tab要设置width和height,而且在线文本编辑器放能够放入tab中,也必须是asp.net的控件型在线文本,例如fckeditor,下面是我设置好的配置. & ...

随机推荐

  1. Python将MySQL表数据写入excel

    背景:将mysql表查询结果写入excel. 1.使用sqlyog工具将查询结果导出到Excel.xml中,用excel打开发现:因为text字段中有回车换行操作,显示结果行是乱的. 2.用mysql ...

  2. 中科院分词ICTCLAS5.0_JNI 使用方法

    1.简介 中国科学院计算技术研究所在多年研究基础上,耗时一年研制出了基于多层隐码模型的汉语词法分析系统 ICTCLAS(Institute of Computing Technology, Chine ...

  3. jsp html5 video实现在线视频播放源码,支持IE6,7,8,10,11,谷歌,火狐等浏览器

    jsp源码: <%@ page language="java" import="java.util.*" pageEncoding="utf-8 ...

  4. Arch Linux sudo: PAM authentication error: Module is unknown [Solved!]

    问题描述: 我的 Arch Linux 已经用了快半年多,由于 Arch Linux 的滚挂问题,我从没有直接升级过系统.软件版本以及库自然落后了一些. 就在我准备需要用到 NFS 时,挂载网络文件系 ...

  5. Python定时任务框架APScheduler 3.0.3 Cron示例

    APScheduler是基于Quartz的一个Python定时任务框架,实现了Quartz的所有功能,使用起来十分方便.提供了基于日期.固定时间间隔以及crontab类型的任务,并且可以持久化任务.基 ...

  6. [转] OpenStack Kilo 更新日志

    OpenStack 2015.1.0 (Kilo)更新日志 原文: https://wiki.openstack.org/wiki/ReleaseNotes/Kilo/zh-hans 目录  [隐藏] ...

  7. 彻底解决mysql中文乱码的办法,修改mysql解压缩版(免安装版或zip版)字符编码

    MySQL会出现中文乱码的原因不外乎下列几点:1.server本身设定问题,例如server字符编码还停留在latin12.table的语系设定问题(包含character与collation)3.客 ...

  8. For循环案例---九九乘法表

    概述:先创建一个Print99类,类中创建5个方法,分别为Test9901.Test9902.Test9903.Test9904.Test9905,分别打印出不同形状的九九乘法表,该类创建完成后再创建 ...

  9. Remote Displayer for Android V1.2

    VERSION LOG for Android Remote Displayer Features:The app allows you to see your Android device remo ...

  10. excel技巧

    1. 使文字自动适配方格大小. 自动调整行高(但是合并后的方格不行)