Solved

Two WSDLs, Same Definition, Different Endpoints

Posted on 2011-02-24
10
1,253 Views
Last Modified: 2012-05-11
Hello,

We are consuming an external WSDL in our app layer using a Service Reference.  Its actually the PayPal WSDL.

They have a test (sandbox) WSDL url and a live production WSDL url.  They both have the same definition but with different wsdl locations and different endpoints.  So how does one handle this in their code?  

We are basically trying to figure out how we can eliminate duplicate clasess/methods but be able to easily run the code for either the sanbox or live site using some config app keys or something.  Not sure what that all entails.

Do I need both of them as Service References?  If so, we can't include both in the same class file, otherwise there is ambiguity, so then do we need different classes and methods for each WSDL service reference?  

Is there a way to only use the live WSDL as the service reference but pass in the sandbox endpoint url so it hits their test site?  Is there anything else needed to be able to do this?

Ideas?  Thanks, ks

0
Comment
Question by:kruegerste
  • 5
  • 5
10 Comments
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 34974781
>>  Do I need both of them as Service References?  If so, we can't include both in the same class file, otherwise there is ambiguity, so then do we need different classes and methods for each WSDL service reference?  

The wonderful thing about "Add Service Reference," though, is that at the bottom of the dialog, you can specify the namespace you would like to give to the reference being added (see screenshot). So you can potentially add both references, but give them different and meaningful namespaces, and there should be no conflict.
untitled.PNG
0
 
LVL 4

Author Comment

by:kruegerste
ID: 34974861
That part I do understand and they do have different namespaces but that leads me to the other questions I had.  Are you able to answer any of the other ones?  

How do I differentiate between the two services in my code?  They have the same exact definition but different endpoints.

If they have different definitions, do I still need both even if they can have different namespaces?  If I have to reference both, then even with different namespaces, when I do the following, ambiguity persists:

using PayPalSvc;
using PayPalSvcSandbox;

We really need help with the overall solution of how to handle two services with the exact same definition but different endpoints.  Is it only the endpoint that matters if they are the same but different locations?  

Please help :)
0
 
LVL 4

Author Comment

by:kruegerste
ID: 34974902
Below is my method for doing the direct payment.  

So how do I specify an endpoint here?  Is this suppose to be in my web.config?  When I created the service, it created an app.config file with some endpoints and stuff in the c# class library.  But obviously my web app can't see that app.config.

And then the other issue of trying to use the same method/class for both the sandbox and live references.   Again, are they both really needed?  if so, how do i handle this?  if not, how do i handle this?
using System;
using System.Data;
using PayPalSvcSandbox;
using PayPalSvc;

public class PaymentBL
{
  public String DoDirectPayment(MOPInfo creditCardMOPInfo, String ipAddress)
		{
            try
            {
                PayPalAPIAAInterfaceClient client = new PayPalAPIAAInterfaceClient();
             
                CustomSecurityHeaderType credentials = new CustomSecurityHeaderType();
                credentials.Credentials = new UserIdPasswordType();
                credentials.Credentials.Username = SecurityBL.Decrypt(ConfigurationUtil.PayPalAPIUsername);
                credentials.Credentials.Password = SecurityBL.Decrypt(ConfigurationUtil.PayPalAPIPassword);
                credentials.Credentials.Signature = SecurityBL.Decrypt(ConfigurationUtil.PayPalAPISignature);
                credentials.Credentials.DevId = ConfigurationUtil.PayPalAPIEnvironment;
            
                DoDirectPaymentReq request = new DoDirectPaymentReq();
                request.DoDirectPaymentRequest = new DoDirectPaymentRequestType();
                request.DoDirectPaymentRequest.Version = "51.0";

                request.DoDirectPaymentRequest.DoDirectPaymentRequestDetails = new DoDirectPaymentRequestDetailsType();
                request.DoDirectPaymentRequest.DoDirectPaymentRequestDetails.IPAddress = ipAddress;

                request.DoDirectPaymentRequest.DoDirectPaymentRequestDetails.CreditCard = new CreditCardDetailsType();
                request.DoDirectPaymentRequest.DoDirectPaymentRequestDetails.CreditCard.CreditCardNumber = creditCardMOPInfo.CreditCardNumber;
                switch (creditCardMOPInfo.CreditCardType)
			    {
				    case ConstantRepository.CREDIT_CARD_VISA:
					    request.DoDirectPaymentRequest.DoDirectPaymentRequestDetails.CreditCard.CreditCardType = CreditCardTypeType.Visa;
					    break;
				    case ConstantRepository.CREDIT_CARD_MASTERCARD:
					    request.DoDirectPaymentRequest.DoDirectPaymentRequestDetails.CreditCard.CreditCardType = CreditCardTypeType.MasterCard;
					    break;
				    case ConstantRepository.CREDIT_CARD_DISCOVER:
					    request.DoDirectPaymentRequest.DoDirectPaymentRequestDetails.CreditCard.CreditCardType = CreditCardTypeType.Discover;
					    break;
			    }
                request.DoDirectPaymentRequest.DoDirectPaymentRequestDetails.CreditCard.ExpMonth = creditCardMOPInfo.CreditCardExpMonth.ToInt32();
                request.DoDirectPaymentRequest.DoDirectPaymentRequestDetails.CreditCard.ExpMonthSpecified = true;
                request.DoDirectPaymentRequest.DoDirectPaymentRequestDetails.CreditCard.ExpYear = creditCardMOPInfo.CreditCardExpYear.ToInt32();
                request.DoDirectPaymentRequest.DoDirectPaymentRequestDetails.CreditCard.ExpYearSpecified = true;
                request.DoDirectPaymentRequest.DoDirectPaymentRequestDetails.CreditCard.CVV2 = creditCardMOPInfo.CreditCardSecurityCode;

                request.DoDirectPaymentRequest.DoDirectPaymentRequestDetails.CreditCard.CardOwner = new PayerInfoType();
                request.DoDirectPaymentRequest.DoDirectPaymentRequestDetails.CreditCard.CardOwner.Payer = "";
                request.DoDirectPaymentRequest.DoDirectPaymentRequestDetails.CreditCard.CardOwner.PayerStatus = PayPalUserStatusCodeType.unverified;
                request.DoDirectPaymentRequest.DoDirectPaymentRequestDetails.CreditCard.CardOwner.PayerCountry = CountryCodeType.US;

                request.DoDirectPaymentRequest.DoDirectPaymentRequestDetails.CreditCard.CardOwner.PayerName = new PersonNameType();      
                request.DoDirectPaymentRequest.DoDirectPaymentRequestDetails.CreditCard.CardOwner.PayerName.FirstName = CustomerBL.GetName(creditCardMOPInfo.CreditCardName, EnumRepository.NamePart.FirstName);
                request.DoDirectPaymentRequest.DoDirectPaymentRequestDetails.CreditCard.CardOwner.PayerName.LastName = CustomerBL.GetName(creditCardMOPInfo.CreditCardName, EnumRepository.NamePart.LastName);
                                     
                request.DoDirectPaymentRequest.DoDirectPaymentRequestDetails.CreditCard.CardOwner.Address = new AddressType();
                request.DoDirectPaymentRequest.DoDirectPaymentRequestDetails.CreditCard.CardOwner.Address.Street1 = creditCardMOPInfo.MOPAddress.AddressLine1;
                request.DoDirectPaymentRequest.DoDirectPaymentRequestDetails.CreditCard.CardOwner.Address.Street2 = creditCardMOPInfo.MOPAddress.AddressLine2;
                request.DoDirectPaymentRequest.DoDirectPaymentRequestDetails.CreditCard.CardOwner.Address.CityName = creditCardMOPInfo.MOPAddress.City;
                request.DoDirectPaymentRequest.DoDirectPaymentRequestDetails.CreditCard.CardOwner.Address.StateOrProvince = creditCardMOPInfo.MOPAddress.StateCode;
                request.DoDirectPaymentRequest.DoDirectPaymentRequestDetails.CreditCard.CardOwner.Address.PostalCode = creditCardMOPInfo.MOPAddress.ZipCode.ToString();
                request.DoDirectPaymentRequest.DoDirectPaymentRequestDetails.CreditCard.CardOwner.Address.CountryName = "USA";
                request.DoDirectPaymentRequest.DoDirectPaymentRequestDetails.CreditCard.CardOwner.Address.Country = CountryCodeType.US;
                request.DoDirectPaymentRequest.DoDirectPaymentRequestDetails.CreditCard.CardOwner.Address.CountrySpecified = true;

                request.DoDirectPaymentRequest.DoDirectPaymentRequestDetails.PaymentDetails = new PaymentDetailsType();
                request.DoDirectPaymentRequest.DoDirectPaymentRequestDetails.PaymentDetails.OrderTotal = new BasicAmountType();
                request.DoDirectPaymentRequest.DoDirectPaymentRequestDetails.PaymentDetails.OrderTotal.currencyID = CurrencyCodeType.USD;
                request.DoDirectPaymentRequest.DoDirectPaymentRequestDetails.PaymentDetails.OrderTotal.Value = creditCardMOPInfo.MOPAmount.ToString();

                var response = client.DoDirectPayment(ref credentials, request);

			    return response.ToString();
            }
       }
}

Open in new window

0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 34979155
Line 12 should have an overload that allows you to pass in the name of the configuration (as specified in your web.config/app.config).
0
 
LVL 4

Author Comment

by:kruegerste
ID: 34979187
So does this mean I don't need both services referenced if they have the same definition?  And I can just pass in a different endpoint name, depending on the location/environment to hit?
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 34979240
I believe that as long as the namespaces on the XML itself are the same, then it should be possible. I haven't personally dealt with a scenario like this, though, so I can only surmise.
0
 
LVL 4

Author Comment

by:kruegerste
ID: 34979775
Anybody else?
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 34979988
If they have different definitions, do I still need both even if they can have different namespaces?  If I have to reference both, then even with different namespaces, when I do the following, ambiguity persists:

using PayPalSvc;
using PayPalSvcSandbox;

Of course there is ambiguity. You have included both namespaces in your "using" section. How would C# know which class you are referring to? If you want to stick with having a reference to both services, then you can provide another "using" in the context of an alias:

    using TestSvc = PayPalSvcSandbox.PaymentBL;

Then in code, you can refer to TestSvc.DoDirectPayment() rather than its official name.
0
 
LVL 4

Author Comment

by:kruegerste
ID: 34980126
It isn't so much "do I want to have both references", my question was, do I need both WSDL references?  I'm trying to first understand the correct solution, I haven't picked one cause I'm not sure which way to go.  This can't be that extraordinary of an issue.  I would assume many 3rd parties have this sort of architecture.  

I think my preference would to not use both in order to prevent having redundant code.  But again, I don't know what issues this would cause, if any.  I guess maybe this part is a PayPal question and I am waiting for a response from them.  They do have versioning too that is specified in the call so you would think that is even more of a reason you could get away with using one WSDL definition and different endpoints, no?

If it turns out that both references are definitely needed, then I will revisit your last post on how to handle this.  It seems your example is for placement in the calling method that is using the DoDirectPayment() method.  But my issue is actually inside the PaymentBL class on how to implement a class and methods using both references.  
0
 
LVL 75

Accepted Solution

by:
käµfm³d   👽 earned 500 total points
ID: 34980199
Part of you confusion may stem from the use of the term "reference". There is not an actual reference (like you would have in a Forms project); rather there is a conversion of the WSDL into a class or set of classes which can inter-operate with the service. Web services are designed to be architecture and language independent, so the internal storage of data should be irrelevant. What I was trying to imply above is that the "data type" the service cares about at its exposed point is that described by the XML (e.g. xs:string, xs:int, etc)--it doesn't know if you store it internally as an int, string, Point, Rectangle, etc. Just as you store your data in some class(es), the backend of the service stores its data in a structure familiar to it.

In short what I am saying is that if the XML types and namespaces are the same for both services, and that your internal storage (which should have been generated for you when you added a service reference to the WSDL) can safely be converted to those types (which it should since .NET did the class creation for you), then I don't see a reason why you would need a reference to both services. You should be able to use the same classes for each service and just change the endpoint as necessary.
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Here I am going to explain creating proxies at runtime for WCF Service. So basically we use to generate proxies using Add Service Reference and then giving the Url of the WCF service then generate proxy files at client side. Ok, what if something ge…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…
Attackers love to prey on accounts that have privileges. Reducing privileged accounts and protecting privileged accounts therefore is paramount. Users, groups, and service accounts need to be protected to help protect the entire Active Directory …

679 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question