【问题标题】:WCF response: Omit SOAP StructureWCF 响应:省略 SOAP 结构
【发布时间】:2015-03-30 15:03:45
【问题描述】:

我开发了一个完美运行的 .NET WCF Web 服务,它产生 SOAP 响应。

我的问题是响应的 SOAP 格式,导致我的最终客户无法使用我的网络服务。 (他只期望响应的正文内容。)

为了更好地解释这种情况,我重新创建了一个名为“计算器”的 WCF 演示;一个简单的 Web 服务,它执行两个数字的总和。 (1+1)

当我在 SOAP UI 上测试 Web 服务时,我得到以下响应:

<?xml version="1.0" encoding="UTF-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
   <s:Header>
      <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
         <u:Timestamp u:Id="_0">
            <u:Created>2015-03-30T14:31:44.759Z</u:Created>
            <u:Expires>2015-03-30T14:36:44.759Z</u:Expires>
         </u:Timestamp>
      </o:Security>
   </s:Header>
   <s:Body>
      <SumResponse xmlns="http://MY-PC">
         <SumResult>2</SumResult>
      </SumResponse>
   </s:Body>
</s:Envelope>

虽然,我的最终客户希望收到以下响应:(all through a new wsdl

<?xml version="1.0" encoding="UTF-8"?>
<SumResponse xmlns="http://MY-PC">
    <SumResult>2</SumResult>
</SumResponse>

有没有办法在 WCF Web 服务的响应中省略 SOAP 格式? (可能使用 .NET 标准系统库)

如果没有,有什么办法可以在.NET中实现最终结果?

注意
我应该使用 .NET framework 4.0,响应应该有:
内容类型'文本/xml; charset=utf-8'(类似于 SOAP 1.1 格式)

【问题讨论】:

  • 如果您的客户不想要 SOAP,为什么还要创建 SOAP 服务?
  • 因为我不知道。我的交付包括开发一个 Web 服务,它必须由消费者的软件使用。没有其他信息,除了服务的签名和在 .NET 中创建 Web 服务。

标签: .net web-services wcf


【解决方案1】:

您可以尝试使用消息调度程序,但是我不确定您是否愿意这样做,如果您创建一个接口,您的客户端可以轻松获得完整的答案,但返回一个仅包含值的对象。 无论如何,使用消息检查器,您可以编辑要发送的消息,这里是一个示例:

//First you will need to implement 2 interfaces
//IDispatchMessageInspector or IClientMessageInspector and IServiceBehavior or IEndpointBehavior

public class MustUnderstandMessageInspector : IDispatchMessageInspector
{

    public object AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext)
    {
        //Here you can use the ref request(Remember it is a ref, careful what you do with it)
        //request is the message you just received
        SaveInDatabase(request);
        return null;
    }

    public void BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
    {
        //reply is a ref like request and it is the message you are sending
        throw new NotImplementedException();
    }
}

// To be able to implement your MessageInspector in your service you need to create a behavior.
//this behavior will have to be added to your server.

public class UnderstandBehavior : IServiceBehavior
{


    void IServiceBehavior.AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
    {
        //throw new NotImplementedException();
    }

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
        //This will Add your inspector to every dispatcher inside serviceHostBase
        //you will have to use the one your service is on
        foreach (ChannelDispatcher chDisp in serviceHostBase.ChannelDispatchers)
        {
            foreach (EndpointDispatcher epDisp in chDisp.Endpoints)
            {
                epDisp.DispatchRuntime.MessageInspectors.Add(new MustUnderstandMessageInspector());
            }
        }
    }

    void IServiceBehavior.Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
        //throw new NotImplementedException();
    }
}

完成这两个接口后,您必须将行为添加到您的服务中。

{
        svcHost = new ServiceHost(typeof(Service), eventendpoint);
        svcHost.AddServiceEndpoint(typeof(IService), new WSHttpBinding, "Endpoint");
        //Add Service Behavior
        UnderstandBehavior behavior = new UnderstandBehavior();
        svcHost.Description.Behaviors.Add(behavior);
        //////
        svcHost.Open();
        textBox1.Text = textBox1.Text + "\n\nService is Running";
        svcHost.Close();
}

如图所示,您还可以编辑传入的消息,您只需使用所需的消息检查器即可。

【讨论】:

  • 首先,感谢您的宝贵时间,感谢您提供的任何帮助。我不知道您的代码是否可以帮助我,可能我忘记指定必须通过 Web 服务的 wsdl 获得新的响应;因此我希望通过简单地更新客户端软件中的服务引用来解决。
  • 那么肥皂规范将是回答这个问题的那个SOAPWikipedia。恐怕信封部分是强制性的。
猜你喜欢
  • 2020-12-12
  • 1970-01-01
  • 2016-07-01
  • 2011-04-10
  • 2016-02-17
  • 1970-01-01
  • 2020-02-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多