FancyWsdl post-processes C# proxy code for WSDL service definitions generated by tools such as wsdl.exe
, svcutil.exe
, or Visual Studio > Add Service Reference and introduces the following enhancements:
- Make it possible to rename types and members
Your tool-generated webservice code does not conform to the naming standards from the app in development? The service does not work anymore after renaming properties? FancyWsdl adds corresponding XML serialization attributes so you can rename types and members. - Apply C# naming conventions (PascalCase)
Web service definitions (and the generated code) often doe not conform to the C# naming standards. FancyWsdl introduces Pascal casing for types and members. - Insert documentation (
summary
tags)
How to generate .NET classes with comments from WSDL and XSD? There are some XSDs and WSDLs containing WSDL documentation (annotation), but tools such aswsdl.exe
orsvcutil.exe
do not generate XML-comments from XSDs annotations? FancyWsdl allows you to turn those WSDL comments to XML comments in the generated proxy code. - Clean up code
FancyWsdl introduces autoimplemented properties, adds using directives, and use attribute shortcuts.
- Generate C# proxy classes from WSDL file, e.g.
wsdl.exe https://example.com/ExampleService/?wsdl
svcutil.exe https://example.com/ExampleService/?wsdl
- Visual Studio > Add Service Reference
- Run FancyWsdl on generated code,
e.g.FancyWsdl.exe ExampleService.cs
- 1st command line parameter: path to C# file with generated proxy classes
If your service definition has annotation
/documentation
elements, FancyWsdl can create appropriate summary tags in your C# code:
- Run FancyWsdl on generated code and pass service definition(s),
e.g.FancyWsdl.exe ExampleService.cs https://example.com/ExampleService/?wsdl https://example.com/ExampleData.xsd
- 1st command line parameter:
- 2nd command line parameter(s): url to XSD or WSDL service definitions (containing
documentation
elements)
Sample output:
With FancyWsdl post-processing (after) | Raw proxy code (before) |
---|---|
/// <summary>
/// Bundles parcel information type data.
/// </summary>
[GeneratedCode("wsdl", "4.8.3928.0")]
[Serializable]
[DebuggerStepThrough]
[DesignerCategory("code")]
[XmlType(Namespace = "http://dpd.com/common/service/types/ShipmentService")]
[XmlRoot("parcelInformationType")]
public partial class ParcelInformationType {
/// <summary>
/// The parcel label number of the corresponding parcel.
/// </summary>
[XmlElement("parcelLabelNumber", Form = XmlSchemaForm.Unqualified)]
public string ParcelLabelNumber { get; set; }
/// <summary>
/// The DPD reference for this parcel.
/// </summary>
[XmlElement("dpdReference", Form = XmlSchemaForm.Unqualified)]
public string DpdReference { get; set; }
/// <summary>
/// The content for the parcel.
/// </summary>
[XmlElement("output", Form = XmlSchemaForm.Unqualified)]
public OutputType[] Output { get; set; }
} |
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.8.3928.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://dpd.com/common/service/types/ShipmentService")]
public partial class parcelInformationType {
private string parcelLabelNumberField;
private string dpdReferenceField;
private OutputType[] outputField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string parcelLabelNumber {
get {
return this.parcelLabelNumberField;
}
set {
this.parcelLabelNumberField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string dpdReference {
get {
return this.dpdReferenceField;
}
set {
this.dpdReferenceField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("output", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public OutputType[] output {
get {
return this.outputField;
}
set {
this.outputField = value;
}
}
} |
-
Property name in
XmlElementAttribute
(so it's possible to rename the property) & pascal-case property nameBefore:
[XmlElement(...)] public string delisId { ... }
After:
[XmlElement("delisId", ...)] public string DelisId { ... }
-
Autoimplemented getters & setters
Before:
private string delisIdField; public string DelisId { get { return this.delisIdField; } set { this.delisIdField = value; } }
After:
public string DelisId { get; set; }
-
Nullable value types
Before:
[XmlElement(...)] public int DateFrom { get; set; } [XmlIgnore] public bool DateFromSpecified { get; set; }
After:
[XmlElement(...)] public int? DateFrom { get; set; } [XmlIgnore] public bool DateFromSpecified => this.DateFrom.HasValue;
-
Method name in SoapDocumentMethodAttribute (so it's possible to rename the method) & pascal-case method name
Before:
[SoapDocumentMethod(...)] public storeOrdersResponse storeOrders(...) { object[] results = this.Invoke("storeOrders", ...); return ...; }
After:
[SoapDocumentMethod(..., RequestElementName = "storeOrders", ResponseElementName = "storeOrdersResponse")] public storeOrdersResponse StoreOrders(...) { object[] results = this.Invoke(nameof(StoreOrders), ...); return ...; }
-
Enum values in XmlEnumAttribute (so it's possible to rename the enum value) & pascal-case enum value
Before:
public enum productAndServiceDataOrderType { consignment, [System.Xml.Serialization.XmlEnumAttribute("collection request order")] collectionrequestorder, /// <remarks/> [System.Xml.Serialization.XmlEnumAttribute("pickup information")] pickupinformation, }
After:
public enum productAndServiceDataOrderType { [XmlEnum("consignment")] Consignment, [XmlEnum("collection request order")] CollectionRequestOrder, [XmlEnum("pickup information")] PickupInformation, }
-
Type names in XmlRootAttribute (so it's possible to rename the type) & pascal-case type
Before:
public partial class parcelInformationType { ... }
After:
[XmlRoot("parcelInformationType")] public partial class ParcelInformationType { ... }
-
Documentation from XML schema
Before:
/// <remarks/> public partial class ParcelInformationType { /// <remarks/> public string ParcelLabelNumber { get; set; } /// <remarks/> public string DpdReference { get; set; } /// <remarks/> public OutputType[] Output { get; set; } }
<schema ...> <xs:complexType name="parcelInformationType"> <xs:annotation> <xs:documentation>Bundles parcel information type data.</xs:documentation> </xs:annotation> <xs:sequence> <xs:element maxOccurs="1" minOccurs="0" name="parcelLabelNumber" type="xs:string"> <xs:annotation> <xs:documentation>The parcel label number of the corresponding parcel.</xs:documentation> </xs:annotation> </xs:element> <xs:element maxOccurs="1" minOccurs="0" name="dpdReference" type="xs:string"> <xs:annotation> <xs:documentation>The DPD reference for this parcel.</xs:documentation> </xs:annotation> </xs:element> <xs:element maxOccurs="unbounded" minOccurs="0" name="output" type="tns:OutputType"> <xs:annotation> <xs:documentation>The content for the parcel.</xs:documentation> </xs:annotation> </xs:element> </xs:sequence> </xs:complexType> </schema>
After:
/// <summary> Bundles parcel information type data. </summary> public partial class ParcelInformationType { /// <summary> The parcel label number of the corresponding parcel. </summary> public string ParcelLabelNumber { get; set; } /// <summary> The DPD reference for this parcel. </summary> public string DpdReference { get; set; } /// <summary> The content for the parcel. </summary> public OutputType[] Output { get; set; } }
-
Use usings & attribute shortcuts
Before:
using System; using System.ComponentModel; using System.Diagnostics; using System.Web.Services; using System.Web.Services.Protocols; using System.Xml.Serialization; [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.8.3928.0")] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Web.Services.WebServiceBindingAttribute(Name="ShipmentService_SOAP")] [System.Xml.Serialization.XmlRootAttribute("ShipmentService")] public partial class ShipmentServicePublic : System.Web.Services.Protocols.SoapHttpClientProtocol { ... }
After:
using System; using System.CodeDom.Compiler; using System.ComponentModel; using System.Diagnostics; using System.Threading; using System.Web.Services; using System.Web.Services.Description; using System.Web.Services.Protocols; using System.Xml.Schema; using System.Xml.Serialization; [GeneratedCode("wsdl", "4.8.3928.0")] [DebuggerStepThrough] [DesignerCategory("code")] [WebServiceBinding(Name="ShipmentService_SOAP")] [XmlRoot("ShipmentService")] public partial class ShipmentServicePublic_4_3 : SoapHttpClientProtocol { ... }