WCF: предоставить универсальное исключение FaultException в IErrorHandler

Немного контекста: у нас есть собственный XSD и мы генерируем код WSDL и C # с помощью WSCF.blue. Клиентская сторона используетChannelFactory<T>&nbsp;и разделяет интерфейс, который включает все атрибуты, добавленные WSCF.blue, чтобы соответствовать тому, что находится в XSD.

Я пытаюсь реализоватьIErrorHandler.ProvideFault&nbsp;где он предоставляет общийFaultException<T>, но на стороне клиента я получаю не универсальныйFaultContract, Это то, что мойProvideFault&nbsp;Метод выглядит так:

public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
    if (!(error is FaultException))
    {
        FaultException faultException = FaultExceptionFactory.CreateFaultException(error);
        MessageFault messageFault = faultException.CreateMessageFault();
        fault = Message.CreateMessage(version, messageFault, faultException.Action);
    }
}

В каждом методе обслуживания, если я делаю попытку / поймать сthrow FaultExceptionFactory.CreateFaultException(ex)&nbsp;это работает, как и ожидалось, поэтому я думаю,[FaultContract], фабрика, крепления и т. д. все правильно. На всякий случай вот так работает фабрика:

BusinessRuleFaultExceptionType businessRuleFaultException = new BusinessRuleFaultExceptionType();
BusinessRuleFaultException.Code = exception.Code.ToString();
BusinessRuleFaultException.Reason = exception.Message;
return new FaultException<BusinessRuleFaultExceptionType>(
    businessRuleFaultException,
    exception.Message,
    new FaultCode(exception.Code.ToString())
);

Я думаю, что проблема в том, как сообщение создается вIErrorHandlerвозможно вCreateMessageFault(), Я прочитал, что действие должно бытьfaultException.Action&nbsp;вместоnull, но по фактуfaultException.Action&nbsp;являетсяnull, Может быть, это вызывает проблему. Я могу установить действие на заводе, но каким должно быть это действие, и почему оно не появится при ручном броске?

Любые другие идеи, которые я мог бы упустить?

Редактировать:&nbsp;Я проверил WSDL и нашел конкретную операцию, которую я вызывал, и ее действие:

<wsdl:operation name="MyMethod">
<wsdl:fault wsaw:Action="http://myNamespace/MyMethodBusinessRuleFaultExceptionTypeFault" name="BusinessRuleFaultExceptionTypeFault" message="tns:..."/>

Я старался кодировать действие:Message.CreateMessage(..., "http://myNamespace/MyMethodBusinessRuleFaultExceptionTypeFault")&nbsp;и установив его на.Action&nbsp;на фабрике, но это все еще не сработало.

Изменить 2:&nbsp;Метод throw / catch генерирует следующий XML, который позволяет перехватить общее исключение на клиенте:

<s:Fault>
    <faultcode xmlns="">s:-100</faultcode>
    <faultstring xml:lang="en-US" xmlns="">xxx</faultstring>
    <detail xmlns="">
        <BusinessRuleFaultExceptionType xmlns="http://myNamespace/Services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
            <Code xmlns="http://myNamespace/Entitites">-100</Code>
            <Reason xmlns="http://myNamespace/Entitites">xxx</Reason>
        </BusinessRuleFaultExceptionType>
    </detail>
</s:Fault>

IHttpErrorHandler&nbsp;генерирует следующее, что идет к неуниверсальномуFaultException:

<s:Fault>
    <faultcode xmlns="">s:-100</faultcode>
    <faultstring xml:lang="en-US" xmlns="">xxx</faultstring>
    <detail xmlns="">
        <BusinessRuleFaultExceptionType xmlns="http://schemas.datacontract.org/2004/07/My.Dot.Net.Namespace" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
            <codeField>-100</codeField>
            <reasonField>xxx</reasonField>
        </BusinessRuleFaultExceptionType>
    </detail>
</s:Fault>

Изменить 3:&nbsp;Если я добавлю[DataContract]&nbsp;а также[DataMember]&nbsp;кBusinessRuleFaultExceptionTypeтогда я получаю почти правильный XML:

<s:Fault>
    <faultcode xmlns="">s:-100</faultcode>
    <faultstring xml:lang="en-US" xmlns="">xxx</faultstring>
    <detail xmlns="">
        <BusinessRuleFaultExceptionType xmlns="http://myNamespace/Services" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
            <Code>-100</Code>
            <Reason>xxx</Reason>
        </BusinessRuleFaultExceptionType>
    </detail>
</s:Fault>

В нем отсутствует пространство имен для кода и причины. По крайней мере, я думаю, что это сужает это. Регулярная сериализация использует[XmlType]&nbsp;а также[XmlElement]&nbsp;в то время какIErrorHandler&nbsp;использует[DataContract]&nbsp;а также[DataMember], к несчастью[DataMember]&nbsp;не позволяет вам установить пространство имен, поэтому я думаю, что теперь вопрос заключается в том, как использовать XMLSerializer вIErrorHandler, Это описывает мою проблему, но исправление не будет работать по причине, указанной выше:http://twenty6-jc.blogspot.com/2011/05/ierrorhandlerprovidefault-serialization.html

Изменить 4:&nbsp;Я частично нашел проблему. Мы используемXmlSerializer, но с тех порIErrorHandler&nbsp;находится за пределами действия операции, возвращается к значению по умолчаниюDataContractSerializer, Решение состоит в том, чтобы либо изменить свой сервис для использованияDataContractSerializer&nbsp;везде или вручную выбратьXmlSerializer&nbsp;при создании неисправностей. Эти две статьи предоставили то, что мне было нужно:

http://twenty6-jc.blogspot.com/2011/05/ierrorhandlerprovidefault-serialization.html http://zamd.net/2008/08/15/serializing-faults-using-xmlserializer/

Это получает меняочень&nbsp;близко. Он такой же, как и рабочий XML, за исключением того, что отсутствует пространство имен типа исключения:

<s:Fault>
    <faultcode xmlns="">s:-100</faultcode>
    <faultstring xml:lang="en-US" xmlns="">xxx</faultstring>
    <detail xmlns="">
        <BusinessRuleFaultExceptionType xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
            <Code xmlns="http://myNamespace/Entitites">-100</Code>
            <Reason xmlns="http://myNamespace/Entitites">xxx</Reason>
        </BusinessRuleFaultExceptionType>
    </detail>
</s:Fault>

Я предполагаю, что это не добавляетxmlns="http://myNamespace/Services"&nbsp;потому что у него нет контекста запроса. Это пространство имен определено в интерфейсе, но не в контракте данных. Я действительно буду вынужден оставаться в контексте запроса (надеюсь,IOperationInvoker&nbsp;работает) вместо использованияIHttpHandler?