I've built a service and corresponding data model in c#. A third party wants to integrate with service. I'm required to provide xsd-schema.
The "xsd" tool in VS does the job but somehow namespaces is lost in the process. Is it possible to include the namespaces I've defined on my classes(using the DataContract tag) using the xsd-tool? Is there other tools out there to convert a .cs model to xsd?
Update:
The service is rest api based on json used by serveral client. This issue arrised when I wanted to integrate biztalk with this api. I could manuanly add namespace but this is tedious as it's a huge service contract that change alot.
Based on the suggestions from #dbc svcutil turned out to be the solution. Using the datacontract only flag I was able to generate service model containing correct namespace references.
Related
I have a Windows UWP client application that needs to call a REST API hosted by my ASP.NET service. To generate my client proxy I use the following Visual Studio option...
Right click project -> Add -> REST API Client...
I provide the URL of the swagger endpoint and it generates the expected client code. But the downside is it generates all the classes even though in my case I have a shared class library that has all the server side classes defined. This is a pain because the generated classes do not respect the inheritance of my class hierarchy and flattens everything into non-inherited classes.
Is it possible to get AutoRest to reuse an existing .NET library for classes instead of always generating new classes? This was an option when I used the WCF client proxy generator.
It seems like Add REST API client doesn't have advanced setting for reusing. But Add REST API client has two ways for loading metadata file, swagger URL and existing metadata file. By testing on my site, it should be able to update an existing metadata file and to remove or adjust the nodes that you don't want be generated. And then load the updated existing metadata when adding REST API client.
The classes generated may be determined by the metadata json file and the host value. You may also try to submit a request here to see if swagger team can keep the hierarchy when generating the meta file. Or you may need to manual create the proxy to reuse the libraries.
I think it would be fair to describe the "REST API Client" generation tool in Visual Studio as "spartan".
This answer may be too late to help you, or there may be reasons why you can't use a different tool, but in the hope of benefiting you and/or future readers I'll detail how I achieved generating a REST client in NSwagStudio which reuses my existing classes and enums. (NSwagStudio is free and open source, and I have no affiliation).
On the left hand pane, we select our input. Besides the expected Swagger feeds there are some interesting options such as "Web API via reflection" which "uses .NET reflection to analyze ASP.NET Web API or ASP.NET Core controllers" - this is the option I used but my screenshot shows the default Swagger input.
On the right hand pane, click "CSharp Client" and switch to the "CSharp Client" tab.
The magic bullet is to untick "Generate DTO types":
This will cause it to generate only the client, so you can reuse your existing DTOs.
You'll want to specify a namespace for the client, and optionally one or more namespaces which will be added to the generated C# file as using directives. For example, if you want your client to be in the namespace MyNamespace and your model classes are in SomeOtherNamespace you'd enter the following:
It's well worth having a play with the options. A few quick notes about some of the defaults and why I'm happy with them:
The HttpClient is injected and you control the lifecycle (which seems to me a good thing)
A BaseUrl property is defined. I haven't tested this yet but I'm hopeful from looking at the generated code that this will allow me to safely spin up multiple instances of the client class to talk to multiple servers which share the same API
The JsonSerializerSettings property is protected, but can be configured via the UpdateJsonSerializerSettings partial method
I've saved my settings from the File menu and added the .nswag file to source control, so that I can easily regenerate the client in future if necessary.
I have been following this tutorial to add protobuf-net to my WCF project. I have a shared DTO library. Both server and Client use those DTO classes. I have attributed all my Service methods with [OperationContract] attributes, but i have not assigned any [DataContract] attributes on my DTO classes.
I added the protobuf-net Nuget package and added the configuration to the web.config.
I am using IIS Express to test my service, and thought that i should be ok with what i had done so far. However, after testing a few calls, i noticed that i forgot to add protobuf-net to my client and yet everything worked as expected (ie. no errors from serialization or deserialization).
I suspect that protobuf is not used in my program at all, and that i am missing something. I'd like to avoid using [DataContract] attributes but i could live with adding them, if that is what is need to get protobuf-net working.
What else am i missing?
A year ago I faced the same problem, where protoBuf seems to be an excellent option, with WCF it has some shortcomings.
I created an open source project to overcome these shortcomings, it uses protobu-net library and adds functionality to it, such that you don't need to share assemblies anymore with client. It however again requires you to put DataContract attributes though currently.
You can give it a try: https://github.com/maingi4/ProtoBuf.Wcf
DISCLAIMER: I am creator and owner of the above project.
Here is my issue: in a project I have to consume 3 third-party wcf services. 2 of those contain the same objects and largely the same methods.
The user's role within the application determines which service to use. For example: Let's say the 2 services are ServiceRoleA en ServiceRoleB. Both services contain the method GetInfo() end return the InfoDetails object. The InfoDetails object has the exact same signature for both services.
If I just add 2 service references to my project I'll get the objects ServiceRolaA.InfoDetails and ServiceRoleB.InfoDetails. Instead, I need just one object InfoDetails. I only want to write just one routine to handle the InfoDetails etc.
My initial thought was to create an assembly with the datacontracts of the services and reference the assembly in my project. This way the service references can use the common set of objects. For this to work I have create the datacontract classes using svcutil and the wsdl, but I get error upon error.
When I try the following:
svcutil *.wsdl /dataContractOnly /n:*,DataContracts
/language:C# /out:XxxData.cs
I get the following error:
"Error: Type 'AuthenticationBase' in namespace 'http://schemas.datacontract.org/2004/07/xxx' cannot be imported. It references 'KindOfModule' from namespace 'http://schemas.datacontract.org/2004/07/yyy' but schema does not contain appropriate statement. Either change the schema so that the types can map to data contract types or use ImportXmlType or use a different serializer.
If you are using the /dataContractOnly option to import data contract types andare getting this error message, consider using xsd.exe instead. Types generatedby xsd.exe may be used in the Windows Communication Foundation after applying the XmlSerializerFormatAttribute attribute on your service contract. Alternatively, consider using the /importXmlTypes option to import these types as XML types to use with DataContractFormatAttribute attribute on your service contract."
Exporting the datacontracts as XML types is no option for my so the next thing to try was:
svcutil *.wsdl /dataContractOnly /n:*,DataContracts
/serializer:XmlSerializer /language:C# /out:XxxData.cs
Which resulted in the exact same error. So I decided to try the other mentioned option to use XSD.exe. But that is also nog working since I only have a WSDL and XSD.exe requires a XSD file. Are there any more options I can try? Please help!
You don't need to add service references or using svcutil to create the client proxies, that is easily done by hand.
Create a contracts assembly that contains all service interfaces and data contracts.
Reference that assembly from both the server(s) and the client (be sure to update the web.config and .svc files to reflect these changes)
Create client proxy classes for your services.
A client proxy is as simple as adding a class like
public class ServiceRoleAClient : ClientBase<IServiceRoleA>, IServiceRoleA
{
public InfoDetails GetInfo(GetInfoRequest request)
{
return Channel.GetInfo(request);
}
}
The only drawback is that you'll have to maintain the system.serviceModel node in the app.config file yourself.
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.
We have several .Net webservices that we use a java client for. Each webservice has it's own namespace, but they all use a lot off common classes. When these are exposed as WSDLs, then generated into Java code, we get a lot of duplicates in Java of the same .Net classes.
Is there a way in .Net to define a set of WebService objects to be exported under a shared namespace (in XML)? Or can we when we use wsimport in Java to generate just one instance of each duplicate class?
From service side, one of the option could be to have specially crafted single WSDL describing all services. See this article for how to do it (applicable for asmx services).
On side note, for .NET clients, its quite simple to use wsdl tool with sharetypes options to have common types generated once and re-used among multiple service proxies. Hopefully, similar tools/options perhaps exist at java client side.
The -p option of wsimport allows you to override the namespace specified in the WSDL to a package that you specify. If you specify the same package for each WSDL you'll only end up with one instance of each class.