【问题标题】:Controlling WCF response format and namespaces控制 WCF 响应格式和命名空间
【发布时间】:2013-03-02 09:57:42
【问题描述】:

我希望我的 WCF 响应有一个响应元素,其中包含两个使用 DataContracts 的命名空间,但我无法让它工作。这就是我希望得到的响应:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <s:Header />
  <s:Body>
    <ns2:TestReply xmlns="http://www.test.org/test/2007/00" xmlns:ns2="http://www.test2.org/test2/types">
      <ns2:Result>
        <ns2:ActionSuccessful>true</ns2:ActionSuccessful>
      </ns2:Result>
      <ns2:ResultData>
        <ns2:Name>Maikel Willemse</ns2:Name>
      </ns2:ResultData>
    </ns2:TestReply>
  </s:Body>
</s:Envelope>

这是我得到的响应(使用 WCF 测试客户端进行测试时):

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header />
  <s:Body>
    <GetDataResponse xmlns="http://www.test.org/test/2007/00">
      <TestReply xmlns:a="http://www.test2.org/test2/types" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
        <a:Result>
          <a:ActionSuccessful>true</a:ActionSuccessful>
        </a:Result>
        <a:ResultData>
          <a:Name>Maikel Willemse</a:Name>
        </a:ResultData>
      </TestReply>
    </GetDataResponse>
  </s:Body>
</s:Envelope>

我的服务界面是这样的:

[ServiceContract(Namespace = "http://www.test.org/test/2007/00")]
public interface IService1
{
    [OperationContract]
    [return: MessageParameter(Name = "TestReply")]
    GetDataResponse GetData(string name);
}

服务类:

public class Service1 : IService1
{
    public GetDataResponse GetData(string name)
    {
        return new GetDataResponse
            {
                Result = new Result {ActionSuccessful = true},
                ResultData = new ResultData {Name = name}
            };
    }
}

DataContract 类是:

[DataContract(Namespace = "http://www.test2.org/test2/types")]
public class GetDataResponse
{
    [DataMember(Name = "Result")]
    public Result Result { get; set; }

    [DataMember(Name = "ResultData")]
    public ResultData ResultData { get; set; }
}

[DataContract(Namespace = "http://www.test2.org/test2/types")]
public class Result
{
    [DataMember(Name = "ActionSuccessful")]
    public bool ActionSuccessful { get; set; }
}

[DataContract(Namespace = "http://www.test2.org/test2/types")]
public class ResultData
{
    [DataMember(Name = "Name")]
    public string Name { get; set; }
}

我的 WCF 项目的目标框架是 .NET 4。命名空间前缀不必相同。如何获得所需格式的响应?

【问题讨论】:

    标签: c# wcf


    【解决方案1】:

    如果您想从响应中删除“包装”元素,您需要使用[MessageContract]。下面的代码显示了如何完成它的一种方法。您可以使用服务/消息/数据合约中的命名空间来匹配您想要的。

    public class StackOverflow_15173138
    {
        [ServiceContract(Namespace = "http://www.test.org/test/2007/00")]
        public interface IService1
        {
            [OperationContract]
            MyResponse GetData(MyRequest request);
        }
    
        public class Service1 : IService1
        {
            public MyResponse GetData(MyRequest request)
            {
                return new MyResponse
                {
                    TestReply = new GetDataResponse
                    {
                        Result = new Result { ActionSuccessful = true },
                        ResultData = new ResultData { Name = request.name }
                    }
                };
            }
        }
    
        [MessageContract(IsWrapped = false)]
        public class MyResponse
        {
            [MessageBodyMember]
            public GetDataResponse TestReply { get; set; }
        }
    
        [MessageContract(WrapperName = "GetData")]
        public class MyRequest
        {
            [MessageBodyMember]
            public string name { get; set; }
        }
    
        [DataContract(Namespace = "http://www.test2.org/test2/types")]
        public class GetDataResponse
        {
            [DataMember(Name = "Result")]
            public Result Result { get; set; }
    
            [DataMember(Name = "ResultData")]
            public ResultData ResultData { get; set; }
        }
    
        [DataContract(Namespace = "http://www.test2.org/test2/types")]
        public class Result
        {
            [DataMember(Name = "ActionSuccessful")]
            public bool ActionSuccessful { get; set; }
        }
    
        [DataContract(Namespace = "http://www.test2.org/test2/types")]
        public class ResultData
        {
            [DataMember(Name = "Name")]
            public string Name { get; set; }
        }
    
        public static void Test()
        {
            string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
            ServiceHost host = new ServiceHost(typeof(Service1), new Uri(baseAddress));
            host.AddServiceEndpoint(typeof(IService1), new BasicHttpBinding(), "");
            host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true });
            host.Open();
            Console.WriteLine("Host opened");
    
            ChannelFactory<IService1> factory = new ChannelFactory<IService1>(new BasicHttpBinding(), new EndpointAddress(baseAddress));
            IService1 proxy = factory.CreateChannel();
            Console.WriteLine(proxy.GetData(new MyRequest { name = "hello" }));
    
            ((IClientChannel)proxy).Close();
            factory.Close();
    
            Console.Write("Press ENTER to close the host");
            Console.ReadLine();
            host.Close();
        }
    }
    

    【讨论】:

    • 感谢您的快速回答,这几乎就是我想要的。 XML 的布局正是我想要的,但是 元素没有“a:”前缀......有什么想法吗?
    • 没有简单的方法可以自定义 WCF 生成的 XML 中的 前缀 - 前缀应该只用于定义命名空间,而且您通常不会选择使用哪个前缀。如果你真的想定制它们,你可以做到,但这并不简单——blogs.msdn.com/b/carlosfigueira/archive/2010/06/13/… 的帖子显示了一种方法。
    • 对不起,我不是这个意思。我不介意前缀是“a”,但我希望 节点(即正文的第一个子节点)也有它:。使用您的代码时, 内的所有节点都有前缀(这很好),但 节点本身没有。
    【解决方案2】:

    致@Maikel TestReply 位于默认命名空间中,因此没有前缀,但里面的元素确实有它。

    xmlns:a="http://www.test2.org/test2/types
    

    所以这个命名空间的前缀是 a。 (因为 'a=')并且它与默认命名空间不同。

    在你的方法的 ServiceContractAttribute 中

    GetDataResponse GetData(string name); 
    

    正如@Carlos 建议的那样,你可以写

    [ServiceContract(Namespace="http://www.test2.org/test2/types")]
    

    你不能拥有这个

    <a:TestReply xmnls:a="http://www.test2.org/test2/types">
    

    【讨论】:

      猜你喜欢
      • 2013-06-25
      • 2011-10-30
      • 2012-07-09
      • 1970-01-01
      • 2010-10-03
      • 1970-01-01
      • 2012-07-08
      • 2014-03-03
      • 1970-01-01
      相关资源
      最近更新 更多