.NET Framework Bookmark and Share   
 index > Windows Communication Foundation > Ambiguous reference between enums when using a service reference / general headaches with enum in WCF
 

Ambiguous reference between enums when using a service reference / general headaches with enum in WCF

I'm in the process of porting some old ASMX code over to WCF. Some of the methods have enumerated constants as return values and parameters. These work fine when using the ASMX services, but have caused all kinds of errors and warnings when porting to WCF. None of the suggestions I've found the web on how to fix similar sounding issues have worked; some say the enum needs a DataContract attribute and each value EnumMember, others say it should just work without modification. This has become very frustrating.

I've managed to reproduce one of the errors in a test project with a similar structure to my production code. It consists of three simple projects:

  1. Common (class library):

    namespace Common
    {
    public enum PrimaryColor
    {
    Red,
    Green,
    Blue
    };
    }
  2. Library (WCF service library), which has a reference to Common:

    using Common;

    namespace Library
    {
    [ServiceContract]
    public interface ILibrary
    {
    [OperationContract]
    PrimaryColor GetColor();
    }

    public class Library : ILibrary
    {
    public PrimaryColor GetColor()
    {
    return PrimaryColor.Red;
    }
    }
    }
  3. ClientApp (console application), which has a reference to Common, and a service reference to Library called "LibraryServiceReference":

    using Common;
    using ClientApp.LibraryServiceReference;

    namespace ClientApp
    {
    class Program
    {
    static void Main(string[] args)
    {
    LibraryClient client = new LibraryClient("WSHttpBinding_ILibrary");
    PrimaryColor color = client.GetColor();
    }
    }
    }
The app.config files in ClientApp and Library are auto-generated and I have not modified them, and I have not changed the default configuration for the LibraryServiceReference in ClientApp.

When I compile this solution, I get the following errors in the ClientApp project:

Error 1 'PrimaryColor' is an ambiguous reference between 'Common.PrimaryColor' and 'ClientApp.LibraryServiceReference.PrimaryColor'
Error 2 Cannot implicitly convert type 'ClientApp.LibraryServiceReference.PrimaryColor' to 'Common.PrimaryColor'. An explicit conversion exists (are you missing a cast?)

So why did the LibraryServiceReference evidently create it's own copy of the PrimaryColor enum and append the host's namespace to it? Why doesn't LibraryServiceReference know about the Common.PrimaryColor enum?

Thanks
Henchman 24

Make sure that 'Reuse types in all referenced assemblies' is selected in the Advanced options of Add service reference.
Also, can you move PrimaryColors to a library and reference this library from your client project. In this case, the client code (autogenerated) will not generate another version of PrimaryColor for you, but use the one from the referenced library instead.

HTH


Amit Sharma
Amit Sharma R
Just remove the reference to Common project from your ClientApp project and the error should go away. When you're creating a proxy for your service, all dependent code from the service must be injected into the proxy. If you want your types to be same as those on the service side, just enable the 'Reuse types' option while generating the proxy code (otherwise they will be put under a different namespace).

Regards,
Stipe-Ivan
Stipe-Ivan Latkovic
Thanks for the replies.

The "Reuse types is all referenced assemblies" option in the Service Reference is enabled by default. PrimaryColors is in a library referenced by the client project; it's in the Common library referenced by both the WCF service Library and the ClientApp.

Removing the Common reference from ClientApp worked as Stipe-Ivan suggested, but in the actual production code this isn't an option because the equivalent of the "Common" library contains other classes that are used by the client application. It actually gets uglier in the production code because the (equivalent class) Common has a service reference to the Library, which in has a normal reference to the Common. If there's not a way to resolve the ambiguity, perhaps this design isn't a good fit.

Is there a way to do this without the Service Reference proxy?
Henchman 24
Why don't you put all the shared entities into the 'Common' project and then reference it from both the service and the client project?

Regards,
Stipe-Ivan
Stipe-Ivan Latkovic

>>PrimaryColors is in a library referenced by the client project; it's in the Common library referenced by both the WCF service Library and the ClientApp.
are you saying that though you had a reference that contained PrimaryColors, add service reference (ASR) did you resolve that for you when it generated the proxy code?

IMO, if you already have a reference dll that contains the type then ASR should not generate that type for you. Can you please delete the ServiceReference (proxy)and add it again.


Amit Sharma
Amit Sharma R
Stipe-Ivan: That is my existing design; the common DLL contains code that's shared by various clients and other components.

Amit: Yes, that's exactly what I'm saying. When I added the reference back in after trying Stipe-Ivan's suggestion and doing a full rebuild, the errors magically disappeared. When I tried your suggestion to delete the ServiceReference and add it again, the errors return. Deleting and re-adding the regular reference makes them go away again.

When I tried this in the production code, I got the ambiguity errors as well as "Custom tool warnings" to the effect of (redacted):

"Warning 1 Custom tool warning: Cannot import wsdl:portType
Detail: An exception was thrown while running a WSDL import extension: System.ServiceModel.Description.DataContractSerializerMessageContractImporter
Error: List of referenced types contains more than one type with data contract name 'PluginManager.PluginType' in namespace 'http://schemas.datacontract.org/2004/07/x.y.Core'. Need to exclude all but one of the following types. Only matching types can be valid references:
"x.y.Core.PluginManager+PluginType, x.y.Core, Version=10.2.1.3, Culture=neutral, PublicKeyToken=null" (matching)
"x.y.Core.yServiceReference.PluginManagerPluginType, x.y.Core, Version=10.2.1.3, Culture=neutral, PublicKeyToken=null" (matching)
XPath to Error Source: //wsdl:definitions[@targetNamespace='http://tempuri.org/']/wsdl:portType[@name='IWarehouseService'] C:\...\yServiceReference\Reference.svcmap 1 1 x.y.UI

"Warning 14 Custom tool warning: Cannot import wsdl:binding
Detail: There was an error importing a wsdl:portType that the wsdl:binding is dependent on.
XPath to wsdl:portType: //wsdl:definitions[@targetNamespace='http://tempuri.org/']/wsdl:portType[@name='IOXPd']
XPath to Error Source: //wsdl:definitions[@targetNamespace='http://tempuri.org/']/wsdl:binding[@name='OXPd'] C:\...\yServiceReference\Reference.svcmap 1 1 x.y.UI"
  • Edited byHenchman 24 Friday, September 18, 2009 6:22 PMMore Info
  •  
Henchman 24

did you look at this? http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/7b51455b-cdba-470c-8009-fdaebe2c9a64


Amit Sharma
Amit Sharma R
I've seen the thread but didn't think it was the same problem at the time. It looked like the original poster had an actual duplicate with the same name, possibly due to confusion between a Service Reference and a Web Reference. My problem is that the proxy seems to be generating it's own copy and the compiler can't sort out the ambiguity. Eugene Osovetsky's reply about how "there are still a number of issues in the area of proxy generation" does seem to apply here, however. I guess I will either have to dig into svcutil.exe, or just stop passing enum's over WCF...
Henchman 24

This is my setup
Project 1:classlib1.dll, this contains enum PrimaryColors
Project 2: WCF service. This project has a project reference classlib1.dll and uses PrimaryColors in operation contract
Project 3: Client app. This project has a project reference to classlib1.dll. ASR resolves ClassLibrary1.PrimaryColors correctly



Amit Sharma
Amit Sharma R
It sounds like we've got the same setup as far as the test project goes. FWIW, I'm running Team System 2008 Development Edition SP1. I haven't been able to reproduce the problem since my last post. Unfortunately I can't resolve it in the production code.
Henchman 24
what happens when you start fresh in your production environmen. So far, I don't think that this is a product bug.
from your production app;
- remove service reference
- remove class lib reference
- add the class lib reference
- ASR


Amit Sharma
Amit Sharma R
Thanks for looking into this. Unfortunately, I still get the same errors, where "PluginType" is an enum:

Argument '1': cannot convert from 'I.I.Core.PluginManager.PluginType' to I.I.Core.IServiceReference.PluginManagerPluginType'

I'm also getting a couple warnings I've not seen before:

Custom tool warning: The assembly 'I.I.C' could not be found. Ensure that the assembly is referenced. If the assembly is part of the current development project, ensure that the project has been built. C:\...\IServiceReference\Reference.svcmap

I don't know if this matters, but for completeness' sake, the production WCF service library is self-hosted in a windows service, and the bindings are all basicHttpBinding.
Henchman 24
Hi Henchman 24,

I didn't reproduce your scenario.

1. I create one class library which contains service contract.

namespace ClassLibrary1
{
public enum PrimaryColor
{
Red,
Green,
Blue
};

[ServiceContract]
public interface ISimpleService
{
[OperationContract]
string SimpleMethod(string msg);

[OperationContract]
PrimaryColor GetColor();
}
}

2. I use Self-Host to start WCF service.

class SimpleService : ISimpleService
{
public string SimpleMethod(string msg)
{
Console.WriteLine("The caller passed in " + msg);
return "Hello " + msg;
}


public PrimaryColor GetColor()
{
return PrimaryColor.Red;
}
}
class Program
{
static void Main(string[] args)
{
ServiceHost svcHost = new ServiceHost(typeof(SimpleService), new Uri[]
{ new Uri("http://localhost:8006/MetadataSample")});
try
{
// Check to see if the service host already has a ServiceMetadataBehavior
ServiceMetadataBehavior smb = svcHost.Description.Behaviors.Find<ServiceMetadataBehavior>();
// If not, add one
if (smb == null)
smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
svcHost.Description.Behaviors.Add(smb);
// Add MEX endpoint
svcHost.AddServiceEndpoint(
ServiceMetadataBehavior.MexContractName,
MetadataExchangeBindings.CreateMexHttpBinding(),
"mex"
);
// Add application endpoint
svcHost.AddServiceEndpoint(typeof(ISimpleService), new WSHttpBinding(), "");
// Open the service host to accept incoming calls
svcHost.Open();

// The service can now be accessed.
Console.WriteLine("The service is ready.");
Console.WriteLine("Press <ENTER> to terminate service.");
Console.WriteLine();
Console.ReadLine();

// Close the ServiceHostBase to shutdown the service.
svcHost.Close();
}
catch (CommunicationException commProblem)
{
Console.WriteLine("There was a communication problem. " + commProblem.Message);
Console.Read();
}

}

3. I create the proxy class for the client via add service references with option "Reuse types in all referenced assemblies". The following is client code.
private void button1_Click(object sender, EventArgs e)
{
ServiceReference1.SimpleServiceClient sc = new ServiceReference1.SimpleServiceClient();
MessageBox.Show(sc.GetColor().ToString());
MessageBox.Show(sc.SimpleMethod("test"));
}


The client has reference to classlibrary1. We can see that there is not new enum type generated by IDE.

public ClassLibrary1.PrimaryColor GetColor() {
return base.Channel.GetColor();
}

Please check your code snippet. Or you can give one small code snippet so that we can reproduce your scenario.


Best regards,
Riquel
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
Riquel_Dong

You can use google to search for other answers

Custom Search

More Threads

• Infamous "Could not find default endpoint element"
• Trusted certificate only works after second service-call
• WCF
• how to consume wcf service implemented with wsFederationBinding
• WCF: WSHttpContextBinding don't found matching element.
• basicHttpBinding and Username Authentication
• wsHttpBinding InactivityTimeout
• How discover service instances and to retrieve WCF performance counter value using VB Script with WMI?
• How to make a REST Service Durable ?
• unable to use WCF service in c# project - MetaData Error