3.2. Create a Personalizable Custom Web Part
Note: Learn how to create a personalizable custom Web Part and see how it can be exported to a file.
In the previous lab you have seen how to create a Web Part by using either a web server control or a Web User control. In this lab, you will learn another way of creating Web Parts: using a custom control. By using a custom control you gain the flexibility to design your own UI for the Web Part. But more importantly, by inheriting from the WebPart class you also are able to perform tasks that would not ordinarily be available, such as exporting a Web Part to a file. Also, you will learn how you can create personalizable Web Parts that are able to persist information in the Web Part for each specific user.
Tip: Personalizable Web Parts are also applicable to a Web User control.
3.2.1. How do I do that?
In this lab, you will add a custom Web Control Library to the solution created in the previous lab. The Web Control Library project template allows you to create a custom web control, and in this lab you will learn how to convert this control into a Web Part control. This custom control will consume a translation web service that translates words from English to French. The control will also save the last word (to be translated) so that when the user visits the page again, that word will be displayed.
First, you'll need to create the Web Control Library. Launch Visual Studio 2005 and add a new Web Control Library project (File Add New Project) to the project created in the last lab (C:\ASPNET20\chap03-Webparts). Name the project C:\ASPNET20\chap03-TranslationWebPart (see Figure 3-11).
Figure 3-11. Adding a new Web Control Library project to the current project
Add a Web Reference (right-click the chap03-TranslationWebPart project name in Solution Explorer and select Add Web Reference...) to point to the Translation Web service at http://www.webservicex.com/TranslateService.asmx?WSDL. This step makes the translation service available to your project as a web service.
To help keep the bits of the project organized in your head, rename the source file for the project from the default name, WebCustomControl1.vb, to TranslationWebPart.vb.
The Solution Explorer window for your project should now look like Figure 3-12.
Figure 3-12. The Solution Explorer with the two projects
Provide the implementation for this control by replacing the default content of TranslationWebPart.vb with the code shown in Example 3-1.
Example 3-1. TranslationWebPart.vb
Imports System.Web.UI.WebControls.WebParts Public Class TranslationWebPart Inherits WebPart Private pStrText As String = Nothing Private txtStringToTranslate As TextBox Private lblTranslatedString As Label Public Sub New( ) Me.AllowClose = True End Sub <Personalizable( ), WebBrowsable( )> _ Public Property strToTranslate( ) As String Get Return pStrText End Get Set(ByVal value As String) pStrText = value End Set End Property Protected Overrides Sub CreateChildControls( ) Controls.Clear( ) '---display a textbox txtStringToTranslate = New TextBox( ) txtStringToTranslate.Text = Me.strToTranslate Me.Controls.Add(txtStringToTranslate) '---display a button Dim btnTranslate As New Button( ) btnTranslate.Text = "Translate" AddHandler btnTranslate.Click, AddressOf Me.btnTranslate_Click Me.Controls.Add(btnTranslate) '---display a label lblTranslatedString = New Label( ) lblTranslatedString.BackColor = _ System.Drawing.Color.Yellow Me.Controls.Add(lblTranslatedString) ChildControlsCreated = True End Sub Private Sub btnTranslate_Click(ByVal sender As Object, _ ByVal e As EventArgs) '---display the translated sentence If txtStringToTranslate.Text <> String.Empty Then Me.strToTranslate = txtStringToTranslate.Text txtStringToTranslate.Text = String.Empty '---access the web service Dim ws As New com.webservicex.www.TranslateService lblTranslatedString.Text = "<br/>" & Me.strToTranslate & "-->" & _ ws.Translate(com.webservicex.www.Language.EnglishTOFrench, _ Me.strToTranslate) End If End Sub End Class
Specifically, you are creating a custom Web Part control that looks like Figure 3-13. The custom Web Part control will allow users to enter a string in English so that it can be translated into French. The translated text would then be displayed in a label control.
Figure 3-13. Creating the custom control
To use the custom control, you need to compile the custom control into a DLL. Right-click the chap03-TranslationWebPart project name in Solution Explorer and select Build.
It's time to put your new control to work. First, return to the Default.aspx page in the chap03-WebParts project you created in the last lab.
To make the control readily available for use with your projects, let's add it to the Toolbox. To do so, right-click the Standard tab within the Toolbox and select Choose Items... (see Figure 3-14).
Figure 3-14. Adding new items to the Toolbox
In the Choose Toolbox Items dialog, click the Browse... button. Locate the chap03-TranslationWebPart.dll file in the C:\ASPNET20\chap03-TranslationWebPart\bin folder. Click OK and then OK again.
You should now be able to see the custom control in the Toolbox (see Figure 3-15).
Figure 3-15. The TranslationWebPart control in the Toolbox
To use the control, drag and drop the TranslationWebPart control from the Toolbox onto WebPartZone2 on the Default.aspx page of your project (see Figure 3-16).
Your Web Part lacks a title, as you'll notice. To fix that, switch to Source View for the page, and under WebPartZone2, locate the <cc1:TranslationWebPart> element. Add the <title> attribute as follows:
<ZoneTemplate> <uc1:Google title="Google Search" runat="server" /> <cc1:TranslationWebPart runat="server" title="Translation Service" /> </ZoneTemplate>
To see the results of your work, switch back to Design View, and your page should now look like Figure 3-16.
Figure 3-16. Adding a custom Web Part control to WebPartZone2
Press F5 to test the application. You will now be able to use the custom Web Part you have created and perform a translation from English to French. Try typing in the word "Hello" and observe the result, which should resemble Figure 3-17. You can also minimize and close the Web Part just like any other Web Part.
Figure 3-17. Using the custom Web Part
3.2.2. What just happened?
What you have just done is create a new custom Web Part control. If you observe the property definition for strToTranslate, you will notice that there are two attributes prefixing it:
<Personalizable( ), WebBrowsable( )> _ Public Property strToTranslate( ) As String ...
The Personalizable attribute allows you to persist information contained within the Web Part so that it can be personalized for each user. There are two scopes you can set for the Personalizable attribute: User (default) and Shared. In this example, you use the default User scope for personalization; hence, each time a user enters text into the text box, that text will be saved. In other words, the Web Part will remember the last word typed into the text box for each individual user.
Note: Personalization in Web Parts works for ASP.NET server controls, custom controls, and user controls.
The other personalization scope, Shared, saves this information but makes it visible to all users. To use shared personalization, use the PersonalizationScope.Shared enumeration within the Personalizable attribute:
<Personalizable(PersonalizationScope.Shared), WebBrowsable( )> _ Public Property strToTranslate( ) As String ...
In doing so, all users will be able to see the text (typed in by the last user) to be translated.
You will learn more about the use of the <WebBrowsable> attribute in the lab Section 3.5, later in this chapter.
Testing Per-User Personalization
So far, you have been using the default Windows authentication for your project and hence you won't be able to see how per-user personalization actually works for different users. To test per-user personalization for different users, follow these steps:
Add two user accounts to your web site through the ASP.NET Web Site Administration Tool (WebSite ASP.NET Configuration). Refer to Chapter 5 for more information on how to add new users to your web site.
Add a Login.aspx page to your web site and populate it with the Login control.
Modify Web.config to disallow anonymous users:
<authenication mode="Forms" /> <authorization> <deny users="?"/> </authorization>
Select Default.aspx in Solution Explorer and press F5. You will be redirected to Login.aspx. Log in using the first user account. Type in some text in the custom Web Part control's text box and click the Translate button.
Load Login.aspx again and this time log in using the other user account. As usual, type in some text in the custom Web Part control and click the Translate button.
If you now load Login.aspx again and log in using the first user account, you will notice that the text box in the custom Web Part control will display the text that you last entered for the first user.
3.2.3. What about...
...exporting a Web Part control?
You can export a Web Part to a file so that it can be shared among users by, say, exchanging email. To see how to export a Web Part, try following these steps:
Go to Default.aspx and switch to Source View. Locate the Translation Web Part and add the ExportMode attribute, as shown in the following snippet:
<cc1:TranslationWebPart title="Translation Service" ExportMode=All runat="server" />
Tip: You can export a Web Part only if the custom control inherits from the WebPart class.
You also need to add the <webParts> element into web.config:
<system.web> <webParts enableExport="true" /> ...
Press F5 to test the application. In the Translation Web Part, click on the arrow in the top-right corner and select Export (see Figure 3-18).
Figure 3-18. Exporting a Web Part
When you test the application, you will see a warning that this Web Part may contain confidential information (see Figure 3-19).
Figure 3-19. The warning dialog before saving a Web Part
Controlling the Export of Sensitive Data
The ExportMode attribute can take either of the following values: All, None, and NonSensitiveData. The default export mode is None. The NonSensitiveData mode will persist only data that is not marked as sensitive (through the isSensitive parameter in the <Personalizable> attribute).
To mark data in a Web Part as sensitive, specify true for the second parameter of the <Personalizable> attribute:
<Personalizable(PersonalizationScope.User, True), _ WebBrowsable( )> _ Public Property strToTranslate( ) As String ...
Click OK and then in the next dialog box, click the Save button to save the Web Part to a file.
Use the default name of TranslationService.WebPart and click the Save button to save the Web Part to the Desktop.
To examine the state of the saved Web Part, use Notepad and load the TranslationService.WebPart file. You should see code that resembles the XML in Example 3-2.
Example 3-2. TranslationService.WebPart content
<webParts> <webPart> <metaData> <type name="chap03_TranslationWebPart.TranslationWebPart" /> <importErrorMessage>Cannot import this Web Part.</importErrorMessage> </metaData> <data> <properties> <property name="AllowClose">True</property> <property name="Width" /> <property name="strToTranslate">Hello</property> <property name="AllowMinimize">True</property> <property name="AllowConnect">True</property> <property name="ChromeType">Default</property> <property name="TitleIconImageUrl" /> <property name="Description" /> <property name="Hidden">False</property> <property name="TitleUrl" /> <property name="AllowEdit">True</property> <property name="Height" /> <property name="HelpUrl" /> <property name="Title">Translation Service</property> <property name="CatalogIconImageUrl" /> <property name="Direction">NotSet</property> <property name="ChromeState">Normal</property> <property name="AllowZoneChange">True</property> <property name="AllowHide">True</property> <property name="HelpMode">Navigate</property> <property name="ExportMode">All</property> </properties> </data> </webPart> </webParts>
Note that the word "Hello" persisted in the .WebPart file.
3.2.4. Where can I learn more?
To learn more about creating custom controls, check out the following links: