alphaleonis/WcfClientProxyGenerator

System.InvalidOperationException at execution

Closed this issue · 2 comments

Hi!

I'm getting this exception:

System.InvalidOperationException

The synchronous OperationContract method 'GetCompaniesForLookup' in type 'WcfClientProxyGeneratorUI.ILookupProxy' was matched with the task-based asynchronous OperationContract method 'GetCompaniesForLookupAsync' because they have the same operation name 'GetCompaniesForLookup'. When a synchronous OperationContract method is matched to a task-based asynchronous OperationContract method, any additional attributes must be declared on the synchronous OperationContract method. In this case, the task-based asynchronous OperationContract method 'GetCompaniesForLookupAsync' has one or more attributes of type 'FaultContractAttribute'. To fix it, remove the 'FaultContractAttribute' attribute or attributes from method 'GetCompaniesForLookupAsync'. Alternatively, changing the name of one of the methods will prevent matching.

Here is ILookupProxy

using Alphaleonis;
using DA.Services.CarPark.ServiceContracts.Common.v1;

namespace WcfClientProxyGeneratorUI
{
    [GenerateWcfClientProxy(typeof(ILookupService))]
    public partial interface ILookupProxy
    {
    }
}

Here is LookupProxy

using Alphaleonis;

namespace WcfClientProxyGeneratorUI
{
    [GenerateErrorHandlingWcfProxy(typeof(ILookupProxy), ConstructorVisibility = GeneratedMemberAccessibility.Public)]
    public partial class LookupProxy
    {
    }
}

And here is my actual contract: ILookupService

using DA.Services.CarPark.ServiceCommon;
using System.Collections.Generic;
using System.ServiceModel;

namespace DA.Services.CarPark.ServiceContracts.Common.v1
{
    [ServiceContract(Namespace = Constants.ServiceNamespace)]
    public interface ILookupService
    {

        [OperationContract]
        [FaultContract(typeof(CarParkFault))]
        IList<BDO.Company> GetCompaniesForLookup(DA.Services.CarPark.BDO.Enums.ServiceTypeEnum serviceType, string filter);

        [OperationContract]
        [FaultContract(typeof(CarParkFault))]
        IList<BDO.Company> GetCompanies();

    }
}

CarParkFault source:

using System.Runtime.Serialization;

namespace DA.Services.CarPark.ServiceCommon
{
    [DataContract]
    public class CarParkFault
    {
        [DataMember]
        public string FaultMessage;

        public CarParkFault(string ErrMessage)
        {
            FaultMessage = ErrMessage;
        }
    }
}

And lastly, public const string ServiceNamespace = "http://www.myairports.ae/internal/services/";

What Am I missing here?

I also noticed the following:

In the ILookupProxy, the generated code has two APIs Sync and Async.

        /*****************************************************************/
        /* WARNING! THIS CODE IS AUTOMATICALLY GENERATED. DO NOT MODIFY! */
        /*****************************************************************/
        [System.ServiceModel.FaultContract(typeof(DA.Services.CarPark.ServiceCommon.CarParkFault))]
        [System.ServiceModel.OperationContract]
        System.Collections.Generic.IList<DA.Services.CarPark.BDO.Company> GetCompanies();


        /*****************************************************************/
        /* WARNING! THIS CODE IS AUTOMATICALLY GENERATED. DO NOT MODIFY! */
        /*****************************************************************/
        [System.ServiceModel.FaultContract(typeof(DA.Services.CarPark.ServiceCommon.CarParkFault))]
        [System.ServiceModel.OperationContract(AsyncPattern = true)]
        System.Threading.Tasks.Task<System.Collections.Generic.IList<DA.Services.CarPark.BDO.Company>> GetCompaniesAsync();

In the LookupProxy, the generated code has one Sync and two Async APIs.

        /*****************************************************************/
        /* WARNING! THIS CODE IS AUTOMATICALLY GENERATED. DO NOT MODIFY! */
        /*****************************************************************/
        public System.Collections.Generic.IList<DA.Services.CarPark.BDO.Company> GetCompanies()
        {
            try
            {
                var proxy = this.GetProxy();
                return proxy.GetCompanies();
            }
            catch
            {
                this.CloseProxy(false);
                throw;
            }
        }

        /*****************************************************************/
        /* WARNING! THIS CODE IS AUTOMATICALLY GENERATED. DO NOT MODIFY! */
        /*****************************************************************/
        public async System.Threading.Tasks.Task<System.Collections.Generic.IList<DA.Services.CarPark.BDO.Company>> GetCompaniesAsync()
        {
            try
            {
                var proxy = await this.GetProxyAsync().ConfigureAwait(false);
                return await proxy.GetCompaniesAsync().ConfigureAwait(false);
            }
            catch
            {
                this.CloseProxy(false);
                throw;
            }
        }

        /*****************************************************************/
        /* WARNING! THIS CODE IS AUTOMATICALLY GENERATED. DO NOT MODIFY! */
        /*****************************************************************/
        public async System.Threading.Tasks.Task<System.Collections.Generic.IList<DA.Services.CarPark.BDO.Company>> GetCompaniesAsync(System.Threading.CancellationToken cancellationToken)
        {
            try
            {
                var proxy = await this.GetProxyAsync().ConfigureAwait(false);
                using (cancellationToken.Register(s => CloseProxy((System.ServiceModel.ICommunicationObject)s, true), proxy, false))
                {
                    return await proxy.GetCompaniesAsync().ConfigureAwait(false);
                }
            }
            catch
            {
                this.CloseProxy(false);
                throw;
            }
        }

But I believe that this may not be the issue.

From just briefly looking at this it seems the error is that both the sync and async method in the generated interface are decorated with FaultContract attributes. Only one of them should have these. If I'm not mistaken. I will take a closer look at this as soon as I get the time.