web reference : How to change proxy class code - c#

i'm using web reference to consume a web service the problem is with a decimal attribute which is optional , its value is not passed the web service. i tried to add default attribute and give it a default value it works fine , but i can not change my wsdl because i have differenet clients working with it (php,java ... clients)
The problem is well described here : msdn post
stackoverflow post
So i want to find a way to change the code of the proxy class generated after the creation of yhe web reference , because i'm sure it's a bug caused by this class which treats optional decimal attributes wrongly .

Solution 1:
Go to your project folder -> Web References -> MyService.
In there, there should be a file called Reference.cs ... that's the file that is created. It contains proxy classes for the webservice.
Also, if you don't want to mistakenly update the reference and delete your changes to the file, update the reference in the csproj file. On the bottom of the project file, you'll find url's to all services you're using. Point it to the WSDL in the same folder.
Solution 2:
Add the service reference to your project
Change your project file and update the url of the service, point it to the wsdl in the same folder as in solution 1
Make the necessary changes to the wsdl in the same folder
Update the reference in VS ... this will create a new Reference.cs ... it will update the proxy classes
NOTE: Depending on the changes made to the WSDL, it might be the web service on the other side might not be able to 'read' your messages. Making a property obligated instead of optional should not break it though.

Related

Changing the url in WSDL generated interface

To start off, i have never coded a SOAP web request before in my life so this has been a learning curve of note.
I am busy writing a service that will make a soap request to a SageX3 web interface in C#. Net (obviously using Visual Studio). We already have similar request on another service that is supposedly working and I am using that as a reference. So took the (supposedly) same wsdl file and created a connected service reference that generated the Reference.cs file which should be the interface I must use to this soap request. But this request url uses a default url that I do not seem to be able to change. I have looked through the class definition and the properties in the interface like "endpoint" and such all seem to be read only. So I looked in the other project how that Refenrence.cs file looks which is completely different. The first part of my generated reference.cs looks like this:
Newly created reference.cs header:
If you look at the original reference.cs file, it is vastly different:
Original created reference.cs header:
What I notice is that the original has public class that also inherits from SoapHttpClientProtocol that will allow the user of that class to setup the url as reqiured. I do not have that option as my generated code is straight up an interface.
This brings me to my question, could it be that I have an invalid wsdl file or working from a different file as the original code?
Was the code generated differently as there might be a different tool used in Visual Studio?
Did the original author make changes to the reference.cs after it was generated? I think this is a possible answer that I need to add a class definition in the reference.cs file.
Or am I on the completely wrong track here.

Adding Service Reference to WCF does not always create .datasource files

In some projects when I add a service reference to a WCF service, it creates datasource files for classes shared in a common class library, however in others the datasources are not created. The Reference.cs file is different where in the first case the types are from the class library and in the latter it's in the Reference.cs file it self. These are not compatible.
What is it that triggers the automatic generation of the datasource files in this case? Advanced options in Add Service Reference dialog are identical so something else must be playing tricks on me.
UPDATE: Turns out the datasource files are not needed. It's the code generated in the Reference.cs file that makes the whole difference. I can manually edit the parameters for the methods to point to the class-library, and it works. This is of course not a solution in the long run, since I have to do this every time I update the Service Reference. Hopefully someone will come along who knows the trigger of this problem.
The file is created by VS when you add a service reference. It's used to enable client UI components to bind to the models (data contracts). I don't know why they are not created for "all" services (but I guess it depends on how that service defines and uses data contracts (as in: no contract no data file)).
Here are some useful links:
https://msdn.microsoft.com/en-us/library/ee373840.aspx
What are the WCF Service Reference .datasource files?
UPDATE: You are right it should not depend on the consumed service. Here are two related links (that impliece that the files are included by VS):
http://objectmix.com/dotnet/797048-wcf-service-reference-datasource-file-name-length-problem.html
Disable automatic generation of datasources file when updating service references
So it looks like the file is created by VS, if you don't wan/need it you can exclude it by creating the proxy with svcutil.exe

is there a way to automatically update proxy object when updating service on WCF?

i have a WCF web service that i'm working on. currently every time i'm changing the contracts in my service at the server side, i need to both update the service reference and regenerate the proxy object used by the client with "svcutil.exe". is there anyway to do both automatically? i once saw someone who generated the client inside the reference.cs file but i have no idea how he did that. I'm using visual studio 2010.
so far all i have found was different msdn references telling me to use the svcutil. its not intuitive and usually i can find easier solutions than cmd when working with VS.
If you want to automate your development work, learn command line and svcutil.exe.
You should use svctuil.exe to generate wsdl and proxy classes which go into a project called something like "MyService.ClientApi". To make thing easier, used a batch file to be called in the build event of the service project.
For more details, please read http://www.codeproject.com/Articles/627240/WCF-for-the-Real-World-Not-Hello-World
After reading this CodeProject article, you should be able to create respective batch files, and call them in the build events.
And you will see the beauty of separating contracts and implementation into 2 projects.
Say, you will have
MyServiceContracts.csproj with CreateWsdl.bat to be called in the post build events
MyServiceImp.csproj
MyServiceClientApi.csproj with CreateProxy.bat
You can make CreateWsdl.bat call CreateProxy.bat. So everytime you make changes in the contracts, you will have new Wsdl/XSD file to be published, and new MyServiceClientApi.dll to be used by all client programs.
You can right click the "Service References" in your Visual Studio project and select "Update service reference". This will update your proxy class and the configuration file.
If you are willing to forgo the use of auto generation, you can construct your service contracts classes manually (go ahead and use reference.cs as a starting point) and then build as a separate assembly that can be shared between the client and server. Propagation of any later change will then happen automatically as you want whenever the contracts assembly is rebuilt.
Solved. Apparently i had to uncheck the reuse types in reference assemblies checkbox, and there was no more difference between the file generated by svcutil and the reference.cs file. I want to blame Microsoft but it really makes sense. Damn. Thanks a lot everyone

Project structure for Schema First Service Development using WCF

I have WSDL and XSD as starting point. (WSDL is generated from XSD using WCSF Blue tool). From the WSDL, using a tool, the service code is generated. The project name is “Autogenerated_Service_Project”. Inside this project it will have [ServiceContract] and [DataContract] classes. It has a data contract named “EmployeeDataContract”. In the GetEmployee() service operation, this datacontract is returned to the client.
I have a business layer project named “Business_Project”. It has a method that returns “Employee” entity object.
At present, I am referring the “Business_Project” inside “Autogenerated_Service_Project”.
Business_Project.MyClass b = new Business_Project.MyClass();
EmployeeDataContract d = b.GetAssociate();
return EmployeeDataContract;
The challenge comes when there happens a change in WSDl. When the WSDL is the changed the “Autogenerated_Service_Project” will be recreated and the code mentioned above will be lost.
What is the solution to overcome this code lose?
Note: The “Autogenerated_Service_Project” is the top most project. Ideally, it cannot be referred by any other projects.
You may change the way calling Business layer(may your solution needs additional layer)
But in simple way, you can generate the proxy once, when changes happen to WSDL
handle the changes manually,Or use the tool only for new services.
If the services on WSDL are finely grained, the solution may be applicable.
This can be resolved by using Partial Classes in a different file. The code given in the question can be moved to this new partial class file. This file will persist even if the auto generated file is re-created.

Namespaces and type resolution in C# solutions with webservices

This might get a little convoluted so please let me know if you need clarification.
I have a solution which contains the following projects
Project A - WPF application
Project B - ASP.NET application (with exposed webservices)
Project C - Class Library
Both project A and project B reference types that are located in project C, but more importantly project A makes webservice calls to project B using types located in project C.
The problem I am running into is it appears that when making webservice calls I have no way of referencing the types located in project C directly but rather need to use the types as exposed by the webservice.
Now the basic idea of why this is done I understand (obviously typically the consumer of your webservice would only have the WSDL to go from) however in my case this is an internal application (which is part of a single solution) so this is not a concern.
The biggest problem I see with continuing this approach is that any updates to the types in project C will need to be reflected in project B and then "refreshed" in project A. This seems pretty nasty to me. Surely there is a smoother path?
Am I wrong? What is a typical approach to this issue?
You may be a little confused here.
The types in Project C and the types you see when you add a reference to your web service are different.
When you added the Web Service reference. Visual Studio used svcutil.exe, read metadata from your web service (I'm assuming .asmx?) and then created proxy classes for you.
Check the types for the Web Service (they will obviously have the same names). Put your cursor on them and pres F12. It'll take you to some designer generated code.
So there is no real workaround as such. When you update your types in Project C and then Update your web services in Project B . You will have to Update Service Reference from Project A Which again uses svcutil.exe and regenerates all your proxies.
Also, this is the same way WCF Services work too.
#giddy is correct - the types exposed by the web service are different to the types contained in Project C - even though their definition may be identical. The web service exposes type information via a wsdl, which Visual Studio uses to generate proxy types.
There is a way around this - you can create an interface which declares all the methods in the web service class, and include it in your shared library. You can then skip the "Add service reference" process, and create the web service proxy with code (you will not need the proxy classes, as you use the classes in the shared library).
Either way, if you make a change to your data transfer objects or the web service class, you will need to update the client by either by requerying the wsdl using "refresh service reference", or by copying the shared library over.

Categories