Generally, WebService uses HTTP and can be intercepted by HttpModule. However, it is difficult to obtain detailed information for self-encoding and decoding. In addition, the Exception thrown by WebMethod is encapsulated and cannot be directly obtained through Context. Error like a normal page.
WebService does not directly inherit CBO. To implement AOP-type WebMethod interception and processing, you can use SoapExtension (Soap extension)
Soap extensions must inherit the SoapExtension class in two ways:
1. Use SoapExtensionAttribute to customize tags for each method before WebMethod.
2. Uniform tag in Web. xml.
<System. web>
<WebServices>
<SoapExtensionTypes>
<Add type = "Utility. LogExtension, Utility" priority = "1" group = "0"/>
</SoapExtensionTypes>
</WebServices>
</System. web>
In a WebMethod, The SoapExtension. ProcessMessage () method is called multiple times. In this way, the parameters before and after method execution are obtained, the returned results, and exceptions are returned.
By intercepting WebMethod, Log/Trace/Transaction control can be completed automatically. No need to keep trying/catch!
The following is a part of [LogExtension:
Public override void ProcessMessage (SoapMessage message)
{
Switch (message. Stage)
{
Case SoapMessageStage. BeforeSerialize: // can get return value
If (message. Exception = null & message. MethodInfo. ReturnType! = Typeof (void ))
OutValue = Convert. ToString (message. GetReturnValue ());
Break;
Case SoapMessageStage. AfterSerialize: // the last step
If (message. Exception = null)
Log. Info (GetLog (message ));
Else
Log. Warning (GetLog (message ));
Break;
Case SoapMessageStage. BeforeDeserialize:
Break;
Case SoapMessageStage. AfterDeserialize: // can get parameters
Int n = message. MethodInfo. Parameters. Length;
InParams = new string [n];
For (int I = 0; I <n; I ++)
InParams [I] = Convert. ToString (message. GetInParameterValue (I ));
Break;
Default:
Throw new Exception ("invalid stage ");
}
}
The following is the transaction control section of [TransExtension:
Public override void ProcessMessage (SoapMessage message)
{
Switch (message. Stage)
{
Case SoapMessageStage. BeforeSerialize: // step 3. can get return value
If (message. Exception = null)
DbHelper. Inst. Commit ();
Else
DbHelper. Inst. Rollback ();
DbHelper. Inst. Close ();
Break;
Case SoapMessageStage. AfterSerialize: // step 4
Case SoapMessageStage. BeforeDeserialize: // step 1
Break;
Case SoapMessageStage. AfterDeserialize: // step 2. can get parameters
DbHelper. Inst. BeginTransaction ();
Break;
Default:
Throw new Exception ("invalid stage ");
}
}