Skip to content

Code generated by dotnet-svcutil breaks when a type has a member called System. #5910

@aleksi-lukkarinen

Description

@aleksi-lukkarinen

The Issue

I have tried to use dotnet-svcutil 8.0.0 for generating a C# client code for a WSDL description, in which many types, unfortunately, have a property named as System. This results in code like in the anonymized code example below. That code is broken, because the argument of EditorBrowsableAttribute tries to refer to the global System namespace, but ends up referencing to the member of the type the attribute is attached to.

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")]
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
[System.ServiceModel.MessageContractAttribute(WrapperName = "Request", WrapperNamespace = "http://abc.org/wcf/", IsWrapped = true)]
public partial class Request
{
    [System.ServiceModel.MessageHeaderAttribute(Namespace = "http://abc.org/wcf/")]
    public Abc.Component System;

    public Request() { }
    public Request(Abc.Component System) { this.System = System; }
}

Using the global:: prefix in the argument would prevent this specific instance of the problem from occurring. The prefix would be beneficial in other places, too (see below).

Expected Behavior

In my opinion, a tool should do all in its power to prevent the above kind of issues from happening, no matter how unfortunate and awful some naming choice might be (and in my case, I'm not in the position to change that naming). Thus, I would expect the tool to use the global:: prefix everywhere, where any potential exist for conflicts. Thus, I would expect the tool to generate code like in the below example, in which the problem does not exist:

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")]
[System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
[System.ServiceModel.MessageContractAttribute(WrapperName = "Request", WrapperNamespace = "http://abc.org/wcf/", IsWrapped = true)]
public partial class Request
{
    [System.ServiceModel.MessageHeaderAttribute(Namespace = "http://abc.org/wcf/")]
    public Abc.Component System;

    public Request() { }
    public Request(Abc.Component System) { this.System = System; }
}

I would suggest going through the whole code generation and fixing this issue everywhere (see below).

Additional Information

Essentially the same problem but fixed in another place (?): #4215

There seems to be a flag called CodeTypeReferenceOptions.GlobalReference that could work with CodeDom. If not, then perhaps the prefixes should be appended manually.

A Type Called System

As a continuation, what would happen if there was a type called System? That could be inside some CLR namespace, and in such a case, using the global:: prefix everywhere else (than in just the single argument of the single attribute above), including namespaces of attributes and usings, might help in solving the issue, as below:

namespace Org.Abc.Dev
{
    using global::System.Runtime.Serialization;

    [global::System.Diagnostics.DebuggerStepThroughAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")]
    [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
    [global::System.ServiceModel.MessageContractAttribute(WrapperName = "Request", WrapperNamespace = "http://abc.org/wcf/", IsWrapped = true)]
    public partial class System
    {
        [global::System.ServiceModel.MessageHeaderAttribute(Namespace = "http://abc.org/wcf/")]
        public string Something;

        public System() { }
        public System(string Something) { this.Something = Something; }
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions