WCF IDispatchMessageFormatter null - PullRequest
0 голосов
/ 17 июня 2020

Я передаю запрос SOAP, чтобы перед внесением некоторых изменений посмотреть, как изменить исходящий префикс с s: Envelop на soap -env: Envelope в соответствии с этим примером https://www.vanacosmin.ro/Articles/Read/WCFEnvelopeNamespacePrefix Я прохожу

<soap-env:Envelope
xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:pro="http://www.xxxx">
<soap-env:Header/>
<soap-env:Body>
    <pro:getProposalList version="6.66">
        <pro:code>323232</pro:code>
    </pro:getProposalList>
</soap-env:Body>

и получаю

<s:Envelope
xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <ProposalList Version="3.22"
        xmlns="http://xxxxx">
        <ProposalHeader>
            <RefNum>1</RefNum>
            <Size>24</Size>
            <DateSubmitted>2020-06-18</DateSubmitted>
        </ProposalHeader>
    </ProposalList>
</s:Body>

Однако мне нужно что-то вроде этого

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <SOAP-ENV:Body> 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <ProposalList Version="3.22"
            xmlns="http://www.xxxx">
            <ProposalHeader>
                <RefNum>1</RefNum>
                <Size>24</Size>
                <DateSubmitted>2020-06-18</DateSubmitted>
            </ProposalHeader>
        </ProposalList>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>    

Когда я передаю объект, который затем создает экземпляр этого класса

public class ProposalMessageFormatter : IDispatchMessageFormatter
{
    private readonly IDispatchMessageFormatter formatter;

    public ProposalMessageFormatter(IDispatchMessageFormatter formatter)
    {
        this.formatter = formatter;
    }

    public void DeserializeRequest(Message message, object[] parameters)
    {
        this.formatter.DeserializeRequest(message, parameters);
    }

    public Message SerializeReply(MessageVersion messageVersion, object[] parameters, object result)
    {
        var message = this.formatter.SerializeReply(messageVersion, parameters, result);
        return new ProposalMessage(message);
    }
}

IDispatchMessageFormatter formatter имеет значение null, я подозреваю, что это может быть причиной проблемы

Я использую autofa c для моего DI и моего global.asax.cs, и на него не ссылались и не ссылались в этих примерах

builder.RegisterType<ProposalMessageFormatter>().As<IDispatchMessageFormatter>();
builder.RegisterType<ProposalMessageFormatter>().SingleInstance();
builder.RegisterType<ProposalMessageFormatter>().UsingConstructor(typeof(IDispatchMessageFormatter));

Возвращаемая ошибка:

Сервер был невозможно обработать запрос из-за внутренней ошибки. Для получения дополнительных сведений об ошибке либо включите IncludeExceptionDetailInFaults (либо из ServiceBehaviorAttribute, либо из поведения конфигурации ) на сервере, чтобы отправить информацию об исключении обратно клиенту, либо включите трассировку в соответствии с Microsoft. NET Документация Framework SDK и проверка журналов трассировки сервера.

немного подробнее об этой ошибке сейчас

<s:Envelope
    xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Body>
        <s:Fault>
            <faultcode
                xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:InternalServiceFault
            </faultcode>
            <faultstring xml:lang="en-GB">Object reference not set to an instance of an object.</faultstring>
            <detail>
                <ExceptionDetail
                    xmlns="http://schemas.datacontract.org/2004/07/System.ServiceModel"
                    xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
                    <HelpLink i:nil="true"/>
                    <InnerException i:nil="true"/>
                    <Message>Object reference not set to an instance of an object.</Message>
                    <StackTrace>   at TQ.LPAConnector.Service.MessageFormatter.ProposalMessageFormatter.DeserializeRequest(Message message, Object[] parameters) in C:\Projects\xxx.Service\MessageFormatter\ProposalMessageFormatter.cs:line 17&#xD;
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc&amp; rpc)&#xD;
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&amp; rpc)&#xD;
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc&amp; rpc)&#xD;
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc&amp; rpc)&#xD;
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc&amp; rpc)&#xD;
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc&amp; rpc)&#xD;
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc&amp; rpc)&#xD;
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc&amp; rpc)&#xD;
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc&amp; rpc)&#xD;
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc&amp; rpc)&#xD;
   at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)</StackTrace>
                    <Type>System.NullReferenceException</Type>
                </ExceptionDetail>
            </detail>
        </s:Fault>
    </s:Body>
</s:Envelope>

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

1 Ответ

1 голос
/ 18 июня 2020

Вот моя демонстрация:

public class ProposalMessageFormatter : IDispatchMessageFormatter
{
    private readonly IDispatchMessageFormatter formatter;

    public ProposalMessageFormatter(IDispatchMessageFormatter formatter)
    {
        this.formatter = formatter;
    }

    public void DeserializeRequest(Message message, object[] parameters)
    {
        this.formatter.DeserializeRequest(message, parameters);
    }

    public Message SerializeReply(MessageVersion messageVersion, object[] parameters, object result)
    {
        var message = this.formatter.SerializeReply(messageVersion, parameters, result);
        return new ProposalMessage(message);
    }
}

Это ProposalMessageFormatter.

public class MyOperationBehavior : IOperationBehavior
{
    public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters)
    {
        return;
    }
    public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
    {
        return;
    }
    public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
    {
        dispatchOperation.Formatter = new ProposalMessageFormatter(dispatchOperation.Formatter);
    }
    public void Validate(OperationDescription operationDescription)
    {
        return;
    }
}

Это MyOperationBehavior.

[AttributeUsage(AttributeTargets.Interface, AllowMultiple = false)]
public class MyContractBehaviorAttribute : Attribute, IContractBehavior
{
    public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {
        return;
    }

    public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
        return;
    }
    public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
    {
        OperationDescription op = contractDescription.Operations[0];
        op.Behaviors.Add(new MyOperationBehavior());

    }
    public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
    {
        return;
    }
}

Это - MyContractBehaviorAttribute.Add MyOperationBehavior в конечную точку через MyContractBehaviorAttribute.

enter image description here

Наконец, мы добавляем этот атрибут в службу WCF.

...