Creating Custom Filters


As you saw earlier in the chapter, it’s possible to add and remove filters from the pipeline; we also briefly mentioned that it’s possible to create your own filters. We’ll now look at creating our own input and output filters that simply add a message to the event log; the message we’ll log is simply the body of the message that we’re sending and receiving.

Under the Covers

As we mentioned earlier, all filters used by WSE inherit from SoapInputFilter or SoapOutputFilter. We briefly explained how filters are actually called because you didn’t need to understand the process by which the prewritten filters are called to use them. Now that we’re developing our own filters, however, you do need to understand this in more detail.

If you look at the documentation for either of the filter base classes, you’ll see that they have only one exposed method, ProcessMessage. This method has one parameter—an instance of the SoapEnvelope class—and we can use this to access the message we’re working with. In this example, we’re only reading from the SoapEnvelope, but nothing can stop a filter from modifying the SoapEnvelope. Any filters that are processed after this filter will receive the modified SoapEnvelope.

This is exactly what the existing filters do—they override the ProcessMessage method and perform their own logic. When an incoming filter processes a message, it interrogates the SoapEnvelope object and populates the correct SoapContext object. The input filter removes the details specific to it from the SoapEnvelope object—the SecurityInputFilter object unencrypts the message if necessary, the TimestampInputFilter object removes the timestamp details, and so forth. Output filters do the opposite and use the correct SoapContext object to modify the SoapEnvelope object, adding details specific to them—the SecurityOutputFilter object might encrypt the message, the TimestampOutputFilter object adds the timestamp details, and so on.

To write your own filter, you follow the same paradigm. You inherit from the correct base class and override the ProcessMessage method.

Building a Custom Filter

We first need to decide whether we’re writing an input filter or an output filter. We can’t write one filter and use this as both the input and the output filter; we must create a unique filter that derives from the correct base class.

We simply add a new class file to our project and create the two classes we require—one inheriting from SoapInputFilter and one from SoapOutputFilter. Within each derived class, we override the ProcessMessage method and call the WriteToEventLog static method on the Logger class (which you’ll see shortly).

namespace CustomFilterClient {     public class EventLogInputFilter : SoapInputFilter     {         public override void ProcessMessage(SoapEnvelope envelope)         {             string strMessage = "INCOMING:\n\n " + envelope.InnerXml;             Logger.WriteToEventLog(strMessage);         }     }     public class EventLogOutputFilter : SoapOutputFilter     {         public override void ProcessMessage(SoapEnvelope envelope)         {             string strMessage = "OUTGOING:\n\n " + envelope.InnerXml;             EventLogger.WriteToEventLog(strMessage);         }     } }

Because we’re performing the same function in both the input filter and the output filter, we’ve created another class, Logger, with one static method, WriteToEventLog, that writes a string we pass it into the event log. Having this in a separate method allows us to use the same logic in both the input and the output filters without repeating any code.

In the WriteToEventLog method, we simply take the string that has been passed as a parameter and write a new entry to the event log. We allow .NET to create the event source for us automatically when we create the EventLog instance, and we delete the event source after we’ve used it:

public class Logger {     public static void WriteToEventLog(string strMessage)     {         string strSource = "NotAShop.com";         // create an event log object (auto creates event source)         EventLog evLog = new EventLog("Application", ".", strSource);         // write message to the event log         evLog.WriteEntry(strMessage, EventLogEntryType.Information);         // now delete the event source we created         EventLog.DeleteEventSource(strSource);     } }

Adding a Custom Filter

As we stated briefly at the start of the chapter, you can add custom filters to the pipeline in two ways: you can add them to the end of the pipeline by using the configuration files, or you can add them programmatically at any point in the pipeline.

We’ll add them programmatically because we want them to trap the actual SOAP message that’s sent or received by the code—we’re not interested in the changes that the other filters might have made to the SOAP envelope. We can do this easily by adding a new instance of the filter we require at position zero to the correct filter collection. We do this in the Load event of the client application’s main form so it is set as soon as we start the application.

// add the custom input filter to the pipeline SoapInputFilterCollection inputFilters =     WebServicesConfiguration.FilterConfiguration.InputFilters; inputFilters.Insert(0, new EventLogInputFilter()); // add the custom output filter to the pipeline SoapOutputFilterCollection outputFilters =     WebServicesConfiguration.FilterConfiguration.OutputFilters; outputFilters.Insert(0, new EventLogOutputFilter());

Note

We’re only showing the custom filter being added to the pipelines on the client, but the code to add the filters on the server is identical. Instead of adding it in the Load event of the form, you add it to the Application_Start event in the global.asax file for the service.

Custom Filters on the Client

We’ll show the use of our custom filter by creating a new client application, CustomFilterClient, that calls the Timestamp and Diagnostics Web services that you saw earlier.

You’ve actually seen the four lines of client code to add the custom filters to the pipeline, but there’s a little more to the client application than that. Figure 13-13 shows a drop-down list to select the service you want to call and an Execute button to call the service you’ve selected.


Figure 13-13: The CustomFilterClient application

Rather than write another Web service to show the custom filter in use, we’ll use two of the services you’ve already seen in this chapter—the Diagnostics Web service, at http://localhost/wscr/13/diagnosticsws.asmx, and the Timestamp Web service, at http://localhost/wscr/13/timestampws.asmx.

The code to set up the five entries in the drop-down list is in the Load event for the form, after the code to add the custom filters to the pipeline. It’s very simple and simply adds two entries and then sets the first entry as the selected entry:

// populate the drop down box cboService.Items.Add("DiagnosticsWS"); cboService.Items.Add("TimestampWS"); cboService.SelectedIndex = 0;

The work done by the client is contained in the click event handler for the Execute button. We use exactly the same method for calling the remote services that we used previously. We determine which service has been selected and then create the correct proxy method. Once we create the proxy, we can call the correct method and return the results as a dialog box to the user:

switch (cboService.SelectedItem.ToString()) {     case "DiagnosticsWS":         DiagnosticsWSWse Dproxy = new DiagnosticsWSWse();         MessageBox.Show(Dproxy.MakeMyDay(), "Returned message");         break;     case "TimestampWS":         TimestampWSWse Tproxy = new TimestampWSWse();         MessageBox.Show(Tproxy.Time(), "Returned message");         break; }

When you call any of the services, the call is made and you’re not immediately aware that a custom filter has been used. If you look at the Event Viewer entries, as shown in Figure 13-14, you can see that the details have been written to the event log as we requested.

click to expand
Figure 13-14: Entries written to event log by the custom filter




Programming Microsoft. NET XML Web Services
Programming MicrosoftВ® .NET XML Web Services (Pro-Developer)
ISBN: 0735619123
EAN: 2147483647
Year: 2005
Pages: 172

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net