Прекращение метаданных при исключении KeyNotFoundException с пользовательским FaultContract - PullRequest
0 голосов
/ 02 июля 2019

Я настраиваю службу WCF и приложение WPF.

Служба является дуплексной службой и имеет привязку net.https и net.tcp.Также конечная точка https и TCP MEX.Наконец udpDiscoveryEndpoint, чтобы обнаружить его в сети.

Приложение обнаружит службу через DiscoveryEndpoint и UdpDiscoveryEndpoint.После этого определите ServiceEndpointCollection с помощью MetadataResolver.Я создаю контракт с svcutil.exe и сохраняю его в DLL.

Дело в том, что я хочу, чтобы ошибки службы были строго типизированы в сервисе, выдаваемом клиенту, поэтому я могу обрабатывать их также на стороне клиента.

В моих первых попытках я подключаю сервис через ссылку на сервис, устанавливаю FaultContract и все в порядке.Затем я установил класс для обнаружения приложения через UdpDiscoveryEndpoint и разрешил метаданные для получения конечных точек.

Таким образом, я получил KeyNotFoundException при выполнении следующего кода:

MetadataResolver.Resolve(typeof(Contracts.ISvcRegistration), findResponse.Endpoints[0].Address)

Когда я удаляю FaultContractAttribute из контракта, он будет работать, но не будет выдавать строго типизированные ошибки клиенту ...

GetEndpoints:

// use a udp discovery client to discover the service
using (DiscoveryClient discoveryClient = new DiscoveryClient(new UdpDiscoveryEndpoint()))
{
    FindCriteria findCriteria = null;

    switch (serviceType)
    {
        case EService.SvcRegistration:
            // find the metadata of the service type by MEX
            findCriteria = FindCriteria.CreateMetadataExchangeEndpointCriteria(typeof(Contracts.ISvcRegistration));
            break;
        default:
            break;
    }

    // only get one result
    findCriteria.MaxResults = 1;

    // find a service with the service type as criteria
    var findResponse = discoveryClient.Find(findCriteria);

    // null the criteria
    findCriteria = null;

    // getting the endpoint collection of the service
    switch (serviceType)
    {
        case EService.SvcRegistration:                            
        // exception will occur on the following line:
            Endpoints_SvcRegistration = MetadataResolver.Resolve(typeof(Contracts.ISvcRegistration), findResponse.Endpoints[0].Address);
            break;
        default:
            break;
    }
    // null the response
    findResponse = null;
}

сниппетиз скачанного контракта:

[System.ServiceModel.OperationContractAttribute(Action = "http://tempuri.org/ISvcRegistration/GetAccountAuthentication", ReplyAction = "http://tempuri.org/ISvcRegistration/GetAccountAuthenticationResponse")] 
[System.ServiceModel.FaultContractAttribute(typeof(VisionHR_Dll.Services.Contracts.AccountNotMemberFault), Action = "http://tempuri.org/ISvcRegistration/GetAccountAuthenticationAccountNotMemberFault" +
    "Fault", Name = "AccountNotMemberFault", Namespace = "http://schemas.datacontract.org/2004/07/VisionHR_Dll.Business.ExceptionObjects")]

На сервисе:

[OperationContract]
[FaultContract(typeof(VisionHR_Dll.Business.ExceptionObjects.AccountNotMemberFault))]        
bool GetAccountAuthentication(VisionHR_Dll.Auxiliaries.Security.AuthenticationWallet wallet, byte[] chiper);

Когда уберу FaultContractAttribute, будет работать.

...