【问题标题】:WCF remove the default responseWCF 删除默认响应
【发布时间】:2015-10-22 17:45:29
【问题描述】:

我有一个 WCF 服务,其默认响应如下所示:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
   <s:Body/>
</s:Envelope>

我希望它完全不同,例如

<?xml version='1.0' encoding='UTF-8'?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/' 
                   xmlns:xsd='http://www.w3.org/1999/XMLSchema' 
                   xmlns:xsi='http://www.w3.org/1999/XMLSchema-instance'>
   <SOAP-ENV:Body>
       <ns1:methodResponse xmlns:ns1='urn:MyService' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
           <message href='cid:success'/>
       </ns1:methodResponse>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

我尝试将响应手动创建为字符串,然后添加Response.Write(xml)

问题是默认响应(第一个)也发送到客户端,所以我得到了两个响应。

如何阻止 WCF 发送不需要的响应?

【问题讨论】:

  • 在语义上,第二个响应的唯一区别是标签 methodResponse 及其内部 xml。你想添加这个标签还是需要命名空间前缀完全一样?
  • 我只需要用包含首选 XML 的逐字字符串替换默认 XML 数据。我不需要更改名称空间或标题。有可能吗?
  • 我遵循了一些教程并附带了这个 ideone.com/bFbnGk 但是我不知道如何使它工作(可能我不知道如何将检查器添加到 web.config 中)我仍然获取默认响应。 THX

标签: c# wcf


【解决方案1】:

更好的方法是将响应替换implementing IDispatchMessageInspector and modifying the message in BeforeSendReply - 使用来自the example you mentioned 的类:

public class CustomInspector : IDispatchMessageInspector
{
    public object AfterReceiveRequest(ref Message request, IClientChannel channel,
    InstanceContext instanceContext)
    {
        return null;
    }

    public void BeforeSendReply(ref Message reply, object correlationState)
    {
        reply = ChangeResponse(reply);
    }

    private Message ChangeResponse(Message oldMessage)
    {
       // change message
    }
}

然后你需要创建支持类:

public class CustomExtension : BehaviorExtensionElement
{
    protected override object CreateBehavior()
    {
        return new CustomBehavior();
    }

    public override Type BehaviorType
    {
        get
        {
            return typeof(CustomBehavior);
        }
    }
}
public class CustomBehavior : IServiceBehavior
{
    public void ApplyDispatchBehavior(ServiceDescription serviceDescription,
    ServiceHostBase serviceHostBase)
    {
        foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers.OfType<ChannelDispatcher>())
        {
            foreach (var endpoint in dispatcher.Endpoints)
            {
                endpoint.DispatchRuntime.MessageInspectors.Add(new CustomInterceptor());
            }
        }
    }

    public void AddBindingParameters(ServiceDescription serviceDescription,
        ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints,
        BindingParameterCollection bindingParameters)
    {
    }

    public void Validate(ServiceDescription serviceDescription,
        ServiceHostBase serviceHostBase)
    {
    }
}

这允许您在服务配置中声明检查器:将此文本添加到 &lt;system.serviceModel&gt; 部分(将 Your.Namespace 替换为实际的类命名空间):

<extensions>
  <behaviorExtensions>
    <!-- Replace default response -->
    <add name="CustomExtension"
          type="Your.Namespace.CustomExtension, Your.Namespace, 
                Version=1.0.0.0, Culture=neutral" />
  </behaviorExtensions>
</extensions>

最后,将这个新的行为扩展添加到服务行为中。您需要将:defaultBehaviour 替换为实际名称,您可以在 &lt;services&gt;&lt;service name="YourService" behaviorConfiguration="defaultBehaviour"&gt; &lt;!-- &lt; that's the name you want --&gt; 中找到该名称

<behaviors>
  <serviceBehaviors>
    <behavior name="defaultBehaviour">

      <CustomExtension/>

【讨论】:

  • 嗯,我把这个消息类型的方法放在哪里?我什至不确定其中哪些是我的自定义 XML,它是字符串类型(逐字)的变量,例如
  • var xml = @" " ;
  • 嗯,虽然这很有意义,但响应保持不变。我怀疑 web.config csharppad.com/gist/1df60a78f2bac27f1459 如果我做错了什么请告诉我
  • F1 F1 :) 你能给我一个工作的例子吗?只是一个应用了修复程序的基本 WCF 项目?将不胜感激。谢谢
  • 对不起,我正在度假,离 WCF 很远。下周之前什么都做不了..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-02
  • 1970-01-01
  • 1970-01-01
  • 2012-06-18
相关资源
最近更新 更多