Can I automatically change the name of the autogenerated wcf proxy? - c#

When I add a Service Reference to my project in Visual Studio, it autogenerates a proxy to the service called ServiceNameClient. I really don't like that naming scheme. Is there a way to change it to something like ServiceNameProxy?
I can rename the class myself in the autogenerated code, but any time I add new features to the service, and go to UpdateServiceReference, it re-generates the code and changes it back to the old name.
My brief web search uncovered a way to create my own WCF Proxy Generator class, but I'm hoping there is some simple attribute that changes how the class name is calculated.

Like you, I have been dissatisfied with Visual Studio's code generation of the WCF service reference. I never have liked the naming scheme, and I also don't want to change it every time I update my service.
To answer your question, I don't know if there's a way to change it or not. But I had an epiphany after watching this video at dnrTV. Since then, I've been manually coding my WCF client proxies using a naming scheme that fits my project.

Related

Using a MetadataType with WCF

I have an auto-generated WCF Client and I thought that I would be able to add Data Annotations by using a partial class and adding a Metedatatype attribute to it. Seemingly this will not work; as I have seen from other posts the MetadataType needs to be registered and I have tried this approach but with no success.
Validation works if I place a validation attribute directly on the field, and maybe I should do this and manually create the client DTOs, but I was wondering if anyone out there knew of a way to get this working.
I will happily post some code if people think it will help.
Thanks.
Create in your solution another project (let's call it "SolutionName.Infrastructure") responsible for storing DataContracts and ServiceContracts. Then in your service and client projects add reference to Infrastructure project. Such a solution declines the amount of code being created since now you store all code in one place depriving of auto-generated code. You can effortlessly leverage of DataAnnotations. The downside is that you need to adjust app.config file on client side manually.

WCF - regenerate client code from interface contract

I have quite simple WCF service and its client - both reside in my application.
At the moment interface used for WCF contract consist of 3 methods, and according to MSDN I generated client code for it using svcutil.exe CLI.
But now I added one more method. And I wonder - is there a simpler way to regenerate client code (probably directly in VisualStudio) using doing less actions for this operation?
Right click on your Services References and select the service you'd like to regenerate code for. Then click Update Service Reference. Then you're done.
Update after re-reading the question I realized its possible you don't know how to import WCF Services.
Here is how its done:
Update as per comments:
There are two workarounds for this, The first is to run the application outside of your IDE and then go into your IDE to import it.
The second one is to create a proxy client that implements your service contract. When you are using the client proxy you can right click on the interface and select an option to implement the interface. Assuming that the set up is done correctly, if you make a change to the ServiceContract you can then go to your proxy class and just click implement interface which will update your proxy class. by doing this you bypass the svc utility completely; however, you have significantly more control over your development. You need to work with DLLs to accomplish this; however, it works like a charm. Here is an example though I doubt you need one I'll just leave it for the sake of completeness. Use this example for duplexes

how to handle redundant classes used in web services

I've started using some web services that have a staggering amount of redundancy when added as web services in Visual Studio 2012. Here are two WSDLs that demonstrate this:
http://webservices.sabre.com/wsdl/sabreXML1.0.00/usg/SessionCreateRQ.wsdl
http://webservices.sabre.com/wsdl/sabreXML1.0.00/usg/SessionCloseRQ.wsdl
These are services to create a new session and to close it, respectively. Each service has its own MessageHeader class, which in turn has a member that's from a MessageData class that's redefined in every generated proxy. There are others like this but I won't name them all.
This makes it difficult when I want to create a helper function that sets up my request and fills in all the common stuff in the envelope such as timestamps, authentication, etc. because Service1.MessageHeader is not the same type as Service2.MessageHeader. I've experimented with duck typing, but as far as I've seen the nested nature of this would prevent that approach.
Looking at the WSDL, these classes are all defined as being from the same namespaces. In other words, in both WSDLs, MessageHeader is defined as:
<xsd:import namespace="http://www.ebxml.org/namespaces/messageHeader" schemaLocation="msg-header-2_0.xsd"/>
...
<part name="header" element="eb:MessageHeader"/>
Is there some way to make VS understand that these are the same thing in both classes and somehow get it to separate them out as common to both? Or is it "a web service is an island"? I'd really rather not have to create separate code for every single type of web service I'll need, as there are far more than just these two. But every one of them uses these same classes.
I've thought about going in and hacking up the proxy classes by hand. But beyond my fear that this would make VS slip some gear because I'd messed up what it was doing behind the scenes that it never expected me to tinker with, I'd lose the whole auto-generation should something change in the WSDL that needed resyncing.
I've tried this both in C# and in Oxygene and run into the same issues. I imagine it'd be the same in other languages under VS. It seems related to how it understands WSDL.
Before anyone asks, I can't change anything about the actual web services. That is another company altogether, and not one that will be interested in redesigning their widely used system based on my whims.
I've found a potential solution to this, and it works in every way I can tell. But I'm open to criticisms or "a better way" (including a better way to do it from the GUI).
I've found that using the following command generates the proper "single unit" type of interface I want with all the types shared:
wsdl.exe /sharetypes /language:CS "http://webservices.sabre.com/wsdl/sabreXML1.0.00/usg/SessionCreateRQ.wsdl" "http://webservices.sabre.com/wsdl/sabreXML1.0.00/usg/SessionCloseRQ.wsdl" /o:"SabreWebServices.cs" /n:SabreWebServices
That creates a C# one. For Oxygene, I use:
wsdl.exe /sharetypes /language:OXYGENE "http://webservices.sabre.com/wsdl/sabreXML1.0.00/usg/SessionCreateRQ.wsdl" "http://webservices.sabre.com/wsdl/sabreXML1.0.00/usg/SessionCloseRQ.wsdl" /o:"SabreWebServices.pas" /n:SabreWebServices
FWIW, I used the wsdl from the "c:\Program Files\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools directory on my machine.
I added the resulting wrapper file to my application and it worked perfectly, if a bit differently than the wrappers created through Add Service Reference. I actually prefer the syntax this created a bit more. It also had the benefit of creating only the one file rather than numerous ones and not mucking with app.config. If you want to change the endpoint, you can just set the Url property of whichever service you instantiate.
I arrived at this solution at this post this via this post.

WCF another best practice?

Ok so I have built my WCF service and its functioning great! However, I am starting to implement it into our pre-existing piece of software now and I am instantly running into the question, do I only use the proxy generated code and get rid of the dll that I used initially? Or do I keep both, and make distinctions between the two very obvious?
What I mean by keeping distinctions is, having a ServerUser and a LocalUser property that represent the same user object. However, my LocalUser property would be filled via the dll that the app initally ran with, if the application service is unavailable.
My main reasoning for this thought pattern is that if I remove my dll, I have a single point of failure. If for some reason my ServiceHost is just not up and running, but the DB server is, I would want my users to still be able to do their job. The features that the new WCF implementation utilize are not dependant for employees to do their job. It is more of a convenience in what the WCF service provides. Also, building in this kind of logic to the Service would allow service modifications more readily available in a non IIS hosted environment.
Also, is there a way to build in logic on the service so that when I pull down the proxy code for the client that it just knows to access the DB manually if the ServiceHost is unavailable? If this was a possibility, I think about 90% of all my problems would disappear.
Thank you in advance!
From what you describe it sounds like keeping your existing DLL, i.e. direct access to the DB, would best suit your needs. Having a WCF service adds nothing if, when it fails, you'll just use the DLL anyway.
Ideally you would go with the WCF service completly and offer some kind of redundency to deal with any potenial service issues. Plus, using a service will mean you won't have to deal with any DLL upgrades/deployments.
But, from your question, it sounds like there would be some real issues to deal with should the service not be available, so just do with the DLL.
EDIT: Just read the last part of your question and I don't think that is possible. The proxy code for accessing services is generated when you add the reference to your project. The kind of "dynamic" information you're after would actually require a service.
EDIT: As a follow up to my comment below you could test this by creating a DLL and class, lets call it Class1. Then create a WCF service with a method that will return Class1. Create a client application and add a reference to the service. If you look at the proxy-generated code you should see (hopefully...I'm thinking of this as I type :)) that the method returns Class1, but when you compile it won't be able to find Class1. This is because Class1 does not have the DataContractAttribute which would auto-generate Class1 on the client. So, you have to distribute the shared DLL to the client. Now when the method returns and WCF tries to re-create Class1 it will use the local version in the shared DLL. Your other DLL, which will already be on the client, would use the same shared DLL.

Create WCF Client without auto generated proxy

looking at
WCF ChannelFactory vs generating proxy
appears that the best practice in creating a WCF client is to create a proxy (Not autogenerated).
I've been looking online for a while and i didn't find any complete example(Proxy class, web.config)
Could you provide an example or links to resources?
This article is about exactly what you're asking, I believe:
WCF the Manual Way... The Right Way
Having shared that, though, creating your proxies manually is probably not always the best possible use of your time. The article goes into some great reasons for doing so - you'll certainly have more control, your clients may have an easier time, etc. but overall, doing things manually like this will require more of your time, and explaining to users of your service exactly how to use the proxy you provide may be a pain.
There's a reason WCF allows metadata exchange and discovery and VS will auto create proxies for you.
Either way, it's a cool article and a technique well worth learning.
This is how I do it.
Get service contracts and data contracts
If I have access to the service code, I have all the contracts. If not, I can use svcutil or Add Service Reference to generate them.
Make config
I use Add Service Reference just to get the app.config file. I then delete everything else it generates. Edit the app.config as necessary.
Define factory
Say I have a service contract IFooService:
interface IFooServiceChannel : IFooService, IClientChannel { }
That is literally it. No members.
Create factory
fooServiceFactory = new ChannelFactory<IFooServiceChannel>(
"NetTcpBinding_IFooService");
The string "NetTcpBinding_IFooService" is the name attribute of the binding element in app.config.
Create channel
fooService = fooServiceFactory.CreateChannel();
Use it
fooService.DoSomething();
The trickiest part is getting app.config right. You need to learn about bindings and endpoints. It's a bit of a learning curve, but nothing drastic.
Here are the basic steps.
Create your service like normal.
Move the interface that your service implements into an assembly that can be shared with the client.
Create a ChannelFactory where T is your interface. You will have to give the uri of your service to the constructor.
Call factory.CreateChannel(). This will be type T.
Use the channel to make calls.
It is really that simple. No auto generated code, no service references. It gets a little more complicated with async calls and Silverlight, but not too much.

Categories

Resources