Utilizzando oggetto FaultContract personalizzata contenente cause System.Exception 'Aggiungi riferimento al servizio' a fallire

StackOverflow https://stackoverflow.com/questions/4656257

Domanda

Ho appena notato qualcosa di particolare. Ho un servizio di magazzino interno che viene pubblicato attraverso basicHttpBinding, e un customBinding (http + binario) i cui metadati è abilitato. Ho incluso anche un endpoint mex per HTTP. Usiamo Visual Studio 2008 e VB.NET

Proprio di recente abbiamo notato che siamo stati in grado di aggiungere con successo un riferimento al servizio di questo servizio nei nostri altri progetti. Tutto ciò che si genererebbe stata la prima eccezione personalizzata abbiamo inserito attraverso un FaultContract (in realtà, c'era solo 1 tipo). se mi piacerebbe aggiungere un semplice riferimento Web che avrebbe funzionato correttamente pure. Inoltre, il WcfClient.exe non ha avuto problemi sia nel caricamento dei servizi. Basta VS.NET riferimento al servizio aggiuntivo non funzionerebbe.

Nel servizio questa eccezione eredita da Exception e viene contrassegnata come serializzabile. Questo è tutto quello che si dovrebbe fare, no?

In ogni caso, questo mi aveva sconcertato. Se rimuovo il FaultContract per questa eccezione personalizzato tutto funziona bene. Posso aggiungere un riferimento al servizio, nessun problema. Ma c'è un modo posso ancora avere le mie eccezioni personalizzate? Si tratta di un problema noto?

È stato utile?

Soluzione

mi sono imbattuto in questo io stesso oggi. La soluzione era quella di utilizzare un oggetto non eredita da Exception nel FaultContract. Se si guarda la documentazione MSDN per FaultException e FaultContract vedrete che gli esempi ufficiali utilizzare le classi normali ( con attributi Datacontact) anziché classi estendono eccezione per FaultException.Detail. Io non sono sicuro perché Eccezione provoca Aggiungi servizio di riferimento a fallire, ma ho il sospetto che abbia a che fare con la serializzazione o il recupero di informazioni sul tipo relative eccezioni personalizzate. Ho incluso prima e dopo alcuni esempi di implementazione per dimostrare il metodo di lavoro.

Prima (non ha funzionato):

[ServiceContract]
public interface IMyService
{
    [OperationContract]
    [FaultContract(typeof(MyException))]
    MyResults MyServiceOperation(string myParameter);
}

[Serializable]
public class MyException : Exception
{
    public string CustomData { get; set; }
}

[ErrorHandlerBehavior(typeof(MyErrorHandler))]
public class MyService : IMyService
{
    public MyResults MyServiceOperation(string myParameter)
    {
        ...
        throw new MyModelException { CustomData = "42" };
        ...
    }
}

public class MyErrorHandler : IErrorHandler
{
    public bool HandleError(Exception error) { return false; }

    public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
    {
        try { throw error; }
        catch (MyModelException ex)
        {
            var faultEx = new FaultException<MyException>(new MyException { CustomData = ex.CustomData });
            fault = Message.CreateMessage(version, faultEx.CreateMessageFault(), faultEx.Action);
        }
        catch { /* Supress all others */ }
    }
}

Dopo (lavorato):

[ServiceContract]
public interface IMyService
{
    [OperationContract]
    [FaultContract(typeof(MyFault))]
    MyResults MyServiceOperation(string myParameter);
}

[DataContract]
public class MyFault
{
    [DataMember]
    public string CustomData { get; set; }
}

[ErrorHandlerBehavior(typeof(MyErrorHandler))]
public class MyService : IMyService
{
    public MyResults MyServiceOperation(string myParameter)
    {
        ...
        throw new MyModelException { CustomData = "42" };
        ...
    }
}

public class MyErrorHandler : IErrorHandler
{
    public bool HandleError(Exception error) { return false; }

    public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
    {
        try { throw error; }
        catch (MyModelException ex)
        {
            var faultEx = new FaultException<MyFault>(new MyFault { CustomData = ex.CustomData });
            fault = Message.CreateMessage(version, faultEx.CreateMessageFault(), faultEx.Action);
        }
        catch { /* Supress all others */ }
    }
}

Fonte: Max Strini per l'uso del suo codice e aiuto per trovare la soluzione a questo problema <. / p>

Altri suggerimenti

Ho trovato il seguente articolo su come creare un contratto di guasto utilizzando obiettò ereditato da System.Exception: http://blog.clauskonrad.net/2008/06/wcf-and-custom-exceptions.html

Tuttavia, non ha funzionato per me. Ho il sospetto che la ragione per cui non ha funzionato per me è che sto usando un BasicHttp vincolante e non un NET-NET vincolante.

Ho colpito anche questo problema. Ho finito per usare lo Svcutil.exe per generare il proxy che non sembra soffrire lo stesso problema.

Ho avuto lo stesso problema e risolto generando il proxy utilizzando Svcutil.exe. Ho avuto la messa a punto di errore personalizzato esattamente il modo in MSDN raccomanda ma "di riferimento servizio aggiunto" non è stato compreso il contratto di colpa nel proxy. Poi ho usato lo svcutil e ha funzionato come per magia:)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top