Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Two WSDLs, Same Definition, Different Endpoints

Posted on 2011-02-24
10
Medium Priority
?
1,258 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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 2000 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

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

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

This article is for Object-Oriented Programming (OOP) beginners. An Interface contains declarations of events, indexers, methods and/or properties. Any class which implements the Interface should provide the concrete implementation for each Inter…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
Video by: ITPro.TV
In this episode Don builds upon the troubleshooting techniques by demonstrating how to properly monitor a vSphere deployment to detect problems before they occur. He begins the show using tools found within the vSphere suite as ends the show demonst…
We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…

704 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