Code generated by dotnet-svcutil breaks when a type has a member called System.
- Dominant language
- C#
- Stars
- 1.8k
- Forks
- 576
- Avg merge
- 6d 9h
- Merged PRs (30d)
- 2
Description
## 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.
```csharp
[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:
```csharp
[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:
```csharp
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; }
}
}
```
Contributor guide
Assessment
This issue has not been assessed yet.