On the server side, SOAP 1.2 is on by default and can beturned off via configuration settings in machine.configor web.config: proto-proxy.SoapVersion = System.Web.Services.Protocols.Soap
Trang 1Figure 13-7
Asynchronous Web Service Methods
The previous section discussed how to call Web services asynchronously over HTTP using the client-sidecapabilities of the NET Framework This approach is an extremely useful way to make calls to a Webservice without locking up your application or spawning a bunch of background threads This sectiondiscusses asynchronous Web service methods that provide similar capabilities on the server side.When you invoke a normal, synchronous ASP.NET Web service method, the response for a synchronousWeb method is sent when you return from the method If it takes a relatively long period of time for arequest to complete, then the thread that is processing the request will be in use until the method call isdone Unfortunately, most lengthy calls are due to something like a long database query, or perhaps acall to another Web service For instance, if you make a Web service call across the Internet, the currentthread waits for the Web service call to complete The thread has to simply wait around doing nothinguntil it hears back from the Web service In this case, if you can free up the thread to do other work whilewaiting for the Web service, you can increase the throughput of your application
Waiting threads can impact the performance of a Web service because they don’t do
anything productive, such as servicing other requests To overcome this problem, you
need a way to be able to start a lengthy background process on a server, but return the
current thread to the ASP.NET process pool When the lengthy background process
completes, you would like to have a callback function invoked so that you can finish
processing the request and somehow signal the completion of the request to ASP.NET.
This is exactly what ASP.NET offers through asynchronous Web methods.
Trang 2How Asynchronous Web Methods Work
When you write a typical ASP.NET Web service using Web methods, Visual Studio simply compiles yourcode to create the assembly that will be called when requests for its Web methods are received Whenyour application is first launched, the ASMX handler reflects over your assembly to determine whichWeb methods are exposed For normal, synchronous requests, it is simply a matter of finding whichmethods have a WebMethod attribute associated with them, and setting up the logic to call the rightmethod based on the SOAPAction HTTP header
For asynchronous requests, during reflection the Web service handler looks for Web methods with a specific signature that differentiates the method as being asynchronous In particular, it looks for a pair
of methods that have the following rules:
❑ There is a BeginXXXand EndXXXWeb method where XXXis any string that represents the name
of the method you want to expose
❑ The BeginXXXfunction returns an IAsyncResultinterface and takes an AsyncCallback, and
an object as its last two parameters, respectively
❑ The EndXXXfunction takes as its only parameter an IAsyncResultinterface
❑ Both BeginXXXand EndXXXmethods must be flagged with the WebMethodattribute
If the Web service handler finds two methods that meet all these requirements, it will expose the method
XXXin its WSDL as if it were a normal Web method The method will accept the parameters definedbefore the AsyncCallback parameter in the signature for BeginXXXas input, and it will return what isreturned by the EndXXXfunction So if you have a Web method whose synchronous declaration lookslike the following:
[WebMethod]
public string EndSleepForSpecificDuration (IAsyncResult call) { }
The WSDL for both synchronous and asynchronous methods will be the same
After the Web service handler reflects on an assembly and detects an asynchronous Web method, it musthandle requests for that method differently than it handles synchronous requests Instead of calling asimple method, it calls the BeginXXXmethod It deserializes the incoming request into the parameters to
be passed to the function — as it does for synchronous requests — but it also passes the pointer to aninternal callback function as the AsyncCallbackparameter to the BeginXXXmethod
Trang 3Now that you have a general understanding of the asynchronous Web methods, Listing 13-20 shows anexample implementation.
Listing 13-20: Creating Asynchronous Web Service Methods
public delegate string SleepForSpecificDurationAsyncStub(int milliseconds);
public string SleepForSpecificDuration(int milliseconds)
public object PreviousState;
public SleepForSpecificDurationAsyncStub AsyncStub;
}
[WebMethod]
public IAsyncResult BeginSleepForSpecificDuration(int milliseconds,
AsyncCallback callback, object s){
SleepForSpecificDurationAsyncStub stub = new SleepForSpecificDurationAsyncStub(SleepForSpecificDuration);
WebServiceState state = new WebServiceState();
In Listing 13-20, after the Web service handler calls the BeginSleepForSpecificDuration()method,
it will return the thread to the process thread pool so it can handle any other requests that are received.The HttpContextfor the request will not be released yet The ASMX handler will wait until the callbackfunction that it passed to the BeginSleepForSpecificDuration()function is called for it to finishprocessing the request After the callback function is called, the ASMX handler will call the EndSleep
Trang 4ForSpecificDuration()function so that your Web method can complete any processing it needs
to perform, and the return data can be supplied that will be serialized into the SOAP response Onlywhen the response is sent after the EndSleepForSpecificDuration()function returns will the
HttpContextfor the request be released
Controlling XML Serialization Using IXmlSerializable
In NET V1.x, you had only limited control over how types were serialized using the XmlSerializer.You could attribute types at design time and you could also override those attributes with new values atruntime, but it was based on attributes and you never really had complete control over the serializationprocess Now with the release of NET 2.0, this is no longer true The IXmlSerializableinterface,which has been present in the NET Framework since version 1.x (but meant only for internal use), isnow available for general use, thereby providing you with the ability to have more control over the gen-erated schema and wire format
One change that has been introduced with the IXmlSerializableinterface is that the GetSchema()
method should no longer be used Instead you should use a new attribute named XmlSchemaProvider
to specify the static method that generates and inserts the schema in the XmlSchemaSetfor the Web service The ReadXml()method controls reading the serialized format and is handed an XmlReadertoread from the stream and populate the type The WriteXml()method controls writing the serialized format and is handed an XmlWriterto write out the data to the stream
Listing 13-21 shows the Customerclass implementing the IXmlSerializableinterface
Listing 13-21: Implementing IXmlSerializable Interface to Customize XML Serialization
private string _firstName;
private string _lastName;
private string _address;
public Customer(){
An example where you might need this type of control is when streaming large amounts of data To enable streaming of data, you have to turn off response buffer- ing and then chunk the data into discrete blocks of data demarcated with XML ele- ments IXmlSerializablelets you control the schema for this chunking format and control the reading and writing of this data to the stream with the ReadXml()and
WriteXml()methods.
Trang 6XmlNodeType type = reader.MoveToContent();
if ((type == XmlNodeType.Element) && (reader.LocalName == “customer”)){
_firstName = reader[“firstName”];
_lastName = reader[“lastName”];
_address = reader[“address”];
}}public override string ToString(){
return (string.Format(“Person [{0} {1}]”));
}}
In Listing 13-21, the Customerclass implements the IXmlSerializableinterface and the read/write isimplemented in ReadXml()and WriteXml()methods, respectively Note that the Customerclass isdecorated with an XmlSchemaProviderattribute which states that the schema for the serialized form of
Customerclass will be provided by the CreateCustomerSchema()method In the CreateCustomerSchema()method, you make up a schema each time and provide it back to the framework
With the Customerclass in place, you should be able to use that class from a Web service as shown inListing 13-22
Listing 13-22: Utilizing the Customer Class from a Web Service Method
}[WebMethod]
public Customer GetCustomer() {
Customer cust = new Customer(“Thiru”, “Thangarathinam”,
“900 N Rural Road, Chandler, AZ”);
return cust;
} }
In Listing 13-22, the GetCustomer()method simply creates an instance of the Customerobject andreturns it back to the caller If you test this Web service method using the default Web service test harness, you should see an output similar to Figure 13-8
Trang 7Figure 13-8
Using Schema Importer Extensions
In the NET Framework 2.0, there is a new namespace named System.Xml.Serialization.Advanced
that supports advanced XML serialization and schema generation scenarios Currently, this namespacecontains the following types:
❑ SchemaImporterExtension— Allows you to customize the code generated from a WSDLdocument
❑ SchemaImporterExtensionCollection— Represents the collection of
SchemaImporterExtensionobjectsSchema importation occurs whenever a Web service proxy is produced through a tool such as the AddWeb Reference dialog box found in Visual Studio, or by using the WSDL.exe Schema importation alsooccurs when using the XML Schema Definition Tool (Xsd.exe) to generate code from a specific XSDdocument
The SchemaImporterExtension Class
The SchemaImporterExtensionclass allows you to modify the code generated when using any of theautomated tools For example, you may have an existing class that processes book orders on a systemand you have an existing XSD document that supplies your orders Using the SchemaImporterExtensionclass, you can instruct the automated tools to generate code that uses your class To controlthe generation of the code, you must use the classes found in the System.CodeDomnamespace You need to go through the following steps to enable the proxy generation tools to use your extensions
1. Create an implementation of the SchemaImporterExtensionclass
2. Use the ImportSchemaTypemethod to write code for the code generator The method containsparameters that allow you to examine the intercepted XSD type and create CodeDOM objectsthat are used to generate the new CLR code
Trang 83. Optionally, use the ImportAnyElement()method to handle <xsd:any>elements found in theXSD document.
4. Optionally, use the ImportDefaultValue()method to examine default values found in theXSD document and return a different default value
5. Compile your extension into a library.
6. Sign the assembly
7. Install the assembly in the Global Assembly Cache (GAC)
8. Modify the machine.configfile to include the extension
Now that you understand the steps, the next section examines the creation of a schema importer sion class
exten-Creating a Schema Importer Extension Class
Creating a schema importer extension is pretty easy You simply derive from SchemaImporterExtension
and override the appropriate methods In most cases, you will override the ImportSchemaType()
method, which perform most of the heavy lifting Listing 13-23 shows an example in action
Listing 13-23: Custom Schema Importer Extension for the Customer Class
public sealed class CustomerSchemaImporterExtension : SchemaImporterExtension{
public override string ImportSchemaType(string name, string ns, XmlSchemaObject context, XmlSchemas schemas, XmlSchemaImporter importer, CodeCompileUnit compileUnit, CodeNamespace mainNamespace,
CodeGenerationOptions options, CodeDomProvider codeProvider){
if (name.Equals(“Customer”) && ns.Equals(“urn:wrox-com”)){
CodeTypeDeclaration customer = new CodeTypeDeclaration(“Customer”);
firstNameProperty.GetStatements.Add(new CodeMethodReturnStatement(
Trang 9CodeThisReferenceExpression(), “_firstName”)));
firstNameProperty.Name = “FirstName”;
firstNameProperty.SetStatements.Add(new CodeAssignStatement(
new CodeFieldReferenceExpression(new CodeThisReferenceExpression(),”_firstName”),new CodePropertySetValueReferenceExpression()));
firstNameProperty.Type = new CodeTypeReference(typeof(string));
lastNameProperty.GetStatements.Add(new CodeMethodReturnStatement(
new CodeFieldReferenceExpression(new CodeThisReferenceExpression(),”_lastName”)));
lastNameProperty.Name = “LastName”;
lastNameProperty.SetStatements.Add(new CodeAssignStatement(
new CodeFieldReferenceExpression(new CodeThisReferenceExpression(),”_lastName”),new CodePropertySetValueReferenceExpression()));
lastNameProperty.Type = new CodeTypeReference(typeof(string));
customer.Members.Add(lastNameProperty);
return “Customer”;
}return null;
}}
}
In this code example, you can see that the only type this extension can process is the element namedCustomer that resides in the namespace, “urn:wrox-com” This means that whenever this schemaimporter extension finds a type it is responsible for generating custom code, it does so via the CodeDOM provided by the NET Framework
Changes to the machine.config File
When a proxy generation tool is used to import a XML Schema, it uses the System.Xml.Serialization.XmlSchemaImporterclass internally to process the schema elements found in the XML Schema docu-ment When created, the XmlSchemaImporterclass loads any schema importer extensions defined in theunderlying configuration In this instance, by default, all the schema importer extensions are registered inthe machine.config file The following declaration shows how a schema importer extension is registered inmachine.config
Trang 10SchemaImporterExtensionsLib, Version=1.0.0.0, Culture=neutral,PublicKeyToken=2489eb64bbbf6741” />
be added to the generated class file
Miscellaneous Web Service Features in NET Framework 2.0
.NET Framework 2.0 provides a number of new features for the Web service developers Some, whichyou have already seen, are the support for WS-I Basic Profile, custom XML serialization through
IXmlSerializableinterface, and schema importer extensions In addition to these features, there are acouple of minor but important features that deserve a mention The next few sections give you a run-down of these features
Enabling Decompression in a Web Service Client
Now with NET 2.0, enabling decompression on the client side just requires one line of code All youneed to do is to set the EnableDecompressionproperty on an instance of a client proxy class to true,
dis-Type Sharing across Proxies
ASP.NET Web services now support proxy type sharing This feature allows you to share identical typesfrom different Web services within the client-side proxy class For example, you can take a type instancereturned from one Web service and pass it to another, and vice versa
In many real-world scenarios, you may want to factor your application’s functionality into individualservices that group methods that logically fit together This typically leads to sharing one or more data
Custom schema importer extension is useful when the client of a Web service has custom types that are much richer than those generated by wsdl.exe Prior to the NET Framework 2.0, this was possible only by modifying the generated proxy But the problem with this approach was that the changes were lost when the proxy was regenerated Schema Importer Extensions can now be developed and registered to map schema type to the custom type every time the proxy is generated.
Trang 11the new type sharing feature of NET 2.0 and provide the client with one Orderclass that is shared bythe two service proxies This feature is exposed on wsdl.exe with the /sharetypesswitch When usingthis switch you supply the URLs of two or more WSDL documents on the command line For example:
wsdl.exe /sharetypes http://localhost/OrderService.asmx?wsdl
http://localhost/OrderStatusService.asmx?wsdl
The code generation engine recognizes when types are equivalent based on their names and spaces, and by comparing their schema definition
name-Support for W3C SOAP 1.2
Version 2.0 of the NET Framework includes support for the W3C SOAP version 1.2 protocol in addition
to the existing SOAP version 1.1 protocol On the server side, SOAP 1.2 is on by default and can beturned off via configuration settings in machine.configor web.config:
proto-proxy.SoapVersion = System.Web.Services.Protocols.SoapProtocolVersion.Soap12;
When using wsdl.exe to consume a Web service that supports both SOAP 1.1 and 1.2, you can specify
/protocol: SOAP12on the command line to generate a proxy class that has its SoapVersionpropertyset to SoapProtocolVersion.Soap12 After you set this property, when you invoke the service youwill be using SOAP 1.2
Summar y
This chapter exposed you to the core building blocks of NET Web services The chapter began by ining the creation of a simple Web service and discussed the different attributes used with a Web service
exam-As you learned, Web services developed using the NET platform require little more than applying the
WebMethodattribute to each member you want to expose from the XML Web service type After youhave created any number of WebMethod-enabled members, you can interact with a Web service through
an intervening proxy You can either use the WSDL.exeutility or the Add Web Reference option to ate such a proxy, which can then be used by a Web service client You can use this proxy to syn-
gener-chronously and asyngener-chronously invoke a Web service method
With the extensibility features built into the NET Framework, you also have the option of leveragingsophisticated features such as SOAP headers, SOAP extensions, custom XML serialization, and schemaimporter extensions while building Web services Finally, the NET Framework 2.0 also offers new fea-tures such as enable decompression, type sharing across proxies, and support for SOAP 1.2
Trang 12ASP.NET 2.0 Configuration
When ASP.NET 1.0 was first released, it was lauded for the comprehensive feature set with which itshipped The long list of new features included object-oriented programming model, caching, richserver controls, declarative programming model, and so on; however ASP.NET 1.0 provided onlybasic support for configuration management, leaving Notepad pretty much the tool of choice forconfiguration management But now with the release of ASP.NET 2.0, things have dramaticallychanged with the suite of new configuration improvements that Web developers and administratorscan take advantage of As part of this, ASP.NET 2.0 ships with a new configuration management APIthat enables users to programmatically build programs or scripts that create, read, and update web.configand machine.configconfiguration files In addition, ASP.NET 2.0 also provides a newcomprehensive admin tool that plugs into the existing IIS Administration MMC, enabling an admin-istrator to graphically read or change any setting within our XML configuration files This chapterfocuses on the new configuration management API by demonstrating the classes, properties, andmethods of the new API and examples of how to use them from within your ASP.NET applications
By the end of this chapter, you will have a good understanding of the following:
❑ New configuration sections introduced with ASP.NET 2.0
❑ How to store and retrieve application settings from predefined ASP.NET sections
❑ How to utilize the web.config file settings to write database independent code
❑ How to encrypt and decrypt configuration settings
❑ How to enumerate configuration sections
❑ How to read contents of the configuration section using strongly typed API
❑ How to read contents of the configuration section using raw XML
❑ How to create a custom configuration section and persist its contents onto a web.configfile
❑ Built-in management tools supplied with ASP.NET 2.0 and Visual Studio 2005
Trang 13ASP.NET Configuration
A web.config file is an XML-based text file that can contain standard XML document elements, includingwell-formed tags, comments, text, cdata, and so on The file may be ANSI, UTF-8, or Unicode; the system automatically detects the encoding The root element of a web.config file is always a
<configuration>tag ASP.NET end-user settings are then encapsulated within the tag, as follows:
<configuration>
<!- Configuration settings would go here >
</configuration>
ASP.NET configuration settings are represented within configuration tag sections, also nested within a
<configuration>tag (and, optionally, within section group tags) For example, in the following sample,the tag <pages>is the configuration section that defines configuration settings for the ASP.NET pagecompiler Configuration section groups allow hierarchical grouping of sections for organizational pur-poses For example, all built-in ASP.NET sections belong in the <system.web>section group Sectiongroups may appear inside other section groups
In the following example, the configuration file contains configuration settings for the built-in <pages>
ASP.NET section This section is contained within the built in section group called <system.web>
an entire server, single or multiple applications, single or multiple directories, or even a single file The following rules apply to the inheritance of configuration settings
❑ Applications first inherit their settings from the machine.configfile of the server, then fromthe web.configfile of any parent applications, and finally from their own web.configfile
❑ The settings in each web.configfile override the settings from the machine.configand
web.configfiles before it
Note tag names in a configuration file are case-sensitive and must be typed exactly
as shown Various attributes and settings for ASP.NET are also case-sensitive and
will not be examined by the configuration runtime if the case does not match.
Trang 14❑ Inheritance follows the URL of the requested resource and not necessarily the physical structure
❑ The settings can be targeted to a specific directory, application, or file using the location setting
An application can override most of the default values stored in the machine.configfile by creatingone or more web.configfiles At a minimum, an application creates a web.configfile in its root folder.Although web.configallows you to override some of the default settings, you cannot override all settingsdefined in machine.config In particular, the information about the ASP.NET process model can bedefined only in a machine-wide manner using the machine.configfile
ASP.NET 1.x Way of Accessing Configuration Sections
In ASP.NET 1.x, there was only one view of configuration: runtime That view is implemented by anobject call System.Configuration.ConfigurationSettingsreturns configuration sections throughcalls to a static method named GetConfigthat takes in the sectionNameas an argument The
sectionNameyou passed into GetConfigchecks to see that the sectionNameitself is valid before anyconfig files are opened
Things have changed for the better in ASP.NET 2.0 ASP.NET 2.0 ships with a comprehensive ment API for reading, editing, and creating web.configfile settings The root class for programmaticaccess to the configuration infrastructure is Configuration Using the static methods of this class, you canaccess the machine.configfile and any web.configfile defined in the context of the application Thenext section starts by looking at the new configuration sections introduced with ASP.NET 2.0
manage-ASP.NET 2.0 Configuration Management
Now that you have a general understanding of the ASP.NET configuration architecture, the remainder ofthis chapter covers the configuration management functionalities of ASP.NET 2.0 The next section looks
at the new configuration sections introduced with ASP.NET 2.0
If the application contains child directories, it can define a web.configfile for each folder The scope of each configuration file is determined in a hierarchical, top- down manner The settings actually applied to an application and thus its Web pages are determined by the sum of the changes that the various web.configfiles
in the hierarchy of the application carry Along this path, any of those web.config
files can extend, restrict, and override any type of settings defined at an upper level, including the machine level, unless the setting is restricted to a certain level (such as process model) If no configuration file exists in an application folder, the settings valid at the upper level are applied.
Trang 15New Configuration Sections in ASP.NET 2.0
ASP.NET has added a number of new configuration sections to support the new features of ASP.NET 2.0.Table 14-1 lists the important ones that you are most likely going to have to work with
Table 14-1 New Configuration Sections
<anonymousIdentification> Configures the built-in mechanism for configuring the ID
assigned to the anonymous user
<connectionStrings> Declares the connection strings used by the application Each
connection string is identified by a unique name, which isused to reference the connection string from the code
<healthMonitoring> Allows you to configure the health monitoring API, which
provides a set of tools designed to trace the performance ofrunning applications
<membership> Allows you to configure providers that are registered to
store and retrieve membership data
<profile> Allows you to configure how a user profile is persisted
This section lets you define the schema of the class that resents the user profile
rep-<roleManager> Allows you to configure how role information about the
current user will be stored
<siteMap> Allows you to register the providers supported for storing
site layout By default, the site map information is stored in
a file called web.sitemap
<urlMappings> Allows you to map virtual URLs to physical URLs by
pro-viding a declarative way to transform a physical page intomultiple logical pages
<webParts> Allows you to configure the settings required for Web parts
Note that Table 14-1 simply highlights the important newly added configuration sections and it doesnot provide an exhaustive list of changes to the configuration schema In addition to the newly addedsections, the existing ASP.NET 1.x sections such as <pages>, <compilation>, <httpHandlers>,
<httpModules>, and <sessionState>have also undergone major revisions For more details, refer
to the NET Framework documentation
Classes Mapped to ASP.NET Configuration Sections
ASP.NET 2.0 also provides a number of public configuration classes (one per predefined section) thatexpose the contents of the configfile sections through properties and methods These classes are allderived from the System.Web.InternalSectionclass, which in turn is derived from the System.Configuration.ConfigurationSectionclass Table 14-2 provides a representation of these classesthat provide one-to-one mapping with the actual configuration sections in the web.configfile Notethat all of these classes are contained in the System.Web.Configurationnamespace
Trang 16Table 14-2 Configuration Section Classes in web.config File
AnonymousIdentificationSection Configures anonymous identification for users
that are not authenticated and represents the
<anonymousIdentification>section in the
web.configfile
AuthenticationSection Configures the authentication for a Web
applica-tion and provides a representaapplica-tion of the
<authentication>section in the web.config
file
AuthorizationSection Allows you to configure the authorization-related
settings for a Web application and provides amapping with the <authorization>section inthe web.configfile
CacheSection Allows you to configure the cache settings for the
entire Web application and provides a mappingwith the <cache>section in the web.configfile
CompilationSection Responsible for all the compilation settings used
by ASP.NET and provides a mapping with the
<compilation>section in the web.configfile
CustomErrorsSection Allows you to configure the ASP.NET custom
errors and provides a mapping with the
<customErrors>section in the web.configfile
GlobalizationSection Allows you to define the configuration settings
that are used to support the globalization tructure of Web applications This class provides amapping with the <globalization>section inthe web.configfile
infras-HealthMonitoringSection Allows you to configure ASP.NET profiles that
determine how health monitoring events are sent
to event providers This class provides a mappingwith the <healthmonitoring>section in the
web.configfile
HostingEnvironmentSection Responsible for hosting the server environment
that hosts ASP.NET applications This class provides a mapping with the <hostingEnvironment>section in the web.configfile
HttpCookiesSection Responsible for configuring cookie-related
proper-ties for the Web application and provides a ping with the <httpCookies>section in the
map-web.configfile
Trang 17Class Description
HttpModulesSection Responsible for configuring HTTP modules
within an application and provides a mappingwith the <httpModules>section in the web.configfile
HttpHandlersSection Responsible for mapping incoming URL to
handler classes that are derived from the
IHttpHandlerclass This class provides a ping with the <httpHandlers>section in theweb.config file
map-HttpRuntimeSection Allows you to configure the ASP.NET HTTP
runtime by providing a mapping with the
<httpRuntime>section in the web.configfile
IdentitySection Responsible for configuring the Windows identity
used to run a Web application This class provides
a mapping with the <identity>section in the
web.configfile
MachineKeySection Responsible for configuring the encryption key
used to encrypt secrets such as forms tion tickets and so on This class provides a map-ping with the <machineKey>section in theweb.config file
authentica-MembershipSection Responsible for configuring settings and
providers for the ASP.NET membership system.This class provides a mapping with the
<membership>section in the web.configfile
PagesSection Responsible for individual ASP.NET page
set-tings This class provides a mapping with the
<pages>section in the web.configfile
ProcessModelSection Responsible for configuring ASP.NET process
model settings This class provides a mappingwith the <processModel>section in the
web.configfile
ProfileSection Responsible for configuring settings and
providers for the ASP.NET role manager Thisclass provides a mapping with the <profile>
section in the web.configfile
SessionPageStateSection Responsible for configuring how session state can
be used to save page viewstate for small devices.This class provides a mapping with the
<sessionPageState>section in the web.configfile
Trang 18Class Description
SessionStateSection Responsible for configuring the HTTP session
state module, and this class provides a mappingwith the <sessionState>section in the
web.configfile
SiteMapSection Allows you to define the configuration settings
that are used to support the navigation ture for configuring, storing, and rendering sitenavigation This class provides a mapping withthe <siteMap>section in the web.configfile
infrastruc-TraceSection Responsible for configuring the ASP.NET trace
service This class provides a mapping with the
<trace>element in the web.configfile
TrustSection Allows you to configure the code access security
that is applied to an application This class vides a mapping with the <trust>section in the
pro-web.configfile
UrlMappingsSection Responsible for configuring URL mappings used
by the ASP.NET site navigation system This classprovides a mapping with the <urlMappings>
section in the web.configfile
WebPartsSection Responsible for configuring the settings used by
ASP.NET Web parts This class provides a ping with the <webParts>section in the
map-web.configfile
XhtmlConformanceSection Responsible for XHTML conformance settings of
ASP.NET controls This class provides a mappingwith the <xhtmlConformance>section in the
Trang 19Table 14-3 Properties of the WebConfigurationManager Class
AppSettings Allows you to retrieve the configuration settings stored
in the <appSettings>section of the web.configfile
ConnectionStrings Allows you to retrieve the configuration settings stored
in the <connectionStrings>section of the web.configfile
Table 14-4 lists the methods of the WebConfigurationManagerclass Note all these methods are static
Table 14-4 Methods of the WebConfigurationManager Class
GetWebApplicationSection Allows you to retrieve the specified configuration section
for the current Web application’s default configuration
OpenMachineConfiguration Allows you to get reference to the machine.configfile
in the form of a Configuration object
OpenMappedMachineConfiguration Allows you to get reference to the machine.configfile
in the form of a Configuration object using the specifiedfile mapping
OpenMappedWebConfiguration Allows you to get reference to the web.config file in the
form of a Configuration object using the specified filemapping
OpenWebConfiguration Allows you to get reference to the web.configfile in the
form of a Configuration object
The major functionality provided by the WebConfigurationManagerclass falls into three categories
❑ Easy and effective access to the appSettingsand connectionStringssections of the currentapplication’s web.configfile This is made possible through the introduction of new propertiessuch as AppSettingsand ConnectionStrings
Note that in NET 2.0, there are two main classes used for managing configuration
settings They are ConfigurationManagerand the WebConfigurationManager.
You should use the ConfigurationManagerif you want to update or add sections to
the app.configfile You should use the WebConfigurationManagerclass if you
want to update or add sections to the web.configfile.
Trang 20❑ Ability to access a specific configuration section from the current application’s web.configfileusing methods such as GetSection(), and GetWebApplicationSection().
❑ Ability to open a configuration file for updating configuration settings To this end, the
WebConfigurationManagerclass exposes methods such as OpenMachineConfiguration(),
OpenMappedMachineConfiguration(), OpenWebConfiguration(), and
OpenMappedWebConfiguration().This chapter discusses most of these properties and methods in detail in the next few sections
Note that for the examples shown in this chapter, the ASP.NET process account needs sufficient sions to be able to read and write into the configuration file For reasons of simplicity, Integrated Windows authentication for Web site is enabled through IIS and also turned on impersonation for the Web site using the following configuration settings under the <system.web>element in the
permis-web.configfile.
<identity impersonate=”true”/>
Because of these settings, the ASP.NET code will execute using the credentials of logged on user’s account instead of using the default ASP.NET (if you are running Windows XP) account Note that in production applications, it is recommended that you run your ASP.NET code using a domain account that has the minimum set of permissions on the server to execute code.
The next section discusses the use of WebConfigurationManagerclass in retrieving connection stringsfrom a web.configfile
Retrieving Configuration from Predefined Sections
To retrieve configuration settings from within an ASP.NET application, you use the
WebConfigurationManagerclass ASP.NET by default provides two predefined sections that can
be used to store configuration information for later retrieval These sections are as follows:
❑ <appSettings>— Primarily used for storing application settings such as path to an XML WebService and so on
❑ <connectionStrings>— As the name suggests, this section is used for storing connectionstrings information
In the next few sections, you see how to retrieve values stored in these sections
Using Application Settings
Configuration files are perfectly suited for storing custom application settings, such as database filepaths, or remote XML Web service URLs ASP.NET, by default, supports a section named
<appSettings>that can store these settings as name/value pairs The following example shows how
to retrieve the share location path from an <appSettings>section
Trang 21Listing 14-1: Using WebConfigurationManager Class to Retrieve Application Settings
<%@ Import Namespace=”System.Web.Configuration” %>
<script runat=server language=C# >
void Page_Load(object source, EventArgs e)
{
string shareLocationFromConfig =
WebConfigurationManager.AppSettings[“shareLocation”];
Response.Write(“Retrieved value : “ + shareLocationFromConfig);
//Code to connect to the share for file processing}
This code is simple and straightforward By making a call to the AppSettings property of the
WebConfigurationManagerclass, the code retrieves the value of the shareLocation key from the
web.configfile Place the following <appSettings>element inside the web.configfile
Using Connection Strings
Similar to general application settings, ASP.NET provides a configuration section specifically forstoring database connection strings, used by ADO.NET This configuration section is called
<connectionStrings>and it allows for secure storage and retrieval of database connection stringsthrough the Configuration API It is important to note that this is not under the <appSettings>section.The following example shows a <connectionStrings>configuration section for an application thatuses the AdventureWorks sample database
<configuration>
<connectionStrings>
<add name=”adventureWorks” connectionString=”server=localhost;integrated
Trang 22</connectionStrings>
-
<script runat=server language=C# >
void Page_Load(object source, EventArgs e){
string connString = WebConfigurationManager
The code retrieves the connection string from the web.config file using the ConnectionStrings property
of the WebConfigurationManagerclass; then, it opens up a connection to the AdventureWorksdatabase and executes a query against ContactTypetable It simply displays the output of the queryexecution in a GridViewcontrol The output produced by Listing 14-2 is shown in Figure 14-1
Trang 23Figure 14-1
Use of Expression Builders
Listing 14-2 utilized the WebConfigurationManagerto programmatically retrieve the connection string In addition to the programmatic approach, ASP.NET 2.0 also provides a new declarative approach to retrieve configuration settings using “$” expressions These expressions are new in ASP.NET 2.0, and they allow you to load connection strings, resources, and other items using a declarative approach For example, you can retrieve the same adventureWorks connection string using the syn- tax <%$ConnectionStrings:adventureWorks%> The following is the code that uses the adventureWorks connection string to retrieve contact type information through a SqlDataSourcecontrol and then displays the same through a GridView
Trang 24Writing Database Provider Independent Code Using web.config Settings
In addition to storing the actual connection string, you can also store the providerNamein the
web.configfile and use that as a foundation for creating database independent code For example,modify the connection string section of the web.configfile to look as follows:
Listing 14-3: Using providerName Setting to Create Provider Independent Data Access Code
<%@ Import Namespace=”System.Web.Configuration” %>
<%@ Import Namespace=”System.Data” %>
<%@ Import Namespace=”System.Data.Common” %>
<script runat=”server” language=”C#” >
void Page_Load(object source, EventArgs e){
string providerName = WebConfigurationManager
Trang 25<asp:GridView runat=”server” ID=”contactTypeView”></asp:GridView>
string providerName = WebConfigurationManager
ConnectionStrings[“adventureWorks”].ProviderName;
Use the provider name as an argument to the GetFactory()method of the DbProviderFactories
class
DbProviderFactory factory = DbProviderFactories.GetFactory(providerName);
After you have a DbProviderFactoryobject that is specific to the database you are connecting to, youcan use that object to create instances of the DbConnection, and DbDataAdapterobjects that are spe-cific to the database you are connecting to These objects are then utilized to open connection to thedatabase, execute the sql query against the contact type table in the AdventureWorks database, andfinally bind the output of the query execution to the database
.NET Framework 2.0 has new factory classes that make it easier to write data access code independent
of the database This is made possible by the introduction of database-independent factory class
namedDbProviderFactorythat allows you to create database specific DbConnectionand
DbDataAdapterobjects to work with specific databases The provider to use at runtime is obtained by calling the GetFactory()static method of the DbProviderFactories class passing in a string uniquely representing that provider This string is called Provider Invariant Name and is registered by each
provider in machine.config For example, for ODBC provider, it is System.Data.Odbc The
advantage of this methodology is that it gives you the option of seamlessly working with multiple
providers like OleDb and ODBC without having to lock onto a specific implementation like
SqlClient
Encrypting and Decrypting Configuration Sections
A powerful feature of the ASP.NET 2.0 Configuration API is its support for encryption Using thisencryption API, you can almost encrypt and decrypt almost all sections of your configuration files,including any user-defined sections There are some exceptions, such as the <httpRuntime>section,that needs to be accessed outside of ASP.NET by some IIS ISAPI code and therefore cannot be encrypted.The encryption API is extremely useful when you are dealing with sensitive data such as usernames andpasswords from within your Web applications Although ASP.NET configures IIS to prevent browseraccess to web.configfiles, it is nevertheless a good practice to never store such data as plain text in a
configuration file Once you encrypt specific sections using the configuration API, those encryptedvalues are virtually impossible to read using a text editor
Trang 26Calls to the configuration API can transparently work with encrypted sections because the API ically handles encryption and decryption To programmatically set a configuration section to be
automat-encrypted, you call the ConfigurationSection.SectionInformationproperty to get the
SectionInformationobject, and then call the ProtectSection()method on the
SectionInformationobject To decrypt the encrypted section, call the UnprotectSection()method
of the SectionInformationobject The following example shows how sections can be cally encrypted and decrypted, and how the configuration API automatically handles encrypted sec-tions Listing 14-4 uses two command buttons named btnEncryptand btnDecryptthat are used toencrypt or decrypt the connectionStringssection of the web.configfile, respectively
programmati-Listing 14-4: Encrypting and Decrypting a Configuration Section
<%@ Import Namespace=”System.Configuration” %>
<%@ Import Namespace=”System.Web.Configuration” %>
<script runat=”server” language=”C#” >
const string PROVIDER = “DataProtectionConfigurationProvider”;
protected void btnEncrypt_Click(object sender, EventArgs e){
try{Configuration config = WebConfigurationManager
OpenWebConfiguration(Request.ApplicationPath);
ConnectionStringsSection sect = config.ConnectionStrings;
sect.SectionInformation.ProtectSection(PROVIDER);
config.Save();
lblResult.Text = “Connection string section is now “ +
“encrypted in web.config file<br>”;
}catch (Exception ex){
lblResult.Text = “Exception: “ + ex.Message;
}//Note when you read the encrypted connection string, //it is automatically decrypted for you
lblResult.Text += “Connection String is:” +WebConfigurationManager.ConnectionStrings[“adventureWorks”]
ConnectionString;
}protected void btnDecrypt_Click(object sender, EventArgs e){
try{
By default, ASP.NET supports two protected configuration providers: RSA and DPAPI The DPAPI provider uses a machine-specific key, so you must physically encrypt the configuration settings on each machine The RSA provider, which is used by default, allows you the option to create an RSA key and install it on other machines, so that you can copy the same configuration file between these machines, thereby deploying the ASP.NET applications using XCOPY
Trang 27OpenWebConfiguration (Request.ApplicationPath);
ConnectionStringsSection sect = config.ConnectionStrings;
if (sect.SectionInformation.IsProtected){
sect.SectionInformation.UnprotectSection();
config.Save();
}lblResult.Text = “Connection string is now decrypted in “ +
“web.config file”;
}catch (Exception ex){
lblResult.Text = “Exception: “ + ex.Message;
} }
<asp:Button ID=”btnEncrypt” Runat=”server” Text=”Encrypt”
Width=”96px” Height=”35px” OnClick=”btnEncrypt_Click” />
<asp:Button ID=”btnDecrypt” Runat=”server” Text=”Decrypt”
Width=”102px” Height=”35px” OnClick=”btnDecrypt_Click” />
ConnectionStringsSection sect = config.ConnectionStrings;
After that, you invoke the ProtectSection()method of the SectionInformationobject passing inthe provider to use for encryption
sect.SectionInformation.ProtectSection(PROVIDER);
Finally, you call the Save()method of the Configuration object to persist the changes back to the
web.configfile
config.Save();
Trang 28Now the connection string is read back from the web.config file using the
In the Click event of the btnDecryptbutton, check to see if the section is encrypted by invoking the
IsProtectedproperty of the SectionInformationobject If it is encrypted, you simply call the
UnprotectSection()method to decrypt the section After it is decrypted, you simply persist thechanges back to the web.configfile through a call to the Save()method
if (sect.SectionInformation.IsProtected){
Trang 29Enumerating Configuration Sections
So far, you have seen how to store and retrieve connection strings as well as the steps involved inencrypting or decrypting connection strings In this section, you learn how to enumerate the contents of
a specific section in the web.configfile For the purposes of this example, you learn how to enumeratethe built-in sections by looping through the ConfigurationSectionCollectionobject This type ofenumeration is useful if you are building a user interface editor that will enable the users to edit the con-figuration settings
Listing 14-5: Enumerating All the Configuration Sections
<%@ Import Namespace=”System.Configuration” %>
<%@ Import Namespace=”System.Web.Configuration” %>
<script runat=server language=C# >
public void Page_Load(object source, EventArgs e)
{
string path = Request.CurrentExecutionFilePath;
path = path.Substring(0, path.LastIndexOf(‘/’));
Configuration config = WebConfigurationManager.OpenWebConfiguration(path); //Enumerate the configuration sections and display them
Response.Write(“<b>Configuration sections in the web.config:</b><br>”); foreach (ConfigurationSection section in config.Sections)
{Response.Write(“Name: “ + section.SectionInformation.Name + “<br>”);
Response.Write(“IsProtected:” + section.SectionInformation.IsProtected.ToString() + “<br><br>”);
}}
As similar to the previous examples, this example also utilizes the OpenWebConfiguration()method
of the WebConfigurationManagerclass to get reference to the configuration section in the web.config
file After you have done that, you can easily get reference to all the sections through the Sections erty of the Configuration object Inside each loop, you loop through all the sections and write their name
prop-as well prop-as their encryption status onto a browser one at a time Figure 14-2 shows the output of the page
Trang 30Figure 14-2
Reading Configuration Sections
The Configuration object contains a hierarchy of configuration sections and configuration sectiongroups, corresponding to the hierarchy of sections and groups in the configuration file To obtain theroot of this hierarchy, you can call the Configuration.RootSectionGroupproperty From this object,you can navigate the Sections collection, which contains all sections that are direct children of the sectiongroup, or the SectionGroupscollection, which contain all section groups that are direct children.You can also access a section directly by calling the Configuration.GetSection (), passing in thepath to the section required Configuration sections are represented by the ConfigurationSection
type meaning that they all inherit from the ConfigurationSectionclass After you have reference tothe section, there are two ways you can process the contents of the section
❑ Because each section returned is typically a strongly typed object (that inherits from the
ConfigurationSectionclass), you can simply call the properties of the object to access thevalues
❑ You can also access the contents of the section as a raw XML The ability to process the contents
of the section as a raw XML is particularly useful for legacy ASP.NET 1.x sections that do notsupport a strongly typed management API Note that the raw XML returned is for the currentlevel only, and does not automatically reflect inherited settings
For the purposes of this chapter, you learn how to retrieve the settings from the <customErrors>ment using the above approaches