Pro ASP.NET 2.0 In CSharp 2005 (2005) [eng]
.pdf
1078 CHAPTER 31 ■ PORTALS WITH WEB PART PAGES
}
}
public DateTime SubmittedDate
{
get
{
//Get the NoteDate value from the grid's data source
//...
}
}
#endregion
// Rest of the implementation
...
Within the property procedures, you need to add the appropriate code for retrieving the values from the data source you have bound to the GridView in the WebPart’s original version. Updating the data in the property’s set procedure means updating the value in the GridView’s data source and then using, for example, a SqlCommand or a SqlDataAdapter for updating the values on the database. Retrieving the SubmittedDate from the GridView’s data source might look like this:
public DateTime SubmittedDate
{
get
{
EnsureChildControls();
if (CustomerNotesGrid.SelectedIndex >= 0)
{
int RowIndex = CustomerNotesGrid.SelectedRow.DataItemIndex;
DataTable dt = (DataTable)CustomerNotesGrid.DataSource; return (DateTime)dt.Rows[RowIndex]["NoteDate"];
}
else
{
return DateTime.MinValue;
}
}
}
You can verify whether an item has been selected in the GridView. (To do this, you need to enable selection on the GridView.) If an item is selected, you retrieve the DataItemIndex, which then can be used as an index for accessing the DataRow of the DataTable, which is bound to the GridView. You can read the value from the DataRow and return it.
The next thing your provider WebPart has to support is a method marked with the [ConnectionProvider] attribute. This method returns the actual implementation of the communication contract interface, which is the WebPart in this case. Therefore, you need to implement it as follows:
[ConnectionProvider("Notes Text")]
public INotesContract GetNotesCommunicationPoint()
{
return (INotesContract)this;
}
CHAPTER 31 ■ PORTALS WITH WEB PART PAGES |
1079 |
That’s it! Your provider WebPart is ready to use. Next you need to implement the consumer WebPart, which is much easier.
Creating the Consumer Web Part
The consumer WebPart retrieves information from the provider WebParts for its own purposes. In this example, you just display the text for the currently selected note in the CustomerNotesPart that you have implemented as the provider.
Because this solution does not contain this WebPart yet, you have to start from scratch. Just add a new class that inherits from WebPart. The WebPart uses the CreateChildControls for creating a label that displays the date, a text box that displays the notes text, and a button that updates the notes text.
public class CustomerNotesConsumer : WebPart
{
private Label NotesTextLabel; private TextBox NotesContentText; private Button UpdateNotesContent;
protected override void CreateChildControls()
{
NotesTextLabel = new Label(); NotesTextLabel.Text = DateTime.Now.ToString();
NotesContentText = new TextBox();
NotesContentText.TextMode = TextBoxMode.MultiLine;
NotesContentText.Rows = 5;
NotesContentText.Columns = 20;
UpdateNotesContent = new Button();
UpdateNotesContent.Text = "Update";
UpdateNotesContent.Click += new EventHandler(UpdateNotesContent_Click);
Controls.Add(NotesTextLabel);
Controls.Add(NotesContentText);
Controls.Add(UpdateNotesContent);
}
void UpdateNotesContent_Click(object sender, EventArgs e)
{
// Update code needs to be implemented later
}
}
Next, you have to add a simple method that is called by the ASP.NET web part framework automatically if the WebPart is connected to another WebPart. This method accepts the other connection point (which is the provider) as a parameter and needs to be marked with the [ConnectionConsumer] attribute so that the runtime knows this is the method to be called for passing in the provider.
private INotesContract _NotesProvider = null;
[ConnectionConsumer("Customer Notes")]
public void InitializeProvider(INotesContract provider)
{
_NotesProvider = provider;
}
1080 CHAPTER 31 ■ PORTALS WITH WEB PART PAGES
With the provider initialized, the WebPart of course can consume information from the provider by just calling properties (or methods) defined in the communication contract. For example, in the PreRender event you can initialize your controls, whereas in the button’s event procedure you can update the notes content by setting the Notes property appropriately:
void UpdateNotesContent_Click(object sender, EventArgs e)
{
if (_NotesProvider != null)
{
_NotesProvider.Notes = NotesContentText.Text;
}
}
protected override void OnPreRender(EventArgs e)
{
//Don't forget to call base implementation base.OnPreRender(e);
//Initialize control
if (_NotesProvider != null)
{
NotesContentText.Text = _NotesProvider.Notes; NotesTextLabel.Text =
_NotesProvider.SubmittedDate. ToShortDateString ();
}
}
Of course, you have to validate whether the provider has been initialized. If it hasn’t been, the WebPart is not connected with any other WebPart, and therefore you cannot access any information. However, with this code in place you are basically finished. You have created a consumer WebPart and a provider WebPart, and communication between those two takes place through the communication contract interface. Next you can connect these WebParts either manually or dynamically at runtime.
Static Connections Between WebParts
The simple way to connect WebParts is through static connections. How can you do that? Well, let’s think about the roles of the different controls involved in web part pages again. The WebPartManager knows about all the web parts and manages features such as personalization. WebPartZones are areas on your web page that can contain WebParts, while the WebParts are independent controls. If you think about it one moment, you definitely will recognize that the WebPartManager might be a good starting point for taking a closer look at connection points. You are right: static connection points are configured through the WebPartManager as follows:
<asp:WebPartManager runat="server" ID="MyPartManager"> <StaticConnections>
<asp:WebPartConnection ID="SimpleConnection" ProviderID="MyCustomerNotes" ConsumerID="MyNotesConsumer" />
</StaticConnections>
</asp:WebPartManager>
The ID values used for the ProviderID and ConsumerID are just the ID values of the WebParts as they have been added to the WebPart zone. You can find these WebParts in the zones of your WebPart page, as you can see in the following code fragment:
1082 CHAPTER 31 ■ PORTALS WITH WEB PART PAGES
Figure 31-16. ConnectionsZone in action
Multiple Connection Points
A WebPart provider can make multiple connection points available, while a WebPart consumer can consume multiple provider connection points. In that case, every connection point requires a unique ID on both the consumer side and the provider side. On the provider side, you specify the connection point ID in the [ConnectionProvider] attribute, as follows:
[ConnectionProvider("Notes Text", "MyProviderID")] public INotesContract GetNotesCommunicationPoint()
{
return (INotesContract)this;
}
You can specify an ID for consumer end points in the same way if a WebPart is a consumer of multiple providers, as follows:
[ConnectionConsumer("Customer Notes", "MyConsumerID")] public void InitializeProvider(INotesContract provider)
{
_NotesProvider = provider;
}
These IDs have to be unique within the WebPart. This means other WebParts can define connection points with the same ID. When configuring static connections for WebParts that support multiple connection points, you have to specify those through additional ProviderConnectionPointID and ConsumerConnectionPointID parameters, as follows:
CHAPTER 31 ■ PORTALS WITH WEB PART PAGES |
1083 |
<asp:WebPartManager runat="server" ID="MyPartManager"> <StaticConnections>
<asp:WebPartConnection ProviderID="MyCustomerNotes"
ProviderConnectionPointID="MyProviderID"
ConsumerID="MyCustomerNotesConsumer" ConsumerConnectionPointID="MyConsumerID" />
</StaticConnections>
</asp:WebPartManager>
In the case of dynamic configuration, the user can select the connection point to connect to based on the name specified as first parameter in the previously used [ConnectionProvider] and [ConnectionConsumer] attributes.
Authorizing Web Parts
When you have all your WebParts on your page, you might want to make some available to specific groups of users. Fortunately, the ASP.NET 2.0 Web Part Framework includes a way to specify such authorization information for web parts. All you need to do is catch one specific event of the WebPartManager class called AuthorizeWebPart. Within this event procedure, you can encapsulate logic for deciding whether a user is authorized to view a web part.
The following example shows how to display the CustomerNotes WebPart only if the user browsing to the page is member of the local Administrators group:
protected void MyPartManager_AuthorizeWebPart(
object sender, WebPartAuthorizationEventArgs e)
{
//Ignore authorization in Visual Studio Design Mode if (this.DesignMode)
return;
//Authorize a web part or not
Type PartType = e.Type;
if (PartType == typeof(CustomerNotesPart))
{
if (User.Identity.IsAuthenticated)
{
if (User.IsInRole("BUILTIN\\Administrators")) e.IsAuthorized = true;
else
e.IsAuthorized = false;
}
else
{
e.IsAuthorized = false;
}
}
}
Because authorization takes place on types of WebParts and not on individual instances of WebParts, you get the type of the WebPart to be authorized from the WebPartManager in the event arguments. You then can make authorization decisions based on the type of the WebPart as demonstrated previously. As soon as you set the IsAuthorized property of the WebPartAuthorizationEventArgs structure passed in to false, the WebPartManager will not display WebParts of this type— neither on the page nor in other situations such as a PageCatalogPart of a CatalogZone.
1084 CHAPTER 31 ■ PORTALS WITH WEB PART PAGES
Final Tasks for Personalization
Finally, you should keep in mind a couple of final tasks for personalization. You can configure personalization properties on a per-page level through the WebPartManager, as follows:
<asp:WebPartManager runat="server" ID="MyPartManager"> <Personalization Enabled="true" ProviderName="YourProvider" />
</asp:WebPartManager>
If you want to configure personalization settings for the whole application, you have to do that through the <webParts> configuration element in the web.config application configuration, as follows:
<webParts>
<personalization defaultProvider="MyProvider"> <authorization>
<allow roles="BUILTIN\Administrators"/> <deny roles="BUILTIN\Guests" />
</authorization>
<providers>
<add name="MyProvider" type="System.Web.UI.WebControls.WebParts.SqlPersonalizationProvider" connectionStringName="CustomSqlConnection" />
</providers>
</personalization>
</webParts>
This code also shows that you can even configure the specific users for which personalization is enabled or disabled. You do this through the <authorization> element; this element works the same way as the <authorization> element you learned about in Chapter 23.
Clearing Personalization
How can you delete personalization information from the store? To do this, you can use the Personalization property of the WebPartManager class; this gives you access to the personalization provider, the settings, and the functions for resetting personalization information. You can do
this as follows:
if (MyPartManager.Personalization.HasPersonalizationState) MyPartManager.Personalization.ResetPersonalizationState();
You can then include functionality in your application for resetting personalization in this way. This could be an administration page, for example.
Summary
In this chapter, you learned how to create real-world web part pages. Such pages include requirements such as personalization as well as a modularized structure through web parts that enable the user to select exactly the information that should be displayed. You also learned what WebPartManagers, WebPartZones, and WebParts are and what their tasks are.
Then you learned about important advanced features such as connecting web parts and authorizing web parts. You also know how to add custom properties to WebParts that will be stored on a per-user or shared basis, and you created custom editors for editing those properties.
The ASP.NET 2.0 Web Parts Framework provides you with a huge set of functionality. You never have to implement your own portal framework, as it is already included with the framework. And, as it is part of the .NET Framework, you get this all for free!
P A R T 6
■ ■ ■
Web Services
