WCF IDispatchMessageFormatter 空

WCF IDispatchMessageFormatter null

我正在传递一个 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>    

当我传入一个对象然后实例化这个 class

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 为空 我怀疑这可能是问题的原因

我正在为我的 DI 和我的 global.asax.cs 使用 autofac,并且没有像这些示例那样引用和引用它

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

返回的错误是

The server was unable to process the request due to an internal error. For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the <serviceDebug> configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework SDK documentation and inspect the server trace logs.

现在关于这个错误的更多细节

<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>

正如您从请求中看到的那样,这不是空的,并且在更改之前正在工作所以想知道我可能错过了什么。

这是我的演示:

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 到端点的 MyContractBehaviorAttribute.Add MyOperationBehavior。

最后,我们将此属性添加到 WCF 服务。