views:

135

answers:

5

basically this is what's going on after researching this more.

If I try to use the type returned by a certain web service method anywhere in my test web project code such as in code-behind I get namespace conflicts because now the web project sees 2 different definitions for it. One as a proxy class in my web service reference namespace and then the original class definition in the referenced project where it's defined and its namespace

So how does one get past this? I've already tried to cast to the namespace where the class is originally defined but no luck, I keep getting errors saying it can't cast to that.

I tried putting a cast on the calls also but no luck.

Check out this video of me clicking to give you more details of code: http://www.elbalazo.net/Post/WebServiceProxyClassIssue.mp4 (be sure to press play..it doesn't automatically start if using quicktime to view this mp4)

+1  A: 

I had the same problem when working on two web services that needed to communicate about a year ago.

I believe I solved the problem by defining an interface that both of them implemented and decoupled my code that was dependent on those classes to instead use the interface. This worked out nicely.

I would give you more details but I don't I'm not sure they would be much help.

I would suggest making an IServiceAuthResponse interface and having your classes implement that interface.

Joseph
+1  A: 

It the problem is that you'd quite like to use just the one type:

With .NET 2.0 web-service proxies this is a PITA, and you need to manually port data between the two. Thankfully, this is fixed in WCF, which lets you use types (as long as they match) from other assemblies. You can do this with the /reference param to svcutil.exe, or the IDE walks you through it painlessly in VS2008.

Is switching to WCF at the client a possibility?

If the problem is the namespaces - then either fully qualify them, or use type aliasing:

using OrderDto = Some.Long.Namespace.Order;

then you can use OrderDto to represent Order - but it is only an alias, and only works for the single code file.

Marc Gravell
Boss says WCF is overkill. I disagree, especially if it fixes sh** like this.
CoffeeAddict
I tried to use type aliasing. It worked for some of the code in this code-behind but not this particular line of code when making the call to the web service method that returns that type that's in question.
CoffeeAddict
(With .NET 2.0 web-service proxies this is a PITA, and you need to manually port data between the two.) I don't really understand what you mean by that statement.
CoffeeAddict
By which I mean: you write code to translate a `Your.Original.Order` instance into a `Your.Web.Proxy.Order` - copying the properties etc. Not fun.
Marc Gravell
Clone/change-type via serialization is a possibility of course, but not *always* the best answer.
Marc Gravell
I was told that you have to create a proxy and specify a different namespace for it and then it won't conflict? But in my example didn't the web service reference already stub out the proxy for me as you can see in object browser? And the namespace is already different...it's WebServicesTesting.LitleWebService. So I don't understand what my boss is trying to tell me here. I still get conflicts even though the original class definition is in a different namespace... xxx.Litle
CoffeeAddict
Marc, are you saying I have to do more code! NO !! :). So I have to actually create a new class in my web project that's referencing this service and basically copy over the entire class definition to this new class and give it a namespace of something different?
CoffeeAddict
No that isn't what I meant. Indeed, in different namespaces they should be OK side by side, but you can't use one in place of the other; what I am saying is that if you have an instance of the "real" type, and want to pass it to the web-service, then you'll need to first shim it into an instance of the *proxy* type. You don't need to repeat the class itself.
Marc Gravell
A: 

Where ever you declare your ServiceAuthResponse objects use the full namesspace regardless of which one you are using. so something like:

Web.Project.Namespace.ServiceAuthResponse response = serviceProxy.getServiceAuthResponse();

When you need to convert one to the other, you won't be able to just do a straight cast, you will need to manually map the data across.

Dean Johnston
already tried using full namespace. Did not help it.
CoffeeAddict
what do you mean by the getServiceAuthResponse(), did you mean my equivilant WebServiceProxy.IssueDebit method which returns a ServiceAuthResponse? I don't follow you here.
CoffeeAddict
Please look at my code examples above in the links.
CoffeeAddict
+1  A: 

Take a look at SchemaImporterExtensions. Basically Visual Studio 2005/2008 has a way to override how it generates proxies for web services.

Here is a link to the article I used waaay back in the days prior to WCF.
http://www.microsoft.com/belux/msdn/nl/community/columns/jdruyts/wsproxy.mspx

Of course now I use WCF! So I don't have to deal with this anymore, but it will still work with VS 2008.

Dan
man that link is complicated, I could spend a week figuring how to use that schemaimporterextension no matter how "simple" that guy states. It's not that simple and takes time to setup and figure out.
CoffeeAddict
I hear you, and I would recommend going the WCF route. But this does work. I am using it for an old project and it does what you are looking for. To be honest it is not too difficult to setup, the article is just in depth.
Dan
but considering my problem aside...I should be able to grab that returned type without casting at all. What if a client that's not .net or a .net project that isn't referencing the project that defines that custom class? meaning I should not even have to worry about casting anything really if I'm not a .NET client consuming this web service because i would not know about that other namespace where the class was defined...I only know what's in the proxy class. This service will be consumed by a cold fusion app.
CoffeeAddict
+1  A: 

You can't do what you're trying to do. Stop right now. ASMX web services do not have this feature. Period, that's all there is to it. They never had this feature, they never will have this feature.

This lack has been corrected in WCF.


You ask how people can ever use web services (very well, thank you, for about a decade). As a learning exercise, I won't give the full answer right away. Instead, I'll ask you how you would call the web service from a Java client?

Better still, how would a customer you've never heard of call the service using a programming language you've never heard of?


The answer is that they would use the proxy classes. See Basics: How Web Services Work for details, but briefly, a client consuming the service will only see the WSDL. The WSDL describes the service in terms of XML Schema, not in terms of .NET types.


An earlier comment mentioned your boss thinks that WCF is overkill. Point him to Microsoft says: ASMX Web Services are a “Legacy Technology” and tell him that WCF is not overkill - it's the replacement for ASMX.

John Saunders
ok, so how the heck do I use a web service if I cannot even use the return custom type in a test web project? how would any client trying to use my web service cast that returned object?
CoffeeAddict
I wonder how people could use web services at all...maybe I'm just missing something about using custom returned objects such as what I'm doing. I mean nobody is sticking to straight strings, arrays, etc. when they return objects from a web service method are they? I don't get how people even used web services successfully in .NET before WCF at all if I can't do this.
CoffeeAddict
and what if I wanted to expose this method and service externally even, how the heck would I do that if the client consuming is not .NET based and has no clue about my xxx.Litle.ServiceAuthResponse namespace? Just a question off topic.
CoffeeAddict
I don't think that asmx web services were meant to be used as a service layer. Whenever this was the case I used remoting. ASMX web services better fit situations where you had interoperability between disparate apps/technologies.
Dan
@Dan: some would say that "interoperability between disparate apps/technologies" is a requirement for a service layer.
John Saunders
My boss doesn't necessarily care that WCF is newer. We pretty much move to everything else but for some reason he seems to think WCF is a better fit for if you're exposing web services or an API externally. He's tried it out and says it's a lot more work to figure out and that we're only using these web services internally for very very simple stuff. I dno't agree with him but he's my boss.
CoffeeAddict
ok, so I even tried to just use the proxy class namespace and changed that variable that you see in my code behind to be MyTestProject.WebService.ServiceAuthResponse. But when I called IssueDebit, and it came back, I moused over that variable and I was not able to see the object's content. Why?
CoffeeAddict
no idea on a java client. We're actually exposing this to a cold fusion client. I don't do cold fusion either.
CoffeeAddict
so I tried something like this and after it called IssueDebit, the variable did not have anything: [TestProject].[ServiceReference].ServiceAuthResponse debitResponse = [ServiceReference].IssueDebit(...); When it was done completing, the variable had nothing. I couldn't mouse over it with intellisense to see its content.
CoffeeAddict
@coffeeaddict: you need a new boss. He's got it totally backward. WCF is better for internal services because the same code, with only a change in configuration, can use binary transfer over TCP/IP for much higher performance, in the case where the service will only be used internally.
John Saunders
The point on the other clients is that they would not be able to use the .NET classes. So, write your .NET clients as though they were foreign - do not use the "real" .NET classes at all.
John Saunders
CoffeeAddict
it's weird, cause we move to everything else that's new. Why not WCF. Whatever.
CoffeeAddict
@coffeeaddict: I recommend you start playing with WCF yourself, and just let him "look over your shoulder". Creating a "hello, world" WCF service and client is pretty much the definition of "code and run". Some people start off looking at WCF and get distracted by all the stuff you can do with it, and don't realize that you don't _have to_ do any of that stuff. The simple stuff is very simple with WCF.
John Saunders