扩展标签控件

分享于 

14分钟阅读

Web开发

  繁體

介绍

这篇小文章展示了如何扩展 ASP.NET 标签 控件,以便从XML文件读取资源字符串,该文件作为缓存存储在内存中 数据集 使用缓存依赖项对xml文件。 每个网页都有自己的xml文件,其中存储文本。

如果你需要将web应用程序翻译成它的他语言,或者网站的所有者想要修改"static"文件,可以使用它。

程序可以很容易地扩展,这样资源文本就从另一个源读取,如数据库。Web服务或者资源文件。

我在生产中使用了这种技术,但是因为我们在生产中使用了web场,因这里在数据库中保存所有字符串。 它也是一个好主意,给web应用程序所有者,一个更好的接口,更改文本。 我可能会写另一篇文章,告诉你如何。

示例项目中使用的一些. NET 特性:

  • 自定义控件
  • 数据集
  • XML
  • 高速缓存

代码概述

控件称为 TextControl,因为它处理字符串资源中的文本。 也许 NAME 和StringResource更好,但是 TextControl 必须做。 你可以随意改变它:)

代码的中心部分由一个自定义控件组成,该控件继承自 ASP.NET,并扩展了 标签 控件。控件还使用一个名为 XMLResource的helper 类,该类将在后面解释。

[DefaultProperty("Key"), 
ToolboxData("<{0}:TextControl runat="server"></{0}:TextControl>")]publicclass TextControl : System.Web.UI.WebControls.Label

我想从 inherit 那里找到的原因 标签 控件代替基控件类,我想使用已经在中实现的呈现函数。 标签 控制不同字体,颜色和材质。 我懒惰;

TextControl 需要知道它应该从文本资源获得什么文本字符串,所以我将一个新属性添加到 Key 中。 我也可以使用继承 文本 属性已经在那里,但是我最好使用 文本 属性( 稍后显示)。

privatestring key;
[Bindable(true), 
 Category("Appearance"),
 DefaultValue(""),
 Description("ID/Key of the resource text to get")] publicstring Key 
{
 get {
 return key;
 }
 set {
 key = value;
 }
}

实际上,关于代码 Fragment 上面的内容并不多。 在 VisualStudio.NET.的属性对话框中,具有正确属性或者属性的重要性不能显示

控件的最终( 有趣的部分) 是在运行时和设计时呈现输出的代码。 要做到这一点,你必须重写 渲染( ) 方法 标签 当ASPX页呈现内容时,页将调用这里 渲染( ) 页上每个控件的方法。

protectedoverridevoid Render(HtmlTextWriter output)
{
 try {
 //get the text string from the resource//the Text property is used as"default" value Text = new XMLResource().GetValueFromKey(Key, Text);
 //call base class for renderingbase.Render(output);
 }
 catch//catch design-time exceptions  {
 //render the Text property with bracketsString tmpText = Text;
 Text = "[" + Text + "]";
 //call base class for renderingbase.Render(output);
 //put back the default text without brackets Text = tmpText;
 }
}

就像你在代码 上面 中所看到的,我使用的是 try / catch 当我们从资源获取文本时,block 会处理错误。 如果XML文件与ASPX文件( 如简介中所述) 相同,那么从一个名为 Default.aspx的ASPX文件中获取文本,因此该页的资源XML文件称为 Default.xml,位于与ASPX页相同的目录。

若要获取ASPX文件的NAME,请使用 CurrentExecutionFilePath 属性 请求 对象。 请求 通过当前对象访问对象 HttpContext ,因这里在设计时不可以用,因这里我捕获引发的异常并显示方括号中的默认文本。 你也可以防止在 XMLResource 类( 显示如下),但这对我很有用。

如果请求的字符串( 基于 密钥 ) 未找到或者发生异常,我将显示默认文本,从使用中获得 文本 父对象的属性 标签 控件。

那么,我们如何从资源文件中获取文本? 全部都是在 XMLResource 类,我将尝试解释 below。 iPhone 7 还没出来,我们已经在iPhone上获取细节 8,或者不管是想到下一步。 XMLResource 类有两种方法;一个 public 获取请求的文本字符串和一个 private,后者从缓存的文件获取XML文件 数据集 首先,public 方法:

publicString GetValueFromKey(String key, String defaultValue)
{
 DataSet ds = GetResourceDS();
 //filter out everything except our resource string in a dataview DataView dv = ds.Tables[0].DefaultView;
 dv.RowFilter = "key = '" + key + "'";
 if(dv.Count >0) //key found, show the valuereturn dv[0]["value"].ToString();
 else//key not found return default valuereturn defaultValue;
}

很简单,拿一个 数据集 ,它包含这里ASPX页的所有资源字符串。 然后根据键过滤掉我们的文本字符串。 如果没有找到键,则返回默认值。

private DataSet GetResourceDS()
{
 //Try to get the DataSet from the Cache first//Note that this one bombs at design time, (we have no HttpContext)//but this exception is caught in the custom control DataSet ds = (DataSet)HttpContext.Current.Cache[HttpContext.Current.
 Request.CurrentExecutionFilePath];
 if(ds == null)
 {
 //no DataSet in the Cache, get a new one and store it in the cache//get the text-id from the resource file for our web-page ds = new DataSet("resourceStrings");
 //build the name of the xml file from the name of the web// page we're sitting inString fileName = HttpContext.Current.
 Request.CurrentExecutionFilePath;
 fileName = fileName.Substring(0, fileName.LastIndexOf(".")) 
 + ".xml";
 try {
 //read ds from the xml file ds.ReadXml(HttpContext.Current.Server.MapPath(fileName));
 }
 catch (System.IO.FileNotFoundException)
 {
 //xml file not found, we will return the empty DataSet }
 //put in Cache with dependency to the xml file HttpContext.Current.Cache.Insert(HttpContext.Current.
 Request.CurrentExecutionFilePath,
 ds, new CacheDependency(HttpContext.Current.
 Server.MapPath(fileName)));
 }
 return ds;
}

iPhone 7 还没出来,我们已经在iPhone上获取细节 8,或者不管是想到下一步。 GetResourceDS 方法较长,但不太复杂。 首先它试图得到 数据集 从内置的.NET 中 高速缓存 对象,非常酷。 作为缓存键,我使用ASPX页的NAME。 如果 数据集 不在 高速缓存 我创建了一个新 数据集 从XML文件中读取内容,该文件应与ASPX页具有相同的名称,该页的名称与 TextControl 使用( 就像前面解释的)。

缓存 数据集 应在有人更新XML文件时过期,对? 因此,我添加了一个缓存依赖项,它指向XML文件。 所以现在,当文件被更新时, 高速缓存 对象检测并移除缓存 数据集 从记忆中。

ASP.NET 高速缓存 如果你决定将所有文本放入一个大的XML文件中,可能会更加有用。 每次呈现 TextControl 时,都不需要读取该XML文件,对吧?

使用代码

若要从 VisualStudio.NET, 使用 TextControl,你需要将包含控件的程序集添加到工具箱中。 加载 VisualStudio.NET 并创建一个新的ASP.NET 应用程序。 然后添加一个WebForm并将它的显示在设计视图中。 现在在包含所有内置服务器控件的工具箱中单击,然后从弹出菜单中选择"自定义工具箱。"。 现在选择名为".NET 框架组件"并使用"浏览的选项卡。"button find查找包含 TextControl的DLL。 示例项目在 MyControls.dll 程序集中具有 TextControl

VS.NET 将自动查找并激活 MyControls DLL中的TextControl inside。 可以将控件放在工具箱中不同的选项卡上,但我更喜欢将它的与其他服务器控件一起使用。

现在 TextControl 已经可以在网页上使用了。 创建一个名为 WebForm1.aspx的on,并在设计视图中从工具箱中拖放 TextControl。 在ASPX页上选择 TextControl,并查看属性对话框。 更改 密钥 属性( 例如,"key1"),并且可选择将某些文本放在 文本 属性。它应该与HTML视图中的类似:

<formid="Form1"method="post"runat="server"><cc1:TextControlid="TextControl1"runat="server"Key="key1"></cc1:TextControl></form>

注意 VS.NET 在项目视图中自动添加对MyControls的引用,并在该文件的顶部添加了用于注册自定义控件的代码:

<%@ Register TagPrefix="cc1" Namespace="MyControls" Assembly="MyControls" %>

现在唯一要做的是创建包含资源字符串的XML文件。 只需在新创建的ASPX页面中添加名为 WebForm1.xml的新XML文件。 XML文件非常简单,看起来像这样:

<?xmlversion="1.0"encoding="utf-8"?><resourceStrings><string><key>key1</key><value>sampleValue 1</value></string><string><key>key2</key><value>sampleValue 2</value></string></resourceStrings>

XML文件中的每个 string 节点组成了资源文件中的键/值对。

网页已经准备好测试了,并且应该显示一个带有文本"sampleValue 1"的纯网页。 如果将XML文件中的文本"sampleValue 1"改为其他内容并重新加载页面,则应立即显示新值。

iPhone 7 还没出来,我们已经在iPhone上获取细节 8,或者不管是想到下一步。 XMLResource 类也可以从代码 behind 中使用,以便在运行时获取和设置文本。 只需调用 public 方法 GetValueFromKey ( ) 从后面的代码中:

//set the text of the label in run-timeLabel1.Text = new MyControls.XMLResource().GetValueFromKey("key2",
 Label1.Text);

结束语

就像我之前写的,你可以用这段代码做很多事情,但是我希望这篇文章能让你into一些 controls,这非常有趣,非常有用。 我建议对按钮。超链接等进行类似的控制,网站的所有者可以更改所有提交按钮的文本。

我在生产站点中添加到这里控件的一些内容:

  • 验证XML资源文件( 从不信任客户以编写完美的XML的XML Schema )
  • 用于更新XML文本的密码 protected web窗体

相关文章