-->

Ambiguous reference in WCF and client application

2019-02-23 07:13发布

问题:

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:

Common (class library):

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

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;
        }
    }
}

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?)

please help me to fix this.

回答1:

Make sure that 'Reuse types in all referenced assemblies' is selected in the Advanced options of Add service reference or Configure Service Reference.



回答2:

  1. Decorate your enum like this:

    namespace Common
    {
        [DataContract]
        public enum PrimaryColor
        {
            [EnumMember]
            Red,
            [EnumMember]
            Green,
            [EnumMember]
            Blue
        };
    }
    
  2. Update Your service reference (with checking reuse types just like Mark stated).

  3. Rebuild your client code.



回答3:

it's because you're building x64 not "AnyCpu". I am running across this right now, and am trying to figure out if it's a bug, or if it's expected behavior.



回答4:

It sounds like you control both the client and the server code. Why do you want to create a service reference, is there a specific reason or is it just deemed easier?

In projects where you control both sides of the client server application you are better of creating a "contract assembly" (which is probably your common assembly). This contains the interfaces and objects that are involved with the contract and should be referenced by both your client and your server. In order to communicate with the service the client creates a proxy class using the ChannelFactory, there is no need to have a dedicated WCF client.

Example:

ChannelFactory<ISampleService> factory = new ChannelFactory<ISampleService>("Binding_from_config");

ISampleService sampleService = factory.CreateChannel();

sampleService.SomeCall();

factory.Close();

The factory pattern also makes it an ideal candidate for injecting your proxy in via IoC.

The benefits of referencing a common assembly over creating a service reference are:

  • No ambiguous reference as there will be no need for auto generated classes.
  • You will not have to update your service reference every time you change the contract.


回答5:

I have had this issue arise in innocuous, unpredictable manners so many times! I thought I'd share how I "fixed" it this last time.

I am using Visual Studio 2013 - but have had the issue down rev.

The ambiguous reference seems to come on by itself. I did nothing of note to cause it. In the latest instance I was debugging some code behind and suddenly I had 7, then 22 then 49 errors - all of the same nature.

I deleted the service reference altogether and re-added it. Simply modifying the re-use type did nothing. My solution has a WCF service, Class Library, UI and a Control Library. I also removed the using - in some code behind, of the class library.

This is an exceptionally troublesome issue which thankfully only occurs about every few weeks. Why this worked? Beyond my pay grade. I feel your pain! Hope this helps. In this case, the error came on, again, when I opened some code behind on a xaml page.



回答6:

The problem here is that PrimaryColor exists in both Common and ClientApp.LibraryServiceReference and you are referencing both namespaces in your class.

To overcome this issue, either explicitly reference the instance that you require, i.e.

Common.PrimaryColor color = ....

or set up an alias:

using Service = ClientLibraryServiceReference; ...

Service.PrimaryColor color = ......



回答7:

When making the service reference aren't there some options that say something like: "inlcude common types in generated service contract" ?

I have the idea that in your service reference the classes are "copied" and that's why you get this error. Inspect the generated service files, remove then and add them again with "Add Service Reference" and see what options you have there.

EDIT

Although I'm almost sure that the Type PrimaryColor is defined twice. One time in the common project and one time in your service reference, you can also try this in your clientApp (to more explicitely specify the PrimaryColor Type):

Common.PrimaryColor color = client.GetColor();


标签: wcf ambiguous