文本框本身不是带了一个MaxLength 的属性么, 怎么还有长度控制的问题? 可能有人会这样想, 可是它是把汉字当做一个字节来计算的, 而数据库中则把汉字认为是两字节, 这样就会存在问题.
当然,我首先是建议把数据库的字段设成nchar,nvarchar 这样的类型, 那么汉字也被处理成1 字节, 就没有任何问题了, 可是在现实情况下, 很多时候数据库的字段仍然是char ,varchar, 这样我们在程序中就不得不做特殊的长度检查, 否则向数据库中插入数据的时候, 将不可避免地出错.
现在就讨论数据库中的数据类型是char,varchar时的处理方法.
首先, 我们可以用 System.Text.Encoding.Default.GetByteCount(txt.Text); 这样的方法来获取到总字节数, 这里, 汉字被当做两字节, 而字母数字等仍然是单字节, 但是, 这是一种相当不友好的处理方式, 因为, 第一, 用户可能输入了很多内容, 但是提交后被告知长度超限, 用户可能会抱怨, 为什么不早点给我警告. 第二, 显然的, 这个检查过程需要往返一次服务器, 这造成许多令人不舒服的结果.
所以, 我必须采用另一种更为妥当的方式. 我希望最终的效果是: 当这个文本框被设置了限制长度后, 用户只能输入这么长, 他无法向里面录入更多的内容, 并且,除了用键盘录入外,他也有可能从别处复制代码,粘贴到当前文本框中, 所以要把粘贴的情况也一并处理掉,这样就不会提交出错, 而这个调用形式应该是简单的, 并且, 它最好是在服务器端调用. 经过一个多小时的尝试,终于完美地实现了我的要求,下面是整个流程的代码:
function master_SetDBMaxLen(txtID,maxLen)
{
var obj=document.getElementById(txtID);
if(obj==null)
return;
obj.name=maxLen;
obj.οnkeyup=function(){ master_Do_SetDBMaxLen(this);};
obj.οnpaste=function(){ master_setTimeout(master_Do_SetDBMaxLen,100,this);};
}
//本函数完成字符管制的功能,本函数启动时,逐字符检查文本框的值,当发现长度大于规定的长度时,就截断原值,并退出
function master_Do_SetDBMaxLen(obj)
{
var lenLimit=obj.name;
var val=obj.value;
var len=master_GetDBLength(val);
if(len>lenLimit)
{
var prevstr="";
for(var i=0;i<val.length;i++)
{
len=master_GetDBLength(val.substring(0,i+1));
if(len>lenLimit)
{
obj.value=prevstr;
return;
}
prevstr=val.substring(0,i+1);
}
}
}
//本函数返回一个串的数据库中使用的数据长度,即: 汉字算2字节,字母数字等算1字节.
function master_GetDBLength(val)
{
var len=0;
for (var i=0;i<val.length;i++)
{
if ((val.charCodeAt(i) < 0) || (val.charCodeAt(i) > 255))
len+=2;
else
len++;
}
return len;
}
代码中用到了master_setTimeout 函数, 关于这个函数, 请参见本人的另一篇博文:
http://moosdau.blog.163.com/blog/static/437112820086291357770
以上三个函数都是JS 函数, 由于我把它们都放在母版页里, 所以这些函数名都以master 开头, 要程序中调用JS函数不是一个讨人喜欢的主意, 所以我把它们封装到一个C# 函数中:
///<summary>
///本函数设置一个文本框的最大允许长度,其中每个汉字计算为两字节.
///</summary>
///<param name="txt">文本框控件</param>
///<param name="maxLen">允许输入的最大长度</param>
public static void SetDBMaxLen(System.Web.UI.WebControls.TextBox txt,int maxLen)
{
string js = "master_SetDBMaxLen('" + txt.ClientID + "'," + maxLen +");";
MUT.ASPTool.RunJs(js);
}
其中,MUT.ASPTool.RunJs 的代码如下:
///<summary>
///运行js脚本, 自带script 等tag, 参数仅需传递js 语句.
///</summary>
///<param name="js"></param>
public staticvoid RunJs(string js)
{
System.Web.UI.Page page=System.Web.HttpContext.Current.CurrentHandleras System.Web.UI.Page;
System.Web.UI.ScriptManager.RegisterStartupScript(page, page.GetType(),"", js, true);
}
这样, 整个功能就封装完成了,在页面上调用时,只要在页面首次载入时,执行
SetDBMaxLen(txtEditRemark, 50);
就可以了.