WEBSITE

Microsoft ASP.NET 4 : Using the SqlProfileProvider (part 3) - Profiles and Custom Data Types

6/25/2012 5:59:58 PM

9. Profiles and Custom Data Types

Using a custom class with profiles is easy. You need to begin by creating the class that wraps the information you need. In your class, you can use public member variables or full-fledged property procedures. The latter choice, though longer, is the preferred option because it ensures your class will support data binding, and it gives you the flexibility to add property procedure code later.

Here's a Address class that ties together the same information you saw in the previous example, using automatic properties to reduce the amount of code:

<Serializable()> _
Public Class Address

    Public Property Name() As String
    Public Property Street() As String
    Public Property City() As String
    Public Property ZipCode() As String
    Public Property State() As String
    Public Property Country() As String

    Public Sub New(ByVal name As String, ByVal street As String, _
      ByVal city As String, ByVal zipCode As String, _
      ByVal state As String, ByVal country As String)

        Me.Name = name
        Me.Street = street
        Me.City = city
        Me.ZipCode = zipCode
        Me.State = state
        Me.Country = country
    End Sub

    Public Sub New()
    End Sub

End Class

You can place this class in the App_Code directory. The final step is to add a property that uses it:

<properties>
  <add name="Address" type="Address" />
</properties>

Now you can create a test page that uses the Address class. Figure 3 shows an example that simply allows you to load, change, and save the address information in a profile.

Figure 3. Editing complex information in a profile

Here's the page class that makes this possible:

Public Partial Class ComplexTypes
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, _
      ByVal e As System.EventArgs) Handles Me.Load
        If Not Page.IsPostBack Then
            LoadProfile()
        End If
    End Sub

    Protected Sub cmdGet_Click(ByVal sender As Object, _
      ByVal e As System.EventArgs) Handles cmdGet.Click
        LoadProfile()
    End Sub

    Private Sub LoadProfile()
        txtName.Text = Profile.Address.Name
        txtStreet.Text = Profile.Address.Street
        txtCity.Text = Profile.Address.City
        txtZip.Text = Profile.Address.ZipCode

txtState.Text = Profile.Address.State
        txtCountry.Text = Profile.Address.Country
    End Sub

    Protected Sub cmdSave_Click(ByVal sender As Object, _
      ByVal e As System.EventArgs) Handles cmdSave.Click
        Profile.Address = new Address(txtName.Text, _
          txtStreet.Text, txtCity.Text, txtZip.Text, _
          txtState.Text, txtCountry.Text)
    End Sub

End Class

9.1. Dissecting the Code . . .
  • When the page loads (and when the user clicks the Get button), the profile information is copied from the Profile.Address object into the various text boxes. A private LoadProfile() method handles this task.

  • The user can make changes to the address values in the text boxes. However, the change isn't committed until the user clicks the Save button.

  • When the Save button is clicked, a new Address object is created using the constructor that accepts name, street, city, zip code, state, and country information. This object is then assigned to the Profile.Address property. Instead of using this approach, you could modify each property of the current Profile.Address object to match the text values.

  • The content of the Profile object is saved to the database automatically when the request ends. No extra work is required.

9.2. Custom Type Serialization

You need to keep in mind a few points, depending on how you decide to serialize your custom class. By default, all custom data types use XML serialization with the XmlSerializer. This class is relatively limited in its serialization ability. It simply copies the value from every public property or member variable into a straightforward XML format like this:

<Address>
  <Name>...</Name>
  <Street>...</Street>
  <City>...</City>
  <ZipCode>...</ZipCode>
  <State>...</State>
  <Country>...</Country>
</Address>

When deserializing your class, the XmlSerializer needs to be able to find a parameterless public constructor. In addition, none of your properties can be read-only. If you violate either of these rules, the deserialization process will fail.

If you decide to use binary serialization instead of XmlSerialization, .NET uses a completely different approach:

<add name="Address" type="Address" serializeAs="Binary"/>

In this case, ASP.NET enlists the help of the BinaryFormatter. The BinaryFormatter can serialize the full public and private contents of any class, provided the class is decorated with the <Serializable()> attribute. Additionally, any class it derives from or references must also be serializable.

9.3. Automatic Saves

The profiles feature isn't able to detect changes in complex data types (anything other than strings, simple numeric types, Boolean values, and so on). This means if your profile includes complex data types, ASP.NET saves the complete profile information at the end of every request that accesses the Profile object.

This behavior obviously adds unnecessary overhead. To optimize performance when working with complex types, you have several choices. One option is to set the corresponding profile property to be read-only in the web.config file (if you know that property never changes). Another approach is to disable the autosave behavior completely by adding the automaticSaveEnabled attribute on the <profile> element and setting it to false, as shown here:

<profile defaultProvider="SqlProvider" automaticSaveEnabled="false">...</profile>

					  

If you choose this approach, it's up to you to call Profile.Save() to explicitly commit changes. Generally, this approach is the most convenient, because it's easy to spot the places in your code where you modify the profile. Just add the Profile.Save() call at the end:

Profile.Address = New Address(txtName.Text, txtStreet.Text, _
  txtCity.Text, txtZip.Text, txtState.Text, txtCountry.Text)
Profile.Save()

For instance, you could modify the earlier example (shown in Figure 21-3) to save address information only when it changes. The easiest way to do this is to disable automatic saves, but call Profile.Save() when the Save button is clicked. You could also handle the TextBox.TextChanged event to determine when changes are made, and save the profile immediately at this point.

Other  
 
Top 10
Review : Sigma 24mm f/1.4 DG HSM Art
Review : Canon EF11-24mm f/4L USM
Review : Creative Sound Blaster Roar 2
Review : Philips Fidelio M2L
Review : Alienware 17 - Dell's Alienware laptops
Review Smartwatch : Wellograph
Review : Xiaomi Redmi 2
Extending LINQ to Objects : Writing a Single Element Operator (part 2) - Building the RandomElement Operator
Extending LINQ to Objects : Writing a Single Element Operator (part 1) - Building Our Own Last Operator
3 Tips for Maintaining Your Cell Phone Battery (part 2) - Discharge Smart, Use Smart
REVIEW
- First look: Apple Watch

- 3 Tips for Maintaining Your Cell Phone Battery (part 1)

- 3 Tips for Maintaining Your Cell Phone Battery (part 2)
VIDEO TUTORIAL
- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 1)

- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 2)

- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 3)
Popular Tags
Video Tutorail Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Exchange Server Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe Photoshop CorelDRAW X5 CorelDraw 10 windows Phone 7 windows Phone 8 Iphone