收录日期:2019/03/20 19:59:13 时间:2012-08-25 00:06:09 标签:asp.net,web-services

This relates specifically to .NET. And I've decided to use the Web service Reference instead of Web Service...I think though my questions below really are for either situation and I want to try to get the overall idea of this.

So here is the issue for me. Let me first explain where I'm coming from. One past projects, I've talked to a couple APIs before by creating manual classes such as a GetPicturesRequest.cs and a GetPicturesResponse.cs for example that would hold state for me. I'd have a base class called Request.cs that did the actual sending of the api call:

Stream requestStream;
Stream responseStream;
XmlDocument doc = new XmlDocument();
doc = CreateRequestXML();

// Determins if API call needs to use a session based URI
string requestURI = UseAuthURI == true ? _requestURIAuthBased + JSessionID : _requestURI;

byte[] data = XmlUtil.DocumentToBytes(doc);

// Create the atual Request instance
HttpWebRequest request = CreateWebRequest(requestURI, data.Length);
request.ContentLength = data.Length;
request.KeepAlive = false;
request.Timeout = 30000;

// Send the Request
requestStream = request.GetRequestStream();
requestStream.Write(data, 0, data.Length);
requestStream.Close();

Now I want to use a Web service Reference. So I pointed and created a new reference to https://www.sandbox.paypal.com/wsdl/PayPalSvc.wsdl in VS 2008. I now have a Web Reference.

I have now these questions as being a first time user of web services as opposed to doing things manually as I was to use a 3rd party API:

1) How can I specify header params? For instance some APIs require you to send a hash (signature), sessionID, username, password, you name it along with the API method call request. How do you specify this using a web service proxy class?

2) How is the request/response objects handled or do I not need to worry about this now that I'm using a web service/reference? I mean do I need to create a request object still and how would I receive the response?

3) When I receive the response, does the proxy class contain its state or do I have to still create a class to hold the state of the returned data from the API method call response when using web services/references?

4) When ever would I want to instead just create custom code like I did before and not use web services/reference option with WSDL?...essentially creating my own proxy classes, request objects, response objects, everything? Rather than have VS spit out a Web Reference based on a WSDL? Is it because if it's not a SOAP based 3rd party API? Is it because the 3rd party API does not provide a WSDL then you're forced to hand code the wrappers yourself?

There's serious confusion here. Everybody please STOP!

WSE is obsolete. Don't use it.

"Web References" relate to the old ASMX web service technology. Microsoft now considers it to be "legacy" code and has stopped fixing bugs. Don't use it if you don't have to.

The OP should use "Add Service Reference". I just tried it, and it worked.


Now, to your questions:

  1. How can I specify header params?

    Because this service uses headers, the proxy classes have been generated as Message Contracts, which can have header parts, and body parts. For instance, the RefundTransactionRequest class has a RequesterCredentials property which is of the CustomSecurityHeaderType type. You simply set that before sending the request. In fact, it has generated a constructor for RefundTransactionRequest that takes both the header and the body as parameters, so this is easy.

  2. How is the request/response objects handled?

    You don't have to do anything except create instances of classes, and call methods. All the serialization is done for you. All the class creation is done for you.

  3. When I receive the response, does the Proxy class contain its state?

    Yes. The proxy class will contain all message header and body parts. Of course, there will only be a header part if there was an output header.

  4. When ever would I want to instead just create custom code like I did before and not use web services/reference option with WSDL?

    Never, I think. I've never seen a reason to do so. I guess the only time would be if there was a bug in "Add Service Reference".


Example:

using (var svc = new PayPalAPIAAInterfaceClient())
{
    var paypal = (PayPalAPIInterface) svc;
    var credentials = new CustomSecurityHeaderType
                          {
                              Credentials =
                                  new UserIdPasswordType
                                      {
                                          AppId = "",
                                          Username = "John",
                                          Password = "John"
                                      }
                          };
    var request = new RefundTransactionRequestType
                      {
                          Amount =
                              new BasicAmountType
                                  {
                                      currencyID = CurrencyCodeType.USD,
                                      Value = "100.00"
                                  },
                          Memo = "I want my money back",
                          RefundType = RefundType.Full,
                          RefundTypeSpecified = true
                      };
    var refundRequest = new RefundTransactionReq
                            {RefundTransactionRequest = request};
    var result =
        paypal.RefundTransaction(
            new RefundTransactionRequest(credentials, refundRequest));
    var response = result.RefundTransactionResponse1;
    var returnedCredentials = result.RequesterCredentials;
}

I'm assuming you are using a web reference for this. For the most part, using the web service should be as easy as using a local object. .NET handles all of the plumbing under the covers. Sometimes this works very nicely -- other times not so much.

When you add a web reference to the PayPal web service Visual Studio will create a file in a sub-folder of Web References called reference.cs which is the proxy class (by default VS 2008 hides it -- you have to "show all files" to see it).

For your specific case, it looks like PayPal is using custom SOAP headers to transmit all of the security context information. Take a look at the CustomSecurityHeaderType and the UserIdPasswordType types for more details. Also, some documentation from PayPal might help. :)

To use the service you will have to do something like this:

    PayPalAPISoapBinding payPal = new PayPalAPISoapBinding();

    CustomSecurityHeaderType customSecurity = new CustomSecurityHeaderType();
    customSecurity.eBayAuthToken = "The Auth Token";

    UserIdPasswordType userId = new UserIdPasswordType();
    userId.Password = "PWD";
    userId.Username = "JIMMY";

    customSecurity.Credentials = userId;

    payPal.RequesterCredentials = customSecurity;

    RefundTransactionReq request = new RefundTransactionReq();

    RefundTransactionResponseType response = payPal.RefundTransaction(request);

I'm not familiar with the PayPal service but I think this is how it should work.

1) In your case signature, username and password are transferred in a soap header. You will need to install WSE 3.0, activate it in your VS project and generate proxy once again.

2) Request creation and response parsing are made by WSE internals. Just create proxy, set the header and call the method on proxy.

3) There should be very strong reason to create custom implementation of proxy. WSE covers SOAP scenarios and part of WS-* specifications. WCF covers TCP, Pipes and MSMQ transports in addition to SOAP. Even if service doesn't provide WSDL, you still can specify contract yourselves and let frameworks do the transport work.