技术开发 频道

ASP.NET4与VS 2010Web开发之窗体改进

  【IT168技术】自从ASP.NET 1.0发布以来,Web窗体中增加了许多核心特征。在最新的ASP.NET 4中,Web窗体方面的许多功能都得到了增强,具体包括以下内容:

  能够设置元标记。

  更好地控制视图状态。

  更方便地使用浏览器的功能。

  支持在Web窗体开发中使用ASP.NET路由机制。

  更好地控制生成的ID。

  能够把在数据控件中选定的行永久保存起来。

  更好地控制由FormView和ListView控件生成的HTML。

  针对数据源控件提供过滤支持。

  在本篇中,我们将讨论ASP.NET 4在元标记设置、视图状态控制及浏览器能力控制等方面的新的或增强功能。

  一、使用Page.MetaKeywords和Page.MetaDescription属性设置元标记

  针对Web窗体的Page类,ASP.NET 4新添了两个属性,即MetaKeywords和MetaDescription。这两个属性代表了你的页面中相应的元标记,如下面的例子所示:

<head id="Head1" runat="server">
  
<title>Untitled Page</title>
  
<meta name="keywords" content="These, are, my, keywords" />
  
<meta name="description" content="This is the description of my page" />
</head>

    这两个属性与网页的Title属性以相同的方式工作。它们都遵循下面这些规则:

  1. 如果在头元素中不存在匹配属性名称的元标记(即,name="keywords"代表了Page.MetaKeywords,而name="description"代表了Page.MetaDescription,意思是这些属性都还没有设置),那么,这些元标记在呈现页面时将被添加到其中。

  2. 如果已经有使用这些名称的元标记,那么,这些属性会被作为针对已存在的元标记内容的get和set方法使用。

  您可以在运行时设置这些属性,它可以使你从数据库或其他来源取得相应的内容,并允许您动态地设置标记来描述一个特定的页面中所代表的内容。

  您也可以在Web窗体页面顶部标记的@ Page指令中设置Keywords和Description属性,如下面的例子所示:

<%@ Page Language="C#" AutoEventWireup="true"
  CodeFile
="Default.aspx.cs"
  Inherits
="_Default"
  Keywords
="These, are, my, keywords"
  Description
="This is a description" %>

  这将重写已经在页面中存在的元标记内容(如果存在的话)。

  Description元标记内容用于改善Google搜索列表预览。Google和Windows Live Search都没有使用这些关键字内容来描述一定的内容,但其他搜索引擎却有可能。有关详情,请参考“元关键字搜索引擎指南”网站。

  这些新属性都是一些简单的功能,但它们却避免了你手动添加这些内容或通过编写您自己的代码来创建元标记的麻烦。

  二、针对个体控件支持视图状态

  默认情况下,页面是启用视图状态的,这将导致页面上每个控件潜在地存储视图状态—即使应用程序中并不需要。视图状态数据包含在页面的HTML标记中,从而增加了把页面发送到客户端和回寄的时间。存储不需要的过多的视图状态有可能造成重大的系统性能退化。在ASP.NET早期版本中,为了减少页面大小,开发者可以针对单个控件禁用视图状态,但不得不针对个别的控件显式地这样操作。在ASP.NET 4中,Web服务器控件包括了一个ViewStateMode属性,默认情况下禁用视图状态,然后只为在页面需要视图状态的控件才启用它。

  ViewStateMode属性将使用具有三个值的枚举:Enabled,Disabled和Inherit。Enabled对于指定的控件或设置为Inherit的子控件或没有作任何设置的控件启用视图状态。Disabled将禁用视图状态,而Inherit指定控件将使用从父控件中的ViewStateMode设置。

  下面的简单示例显示了ViewStateMode属性如何工作的。注意到,下列页面中的控件标记中包括了一个ViewStateMode值:

<form id="form1" runat="server">
  
<script runat="server">
      protected override void OnLoad(EventArgs e) {
      
if (!IsPostBack) {
        label1.Text
= label2.Text = "[DynamicValue]";
      }
      base.OnLoad(e);
    }
  
</script>
  
<asp:PlaceHolder ID="PlaceHolder1" runat="server" ViewStateMode="Disabled">
      Disabled:
<asp:Label ID="label1" runat="server" Text="[DeclaredValue]" /><br />
    
<asp:PlaceHolder ID="PlaceHolder2" runat="server" ViewStateMode="Enabled">
        Enabled:
<asp:Label ID="label2" runat="server" Text="[DeclaredValue]" />
    
</asp:PlaceHolder>
  
</asp:PlaceHolder>
  
<hr />
  
<asp:button ID="Button1" runat="server" Text="Postback" />
  
<%-- Further markup here --%>

  正如你看到的,代码中禁用了PlaceHolder1控件的视图状态。子控件Label1继承此属性值(Inherit是针对控件的ViewStateMode提供的默认值。),因此没有保存任何视图状态。在PlaceHolder2控件中,ViewStateMode设置为Enabled,因此Label2控件继承了此属性并保存视图状态。当页面第一次加载时,两个Label控件的Text属性都被设置为字符串“[DynamicValue]”。

  这些设置效果是,当页面首次加载时,将在浏览器端显示以下输出:

Disabled: [DynamicValue]

  Enabled: [DynamicValue]

   但是在发生页面回寄后,显示如下的输出内容:

Disabled: [DeclaredValue]

Enabled: [DynamicValue]

    正如你可能料想到的,Label1(其ViewStateMode值设置为Disabled)并没有保存在代码中设置的值。然而,Label2(其ViewStateMode值设置为Enabled)保留了其状态。

  您还可以在@ Page指令中设置ViewStateMode,如下面的例子所示:

<%@ Page Language="C#" AutoEventWireup="true"
  CodeBehind
="Default.aspx.cs"
  Inherits
="WebApplication1._Default"
  ViewStateMode
="Disabled" %>

     Page类仅仅是另一个控件而已,它承担了所有页面中其他控件的父控件行为。对于Page对象来说,ViewStateMode的默认值为Enabled。由于控件默认为Inherit类型,控件将继承Enabled属性值,除非您在页面或控件级上设置ViewStateMode。

  ViewStateMode属性的值决定了仅当EnableViewState属性设置为true时是否维持视图状态。如果EnableViewState属性设置为false,视图状态将不能保持,即使ViewStateMode设置为Enabled。

  此特征的一个不错的应用是在母版页面中使用ContentPlaceHolder控件。此时,您可以把母版页面的ViewStateMode设置为Disabled,然后针对个别的包含需要视图状态的控件中的ContentPlaceHolder控件启用这一功能。

  三、改变浏览器能力

  通过使用一种称为浏览器能力的特征,ASP.NET能够确定用户正在使用的浏览你的网站的浏览器的功能。浏览器能力通过使用HttpBrowserCapabilities对象(由Request.Browser属性提供)加以描述。例如,您可以使用HttpBrowserCapabilities对象来确定当前浏览器的类型和版本是否支持特定版本的JavaScript。或者,您可以使用HttpBrowserCapabilities对象来确定是否请求是从一台移动设备发出的。

  HttpBrowserCapabilities对象通过一组浏览器定义文件驱动。这些文件包含了一些特定浏览器的功能信息。在ASP.NET 4中,这些浏览器定义文件都得到了更新以便包含最新出现的浏览器及设备(例如Google Chrome,Research in Motion的BlackBerry智能手机和苹果的iPhone)的信息。

  下面的列表显示了新的浏览器定义文件:

    blackberry.browser

   chrome.browser

   Default.browser

    firefox.browser

   gateway.browser

   generic.browser

   ie.browser

   iemobile.browser

    iphone.browser

    opera.browser

    safari.browser

  四、使用浏览器能力提供程序

  在ASP.NET版本3.5 Service Pack 1中,您可以使用下列方式来定义浏览器能力:

   在机器级上,您可以在以下文件夹下创建或更新一个.browser XML文件:

  \Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG\Browsers

  后在您定义浏览器能力后,您可以从Visual Studio命令提示符运行以下命令来重建浏览器能力程序集并把它添加到GAC中:

  aspnet_regbrowsers.exe -I c

  对于个体应用程序,您可以在应用程序的App_Browsers文件夹下创建一个.browser文件。

  这些办法需要您更改XML文件,而对于机器级别的更改,在您运行aspnet_regbrowsers.exe进程后,您必须重新启动应用程序。

  ASP.NET 4中包括了一个称为浏览器能力提供程序的新特征。顾名思义,这可以让您构造一个提供程序,它能让您使用自己的代码来决定浏览器能力。

  在实践中,开发人员往往不去定义定制的浏览器能力。浏览器文件很难更新,更新它们的进程也相当复杂,而且.browser文件相应的XML语法也可能在使用和定义时比较复杂。使这一过程容易得多的一种方案是提供一种共同的浏览器定义语法,或者包含最新浏览器定义的数据库,甚至是一个针对这样的一个数据库的Web服务。新的浏览器能力提供程序使得这些支持都有可能实现,适合第三方开发商开发。

  使用新的ASP.NET 4浏览器能力提供程序的功能主要有两种方法:扩展ASP.NET浏览器能力定义功能;或完全取代它。下面首先描述如何取代浏览器能力,然后讨论如何扩展它。

  (一)取代ASP.NET浏览器能力功能

  要完全替换ASP.NET浏览器能力定义功能,请遵循下列步骤:

  1. 创建一个派生自HttpCapabilitiesProvider类的提供程序,并重载GetBrowserCapabilities方法,如以下示例所示:

public class CustomProvider : HttpCapabilitiesProvider
{
  
public override HttpBrowserCapabilities
   GetBrowserCapabilities(HttpRequest request)
   {
     HttpBrowserCapabilities browserCaps
= new HttpBrowserCapabilities();
     Hashtable values
= new Hashtable(180, StringComparer.OrdinalIgnoreCase);
     values[
String.Empty] = request.UserAgent;
     values[
"browser"] = "MyCustomBrowser";
     browserCaps.Capabilities
= values;
     return browserCaps;
   }
}

  在此示例代码中,创建了一个新的HttpBrowserCapabilities对象,仅指定了命名为browser的能力并设置此能力为MyCustomBrowser。

  2. 在应用程序中注册提供程序。

  为了在一个应用程序中使用一个提供程序,您必须把provider属性添加到Web.config或Machine.config文件中的browserCaps节。(您也可以在一个应用程序的特定目录的一个位置元素中定义provider属性,例如在一个针对特定的移动设备的文件夹下。)下面的示例显示了如何在一个配置文件中设置provider属性:

<system.web>
<browserCaps provider="ClassLibrary2.CustomProvider, ClassLibrary2,
  Version=1.0.0.0, Culture=neutral" />
</system.web>

   另一个注册新的浏览器能力定义的途径是使用代码,如以下示例所示:

void Application_Start(object sender, EventArgs e)

  {

  HttpCapabilitiesBase.BrowserCapabilitiesProvider
=

  
new ClassLibrary2.CustomProvider();

  
// ...

  }

  此代码必须运行在Global.asax文件的Application_Start事件中。任何对BrowserCapabilitiesProvider类的改变必须在应用程序执行任何代码之前发生,以确保缓存处于针对解析的HttpCapabilitiesBase对象的一个有效的状态。

  (二)缓存HttpBrowserCapabilities对象

  前面的例子中有一个问题,就是每当调用这个自定义提供程序以获得HttpBrowserCapabilities对象时该代码都将运行。因此,这在每个请求期间都可能发生多次。在这个例子中,自定义提供程序并没有实现什么功能。但是,如果在您的自定义提供程序代码中要执行重要的工作以便获得HttpBrowserCapabilities对象,那么,这有可能会导致巨大的开销。为了防止这种情况发生,你可以缓存HttpBrowserCapabilities对象。为此,请按照下列步骤操作:

  1. 从HttpCapabilitiesProvider类创建一个派生类,如下面的例子所示:

public class CustomProvider : HttpCapabilitiesProvider
{
  
public override HttpBrowserCapabilities
    GetBrowserCapabilities(HttpRequest request)
  {
    
string cacheKey = BuildCacheKey();
    
int cacheTime = GetCacheTime();
    HttpBrowserCapabilities browserCaps
=
    HttpContext.Current.Cache[cacheKey]
as
    HttpBrowserCapabilities;
    
if (browserCaps == null)
    {
      HttpBrowserCapabilities browserCaps
= new
      HttpBrowserCapabilities();
      Hashtable values
= new Hashtable(180,
                StringComparer.OrdinalIgnoreCase);
values[
String.Empty] = request.UserAgent;
      values[
"browser"] = "MyCustomBrowser";
      browserCaps.Capabilities
= values;
      HttpContext.Current.Cache.Insert(cacheKey,
      browserCaps,
null, DateTime.MaxValue,
        TimeSpan.FromSeconds(cacheTime));
    }
    return browserCaps;
  }
}

  在这个例子中,通过调用一个自定义的BuildCacheKey方法生成了一个缓存键,它通过调用一个自定义GetCacheTime方法来取得缓存需要的时间长度。然后,该代码把解析后的HttpBrowserCapabilities对象添加到缓存中。然后,可以从缓存中检索该对象,并重用于需要你的自定义提供程序的后续的请求中。

  2. 如前面所描述的那样,在应用程序中注册这个提供程序。

  (三)扩展ASP.NET浏览器能力功能

  上一节介绍如何在ASP.NET 4中创建一个新的HttpBrowserCapabilities对象。您还可以通过添加新的浏览器能力定义来扩展那些已经在ASP.NET中存在的ASP.NET浏览器能力的功能。你不需要使用XML浏览器定义来实现这种功能。下面的过程说明了实现方法。

  1. 创建一个派生自HttpCapabilitiesEvaluator的类,并重载其中的GetBrowserCapabilities方法,如下面的例子所示:

    此代码首先使用ASP.NET浏览器能力功能来尝试识别出浏览器。但是,如果在请求中定义的信息没有标识出浏览器(即,如果HttpBrowserCapabilities对象的Browser属性是字符串“Unknown”),那么,代码将调用自定义的提供程序(MyBrowserCapabilitiesEvaluator)来识别浏览器。

  2. 如前面的例子中说明的那样,在应用程序中注册这个提供程序。

public class CustomProvider : HttpCapabilitiesEvaluator

  {

  
public override HttpBrowserCapabilities

  GetBrowserCapabilities(HttpRequest request)

  {

  HttpBrowserCapabilities browserCaps
=

  base.GetHttpBrowserCapabilities(request);

  
if (browserCaps.Browser == "Unknown")

  {

  browserCaps
= MyBrowserCapabilitiesEvaulator(request);

  }

  return browserCaps;

  }

  }

   (四)扩展浏览器能力功能—在现有能力定义中添加新能力

  除了创建一个自定义浏览器定义提供程序以便动态地创建新的浏览器定义外,你可以使用附加的能力来扩展现有的浏览器定义。这可让您使用很接近于你想要的但仅缺乏少数能力的定义。为了做到这一点,请使用下面的步骤。

  1. 创建一个由HttpCapabilitiesEvaluator类派生的类,并重载它的GetBrowserCapabilities方法,如下面的例子所示:

public class CustomProvider : HttpCapabilitiesEvaluator

  {

  
public override HttpBrowserCapabilities

  GetBrowserCapabilities(HttpRequest request)

  {

  HttpBrowserCapabilities browserCaps
=

  base.GetHttpBrowserCapabilities(request);

  
if (browserCaps.Browser == "Unknown")

  {

  browserCaps
= MyBrowserCapabilitiesEvaulator(request);

  }

  return browserCaps;

  }

  }

         该示例代码扩展了现有的ASP.NET HttpCapabilitiesEvaluator类,并使用以下代码来获取匹配当前请求定义的HttpBrowserCapabilities对象:

HttpBrowserCapabilities browserCaps =

  base.GetHttpBrowserCapabilities(request);

然后,该代码可以添加或修改此浏览器的某种能力。有两种方法可以用来指定一个新的浏览器能力:

  把一个键/值对添加到HttpCapabilitiesBase对象的Capabilities属性暴露的IDictionary对象。在前面的例子中,代码添加了一个称为“MultiTouch”的能力,并设置其值为true。

  设置HttpCapabilitiesBase对象的现有属性。在前面的例子中,代码把Frames属性设置为true。这个属性仅仅是一个充当Capabilities属性暴露的IDictionary对象的访问器。

  注:此模式适用于HttpBrowserCapabilities的任何属性,包括控件适配器。

  2. 如前面的例子中说明的那样,在应用程序中注册这个提供程序。

 ASP.NET4与VS2010 Web开发页面服务改进

ASP.NET4与VS2010Web开发核心服务改进

 

0
相关文章