Question

I'm currently preparing to consume a SOAP web service in a .NET project (C#), however the naming conventions used for the service types and operations are pretty bad not consistent with the naming conventions typical to C# .NET projects.

My question, essentially: is there a way to auto-alias the generated SOAP web service proxy types/methods in my client implementation?

I'm hoping that there's some way to perform a transformation of the WSDL with a map of aliases, such that the generated (or regenerated) types use names such as Contact but map to the underlying contactObject definition.

Since I'm unaware of any transformations that could be performed during generation, I'm currently looking at manually (or at least with the assistance of a T4) writing wrappers for the classes, however this seems like an unnecessary level of indirection; not to mention, a pain in the ass.

I'm reading through the docs on Svcutil, but haven't found any applicable flags.

Was it helpful?

Solution

I had posted this to your other question but you are right, it's better suited to this one:

I assume that you are consuming this third-party service by adding it with "Add Service Reference...", which auto-generates some code for each class in a Reference.cs, with signatures that might look something like this:

[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://www.thirdpartyguys.net")]
public partial class qux: object, System.ComponentModel.INotifyPropertyChanged {

And you wish that instead of qux, it said Qux. If this is all similar to your model so far, then you can just change qux to Qux, but add TypeName="qux" to the XmlTypeAttribute, and change all references to this class within the reference. This maintains the correct xml schema in the SOAP, but let's you change the name within your project:

[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://www.thirdpartyguys.net", TypeName = "qux")]
public partial class Qux: object, System.ComponentModel.INotifyPropertyChanged {

And of course, if that XmlType attribute is not already on the class to define the namespace, you can add it. It just won't have the Namespace parameter. I tested this just now it does allow me to use the service and simply call an object by a different name everywhere that I use it.

Will this work for you?

Edit: (To brief future readers on the SchemaImporterExtension idea) As I understand it, this extension class can invoke a deviation from the default code generation behavior when a Service Reference is added from a WSDL. You still end up having some Reference.cs that acts as the link between your project and the Service, but you can change what is generated. So if we want the objects to always begin with a capital letter, for example, I think the idea is to do something like this (untested):

public class test : SchemaImporterExtension
{
    public override string ImportSchemaType(string name, string ns, XmlSchemaObject context,
        XmlSchemas schemas, XmlSchemaImporter importer, CodeCompileUnit compileUnit,
        CodeNamespace codeNamespace, CodeGenerationOptions options, CodeDomProvider codeGenerator)
    {
        if (name[0].CompareTo('a') >= 0) //tests if first letter is lowercase
        {
            CodeExpression typeNameValue = new CodePrimitiveExpression(name);
            CodeAttributeArgument typeNameParameter = new CodeAttributeArgument("TypeName", typeNameValue);
            CodeAttributeDeclaration xmlTypeAttribute = new CodeAttributeDeclaration("XmlTypeAttribute", typeNameParameter);
            compileUnit.AssemblyCustomAttributes.Add(xmlTypeAttribute);
            return name.Substring(0, 1).ToUpper() + name.Substring(1);
        }
        return null;
    }
}

This, in theory, will write in the XmlType Attribute and change the name to the correct casing, thus maintaining the correct XML mapping in the SOAP. The advantage in using SchemaImporterExtension, in theory, is that updates to the service reference will not overwrite the changes. Also, changes can be made generically rather than to each specific reference.

Comments or edits from people who have used SchemaImporterExtension successfully are welcome.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top