਍ഀ ਍ഀ ਍ഀ ਍ഀ ਍ഀ ਍ഀ ਍ഀ ਍ഀ ASP.NET Universal Providers Prerelease Notes਍ഀ ਍ഀ ਍ഀ ਍ഀ ਍ഀ ਍ഀ ਍ഀ ਍ഀ ਍ഀ ਍ഀ ਍ഀ ਍ഀ ਍ഀ
਍ഀ ਍ഀ

ASP.NET Universal਍ഀ Providers

਍ഀ ਍ഀ

Last਍ഀ update: 11 January 2012

਍ഀ ਍ഀ

The SqlMembershipProvider,਍ഀ SqlRoleProvider,਍ഀ SqlProfileProvider਍ഀ classes that shipped in ASP.NET through version 4 support only Microsoft SQL਍ഀ Server and Microsoft SQL Server Express. They do not support newer offerings਍ഀ such as Microsoft਍ഀ SQL Azure and Microsoft਍ഀ SQL Server Compact.

਍ഀ ਍ഀ

ASP.NET਍ഀ Universal Providers have been created in order to extend support to all਍ഀ editions of SQL Server 2005 and later and to SQL Azure. If you use these਍ഀ providers to develop your application, the application will be ready for cloud਍ഀ environments like Azure.

਍ഀ ਍ഀ

Other than਍ഀ supporting additional storage options, the providers work like the existing਍ഀ SQL-based providers. Except as noted below, using ASP.NET Universal Providers਍ഀ requires no change in any of your applications.

਍ഀ ਍ഀ

·        ਍ഀ Installing and Configuring਍ഀ ASP.NET Universal Providers

਍ഀ ਍ഀ

·        ਍ഀ Selecting਍ഀ a Data Store

਍ഀ ਍ഀ

·        ਍ഀ Storing Data in Session State਍ഀ using ASP.NET Universal Providers

਍ഀ ਍ഀ

·        ਍ഀ Known Issues

਍ഀ ਍ഀ

·        ਍ഀ Additional਍ഀ Resources

਍ഀ ਍ഀ

·        ਍ഀ Disclaimer

਍ഀ ਍ഀ

Installing and Configuring ASP.NET Universal Providers

਍ഀ ਍ഀ

To install਍ഀ ASP.NET Universal Providers, you use a NuGet package, which installs all਍ഀ required files (including this documentation). The NuGet package automatically਍ഀ enables the new providers when it is installed. By default, the NuGet package਍ഀ configures provider to use SQL Server Express. To use SQL Server Compact or SQL਍ഀ Azure, you must change the connection string for the provider, as explained later in this document.

਍ഀ ਍ഀ

To enable਍ഀ the providers, the NuGet package adds configuration entries in the web.config file. The਍ഀ configuration for these providers is the same as the existing SqlMembershipProvider class, but the type parameter is set਍ഀ to the type of the new providers, as shown in the following table:

਍ഀ ਍ഀ ਍ഀ ਍ഀ ਍ഀ ਍ഀ ਍ഀ ਍ഀ ਍ഀ ਍ഀ ਍ഀ ਍ഀ ਍ഀ ਍ഀ ਍ഀ ਍ഀ ਍ഀ ਍ഀ ਍ഀ ਍ഀ ਍ഀ ਍ഀ ਍ഀ ਍ഀ
਍ഀ

SQL Provider Types

਍ഀ
਍ഀ

Equivalent Type for Universal Providers

਍ഀ
਍ഀ

System.Web.Security.SqlMembershipProvider

਍ഀ
਍ഀ

System.Web.Providers.DefaultMembershipProvider

਍ഀ
਍ഀ

System.Web.Profile.SqlProfileProvider

਍ഀ
਍ഀ

System.Web.Providers.DefaultProfileProvider

਍ഀ
਍ഀ

System.Web.Security.SqlRoleProvider

਍ഀ
਍ഀ

System.Web.Providers.DefaultRoleProvider

਍ഀ
਍ഀ

(Built into default provider)

਍ഀ
਍ഀ

System.Web.Providers.DefaultSessionStateProvider

਍ഀ
਍ഀ ਍ഀ

In the web.config file, the਍ഀ configuration looks like the following example (the connection string has been਍ഀ wrapped for readability). The differences from the configuration for older਍ഀ SQL-based providers are highlighted. Notice that a section has been added to਍ഀ define custom session-state handling using a custom provider, as described਍ഀ later under Storing Data in਍ഀ Session State using ASP.NET Universal Providers.

਍ഀ ਍ഀ
 
<configuration>
<connectionStrings>
  <add name="DefaultConnection"
    connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=aspnetdb;Integrated Security=True"
਍ഀ
    providerName="System.Data.SqlClient" />
  </connectionStrings>
 
  <system.web>
    <membership defaultProvider="DefaultMembershipProvider">
      <providers>
        <clear />
        <add name="DefaultMembershipProvider"
             type="System.Web.Providers.DefaultMembershipProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" 
             connectionStringName="DefaultConnection"
             enablePasswordRetrieval="false"
             enablePasswordReset="true"
             requiresQuestionAndAnswer="false"
             requiresUniqueEmail="false"
             maxInvalidPasswordAttempts="5"
             minRequiredPasswordLength="6"
             minRequiredNonalphanumericCharacters="0"
             passwordAttemptWindow="10"
             applicationName="/" />
      </providers>
    </membership>
 
    <profile defaultProvider="DefaultProfileProvider">
      <providers>
        <clear />
        <add name="DefaultProfileProvider"
             type="System.Web.Providers.DefaultProfileProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" 
             connectionStringName="DefaultConnection"
             applicationName="/" />
      </providers>
    </profile>
 
    <roleManager defaultProvider="DefaultRoleProvider" enabled="false">
      <providers>
        <clear />
        <add name="DefaultRoleProvider"
             type="System.Web.Providers.DefaultRoleProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
             connectionStringName="DefaultConnection"
             applicationName="/" />
      </providers>
    </roleManager>
 
    <sessionState mode="Custom" customProvider="DefaultSessionProvider">
      <providers>
        <add name="DefaultSessionProvider"
           type="System.Web.Providers.DefaultSessionStateProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
           connectionStringName="DefaultConnection"
           applicationName="/" />
      </providers>
    </sessionState>
  </system.web>
਍ഀ ਍ഀ

Selecting਍ഀ a Data Store

਍ഀ ਍ഀ

By default, the਍ഀ NuGet package sets the connection string to use a SQL Server Express database਍ഀ (wrapped here for readability):

਍ഀ ਍ഀ
"Data Source=.\SQLEXPRESS;Initial Catalog=aspnetdb;Integrated Security=True" providerName="System.Data.SqlClient" 
਍ഀ ਍ഀ

If you want to use਍ഀ SQL Server Compact, change the connection string as shown in the following਍ഀ example:/o:p>

਍ഀ ਍ഀ
 
<connectionStrings>
  <add name="DefaultConnection" connectionString="Data Source=|DataDirectory|\aspnet.sdf" 
      providerName="System.Data.SqlServerCe.4.0"/>
</connectionStrings>
਍ഀ ਍ഀ

If you want to use਍ഀ SQL Azure, change the connection string as shown in the following example਍ഀ (wrapped for readability):

਍ഀ ਍ഀ
<connectionStrings>
  <add name="DefaultConnection" 
     connectionString="data source=myDNSName;
         User ID=myUserName;Password=myPassword;
         Encrypt=true;Trusted_Connection=false=false"
਍ഀ
     providerName="System.Data.SqlClient"/>
<connectionStrings>
਍ഀ ਍ഀ

Storing Data in Session State using ASP.NET Universal਍ഀ Providers

਍ഀ ਍ഀ

By default, ASP.NET਍ഀ stores session data using an in-process (in-memory) session provider. This਍ഀ provider allows you to put any object in session state, because session state਍ഀ simply holds a reference to the object, not the object itself.

਍ഀ ਍ഀ

However, cloud਍ഀ environments might run your application on multiple computers. Therefore, for਍ഀ cloud-based applications, the application must store session state in some form਍ഀ of storage (like a database) that be accessed by more than one machine. This਍ഀ puts some restrictions on what data you store in session state — essentially,਍ഀ the data must be serializable.

਍ഀ ਍ഀ

When you install਍ഀ ASP.NET Universal Providers, the installation process configures session state਍ഀ to use the System.Web.Providers.DefaultSessionStateProvider type, as shown in਍ഀ the web.config਍ഀ file example earlier. This type stores session state in a database.

਍ഀ ਍ഀ

Session data must਍ഀ be serializable. If you attempt to store something in session state that is not਍ഀ serializable, you will receive the following error:

਍ഀ ਍ഀ
਍ഀ ਍ഀ

Unable to serialize the session state. In਍ഀ 'StateServer' and 'SQLServer'਍ഀ mode, ASP.NET will serialize the session state objects, and as a result਍ഀ non-serializable objects or MarshalByRef objects are਍ഀ not permitted. the same restriction applies if similar਍ഀ serialization is done by the custom session state store in 'Custom' mode.

਍ഀ ਍ഀ
਍ഀ ਍ഀ

There are two ways਍ഀ to resolve this issue: by marking the type as serializable or by using a਍ഀ surrogate serializer.

਍ഀ ਍ഀ

Marking Types as Serializable

਍ഀ ਍ഀ

If you have access਍ഀ to the source code for the type that is being stored in session state, you can਍ഀ mark the type using the Serializable attribute, as in the following਍ഀ example. If the type contains additional classes, all the contained classes਍ഀ must be serializable as well.

਍ഀ ਍ഀ
[Serializable]
public class Address { }
 
[Serializable]
public class Person { 
     public Address Work;
     public Address Home; 
}
਍ഀ ਍ഀ

Using a Surrogate Serializer਍ഀ in .NET Framework 4.5

਍ഀ ਍ഀ

If it's not਍ഀ practical to mark the type as serializable in source code, and if you are using਍ഀ .NET Framework 4.5, you can use a surrogate serializer. (This technique does਍ഀ not work in .NET Framework 4.)

਍ഀ ਍ഀ

Create a class that਍ഀ implements the ISerializationSurrogate interface. ਍ഀ In this class, you implement GetObjectData and SetObjectData methods in order਍ഀ to serialize and deserialze the data, respectively. In GetObjectData you invoke SerializationInfo.AddValue (using the਍ഀ appropriate overload for the data type of your data) to add individual fields਍ഀ of the object to serialize to a SerializationInfo object. In SetObjectData you extract the਍ഀ serialized version back to its original value in the object. Here's an example:

਍ഀ ਍ഀ
public class EmployeeSerializationSurrogate : ISerializationSurrogate
{
    // Serialize the Employee object to save the object name and address fields.
    public void GetObjectData(Object obj, SerializationInfo info, StreamingContext context)
    {
        Employee emp = (Employee)obj;
        info.AddValue("name", emp.name);
        info.AddValue("address", emp.address);
    }
 
    // Deserialize the Employee object to set the object name and address fields.
    public Object SetObjectData(Object obj, SerializationInfo info, StreamingContext context,
        ISurrogateSelector selector)
    {
        Employee emp = (Employee)obj;
        emp.name = info.GetString("name");
        emp.address = info.GetString("address");
        return null;
    }
}
਍ഀ ਍ഀ

You then register਍ഀ the serializer and the class to be serialized using the SurrogateSelector class in code,਍ഀ like this:

਍ഀ ਍ഀ
protected void Page_Load(object sender, EventArgs e)
{
    SurrogateSelector ss = new SurrogateSelector();
    ss.AddSurrogate(typeof(Employee), new StreamingContext(StreamingContextStates.All), new EmployeeSerializationSurrogate());
    SessionStateUtility.SerializationSurrogateSelector = ss;
}
਍ഀ ਍ഀ

Deploying਍ഀ to a Cloud Environment

਍ഀ ਍ഀ

If you are deploying to a cloud environment that has਍ഀ multiple web server instances, you should change session state mode from਍ഀ "InProc" to "Custom". ਍ഀ In addition, change the connection string named਍ഀ "DefaultConnection" to connect to an instance of SQL Server਍ഀ (including SQL Azure and SQL ਍ഀ Compact) instead of to SQL Server Express.

਍ഀ ਍ഀ

Known਍ഀ Issues

਍ഀ ਍ഀ

·        ਍ഀ During਍ഀ the installation process, NuGet performs an exact match on items in the web.config file. If you਍ഀ have customized any of the elements in web.config਍ഀ that are updated by the installation process for ASP.NET Universal Providers,਍ഀ the installation process will not find these elements. Instead of updating the਍ഀ elements, the installation process will assume that they do not exist and add਍ഀ them. As a result, the web.config਍ഀ will effectively contain duplicate elements.

਍ഀ ਍ഀ

If your application਍ഀ is experiencing issues that indicate problems in the web.config file, make਍ഀ sure that the file contains the elements that are illustrated earlier in this਍ഀ document and remove any duplicate elements.

਍ഀ ਍ഀ

·        ਍ഀ If you are working in Visual Studio਍ഀ and use Server਍ഀ Explorer to open the database that contains the membership,਍ഀ role, profile, or session provider tables, and if you then try to run the਍ഀ application, you might see an error like the following:

਍ഀ ਍ഀ

Cannot਍ഀ open database "aspnet" requested by the login. The login failed.਍ഀ Login failed for user 'yourname.'

਍ഀ ਍ഀ

To਍ഀ resolve this issue, right-click the database in Server Explorer and then click Close Connection.

਍ഀ ਍ഀ

·        ਍ഀ The਍ഀ new providers do not use the same tables, stored procedures, and database਍ഀ objects as the SQL-based providers. If you switch to the new providers in an਍ഀ existing application, the data from the existing tables will not be available.਍ഀ We are considering creating a conversion utility to help you move existing਍ഀ applications to the new providers.

਍ഀ ਍ഀ

·        ਍ഀ Web਍ഀ Parts personalization will not work with Universal Providers. You must use the਍ഀ SQL Personalization provider. That in turn does not work with LocalDB, so you਍ഀ must use SQL Server Express.

਍ഀ ਍ഀ

·        ਍ഀ This਍ഀ release requires that the ASP.NET application be running under full trust.

਍ഀ ਍ഀ

Additional਍ഀ Resources

਍ഀ ਍ഀ

·        ਍ഀ Managing Users by਍ഀ Using Membership

਍ഀ ਍ഀ

·        ਍ഀ Managing਍ഀ Authorization Using Roles

਍ഀ ਍ഀ

·        ਍ഀ ASP.NET Profile਍ഀ Providers

਍ഀ ਍ഀ

·        ਍ഀ Microsoft SQL Azure

਍ഀ ਍ഀ

·        ਍ഀ Microsoft਍ഀ SQL Server Compact

਍ഀ ਍ഀ

·        ਍ഀ Configuration਍ഀ File and Source Code Transformations

਍ഀ ਍ഀ

Disclaimer

਍ഀ ਍ഀ

This is a਍ഀ preliminary document and may be changed substantially prior to final commercial਍ഀ release of the software described herein.

਍ഀ ਍ഀ

The information contained਍ഀ in this document represents the current view of Microsoft Corporation on the਍ഀ issues discussed as of the date of publication. Because Microsoft must respond਍ഀ to changing market conditions, it should not be interpreted to be a commitment਍ഀ on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any਍ഀ information presented after the date of publication.

਍ഀ ਍ഀ

This White Paper is਍ഀ for informational purposes only. MICROSOFT MAKES NO WARRANTIES, EXPRESS,਍ഀ IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS DOCUMENT.

਍ഀ ਍ഀ

Complying with all਍ഀ applicable copyright laws is the responsibility of the user. Without limiting਍ഀ the rights under copyright, no part of this document may be reproduced, stored਍ഀ in or introduced into a retrieval system, or transmitted in any form or by any਍ഀ means (electronic, mechanical, photocopying, recording, or otherwise), or for਍ഀ any purpose, without the express written permission of Microsoft Corporation.

਍ഀ ਍ഀ

Microsoft may have਍ഀ patents, patent applications, trademarks, copyrights, or other intellectual਍ഀ property rights covering subject matter in this document. Except਍ഀ as expressly provided in any written license agreement from Microsoft, the਍ഀ furnishing of this document does not give you any license to these patents,਍ഀ trademarks, copyrights, or other intellectual property.

਍ഀ ਍ഀ

Unless otherwise਍ഀ noted, the example companies, organizations, products, domain names, e-mail਍ഀ addresses, logos, people, places and events depicted herein are fictitious, and਍ഀ no association with any real company, organization, product, domain name, email਍ഀ address, logo, person, place or event is intended or should be inferred.

਍ഀ ਍ഀ

© 2011 Microsoft਍ഀ Corporation. All rights reserved.

਍ഀ ਍ഀ

Microsoft and਍ഀ Windows are either registered trademarks or trademarks of Microsoft Corporation਍ഀ in the United States and/or other countries.

਍ഀ ਍ഀ

The names of actual਍ഀ companies and products mentioned herein may be the trademarks of their਍ഀ respective owners.

਍ഀ ਍ഀ
਍ഀ ਍ഀ ਍ഀ ਍ഀ ਍ഀ