Basic WebServices knowledge
1. supplement related to survival
Under normal circumstances, the server creates a new WebService object each time WebMethod is called, even if the client uses the same proxy object to call WebMethod multiple times.
Once we call a WebMethod with a cache tag, the WebService object will not be re-created as long as it does not exceed the cache period. If you call a WebMethod without any cached tags during the cache period, the WebService object will continue to be used. There are too many factors that make the cache mechanism less reliable. Therefore, we cannot expect to use the cache tag to maintain the specific object state, besides, the cache mechanism is designed to quickly output data that is relatively stable and very large.
Based on the multi-user concurrent call environment, WebService itself is best designed as a stateless object. We can use Session and Application to maintain specific State information.
2. asynchronous call
Many people on the internet like to use the word "Elegance" when writing articles about. net 2.0. Indeed, in 2.0, the compiler and code generator encapsulate a lot of wordy things for us, such as anonymous methods, delegate inference, and so on. Of course, there are asynchronous calls of this WebService. We no longer need to write those BeginXXX and EndXXX. The event-driven asynchronous mechanism will automatically generate a XXXAsync Asynchronous Method and XXXCompleted event for each WebMethod. We only need to call this method, asynchronous operations can be completed after the event is processed. Do not underestimate the 2.0 encapsulation. The less code we write, the less chance of errors.
In the following example, we use the anonymous method to process events, which looks more concise.
WebServices. cs
[WebService (Namespace = "http://www.rainsts.net/", Description = "my Web services")]
[WebServiceBinding (ConformsTo = WsiProfiles. BasicProfile1_1)]
Public class WebService: System. Web. Services. WebService
{
[WebMethod]
Public string HelloWorld ()
{
Return "Hello World! ";
}
}
Client. cs
WebService ws = new WebService ();
Ws. HelloWorldCompleted + = delegate (object sender, HelloWorldCompletedEventArgs e)
{
Console. WriteLine (e. Result );
};
Ws. HelloWorldAsync ("xxx ");
3. Cache
Webmethodattriation. CacheDuration provides a cache declarative mechanism for WebService. By adding this tag, We Can cache the output results. However, the cache mechanism will affect the survival of WebService (see above ).
WebServices. cs
[WebService (Namespace = "http://www.rainsts.net/", Description = "my Web services")]
[WebServiceBinding (ConformsTo = WsiProfiles. BasicProfile1_1)]
Public class WebService: System. Web. Services. WebService
{
[WebMethod (CacheDuration = 10)]
Public DateTime TestCache ()
{
Return DateTime. Now;
}
}
Client. cs
WebService ws = new WebService ();
For (int I = 0; I <20; I ++)
{
Console. WriteLine ("{0 }:{ 1}", I + 1, ws. TestCache ());
Thread. Sleep (1000 );
}
4. Keep status
. NET WebService is based on ASP. NET. In WebService, we can also access Session, User, Application, and other context objects, but some usage details may be different.
The proxy object of the WebService client may be applied to leleapplication, WinForm, WebForm, and other environments. Session must use cookies to save the unique SessionID, therefore, we must use CookieContainer to create a Cookie container to save the Session information returned by WebService. Otherwise, the SessionID of each call is different, and the Session cannot be used to save the status.
After creating a container object, you must assign its reference to the CookieContainer attribute of the proxy object. After SessionEnabled WebMethod is called for the first time, the container holds Session Cookie information. If you need to call SessionEnabled WebMethod in multiple proxy objects, they must hold the same Cookie container object.
WebServices. cs
[WebService (Namespace = "http://www.rainsts.net/", Description = "my Web services")]
[WebServiceBinding (ConformsTo = WsiProfiles. BasicProfile1_1)]
Public class WebService: System. Web. Services. WebService
{
[WebMethod (EnableSession = true)]
Public string TestSession ()
{
String s = "TestSession ";
Object o = Session [s];
Int I = o! = Null? (Int) o: 0;
++ I;
Session [s] = I;
Return Session. SessionID. ToString () + ":" + I;
}
}
Client. cs
WebService ws = new WebService ();
// Create a Cookie container and keep SessionID. Otherwise, the SessionID of each call is different.
CookieContainer cookies = new CookieContainer ();
Ws. CookieContainer = cookies;
For (int I = 0; I <10; I ++)
{
Console. WriteLine ("{0 }:{ 1}", I + 1, ws. TestSession ());
}
There is no difference between Application and WebForm.
WebServices. cs
[WebService (Namespace = "http://www.rainsts.net/", Description = "my Web services")]
[WebServiceBinding (ConformsTo = WsiProfiles. BasicProfile1_1)]
Public class WebService: System. Web. Services. WebService
{
[WebMethod]
Public DateTime TestApplicationState ()
{
Object o = Application ["TestApplicationState"];
If (o = null)
{
O = DateTime. Now;
Application ["TestApplicationState"] = o;
}
Return (DateTime) o;
}
}
Client. cs
For (int I = 0; I <10; I ++)
{
WebService ws = new WebService ();
Console. WriteLine ("{0 }:{ 1}", I + 1, ws. TestApplicationState ());
Thread. Sleep (1000 );
}
5. SoapHeader
In most cases, SoapHeader is used to transmit user authentication information. Of course, it has far more functions than this and needs to be explored in practical applications.
By default, SoapHeader is sent to WebService by the client proxy object. Of course, we can change the transmission Direction through WebMethodAttribute. Direction.
To use SoapHeader, follow these steps:
(1) Create the custom SoapHeader type inherited from System. Web. WebServices. SoapHeader.
(2) create a custom SoapHeader field with public access permission in WebService.
(3) Add the SoapHeaderAttribute access feature on the WebMethod that requires using SoapHeader. The memberName parameter must be specified for the SoapHeaderAttribute construction, which is the field name stated in step 2.
(4) The generator will automatically generate a custom SoapHeader type with the same name for the client, but it is more complicated than what we create on the WebService end. A soapheaderValue attribute is added for the proxy type.
In the Demo code below, the client will pass a custom MyHeader to WebService. Please note that although the MyHeader field is declared in WebService, no object instance is created because the XML passed by the client contains SoapHeader information, the infrastructure will automatically parse and create an object instance, and then assign the value to my field. As for the client, you need to create a MyHeader object instance and assign it to the WebService. MyHeaderValue attribute. SoapHeaderAttribute. Direction is In by default. In the following example, "Direction = SoapHeaderDirection. In" can be omitted.
WebServices. cs
Public class MyHeader: SoapHeader
{
Public string Username;
Public string Password;
}
[WebService (Namespace = "http://www.rainsts.net/", Description = "my Web services")]
[WebServiceBinding (ConformsTo = WsiProfiles. BasicProfile1_1)]
Public class WebService: System. Web. Services. WebService
{
Public MyHeader my;
[WebMethod]
[SoapHeader ("my", Direction = SoapHeaderDirection. In)]
Public void TestSoapHeadIn ()
{
System. Diagnostics. Debug. Write (my. Username );
System. Diagnostics. Debug. Write (my. Password );
}
}
Client. cs
WebService ws = new WebService ();
MyHeader head = new MyHeader ();
Head. Username = "u2 ";
Head. Password = "p2 ";
Ws. MyHeadValue = head;
Ws. TestSoapHeadIn ();
Change the transmission direction from WebService to client. Naturally, we need to adjust "Direction = SoapHeaderDirection. Out". In WebMethod, we must create a MyHeader instance, because this time we will not accept the SoapHeader passed by the client. After the client proxy object calls WebMethod, you can use the MyHeaderValue attribute to access its content.
WebServices. cs
Public class MyHeader: SoapHeader
{
Public string Username;
Public string Password;
}
[WebService (Namespace = "http://www.rainsts.net/", Description = "my Web services")]
[WebServiceBinding (ConformsTo = WsiProfiles. BasicProfile1_1)]
Public class WebService: System. Web. Services. WebService
{
Public MyHeader my;
[WebMethod]
[SoapHeader ("my", Direction = SoapHeaderDirection. Out)]
Public void TestSoapHeadOut ()
{
My = new MyHeader ();
My. Username = "u1 ";
My. Password = "p1 ";
}
}
Client. cs
WebService ws = new WebService ();
Ws. TestSoapHeadOut ();
Console. WriteLine (ws. MyHeaderValue. Username );
Console. WriteLine (ws. MyHeaderValue. Password );
6. Exceptions
ASP. NET WebService transmits exception information through the Fault XML element. The client proxy object generates a SoapException exception and uses the Fault XML Information to fill in its related attributes, such as Message. In addition, we can wrap WebService exceptions. In addition to passing Exception messages, we can also pass some error Status Code to facilitate further processing by the client users.
WebServices. cs
[WebService (Namespace = "http://www.rainsts.net/", Description = "my Web services")]
[WebServiceBinding (ConformsTo = WsiProfiles. BasicProfile1_1)]
Public class WebService: System. Web. Services. WebService
{
[WebMethod]
Public void TestException ()
{
Try
{
Throw new Exception ("aaa ...");
}
Catch (Exception e)
{
Throw new SoapException (e. Message, new System. Xml. XmlQualifiedName ("ErrorCode01"), e );
}
}
}
Client. cs
WebService ws = new WebService ();
Try
{
Ws. TestException ();
}
Catch (System. Web. Services. Protocols. SoapException e)
{
Console. WriteLine (e. Message );
Console. WriteLine (e. Code. Name );
} Address: http://www.rainsts.net/article.asp? Id = 282