从WCF返回多个响应

时间:2010-09-15 16:09:41

标签: c# wcf

我在服务中有一个WCF服务和一个名为GetStudentList()的方法。当它返回单个响应时工作正常。这样的事情

  [WebGet(ResponseFormat = WebMessageFormat.Xml, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
List<Student> GetStudentList();

但是我想要返回多个响应,即xml和json都像这样

  [WebGet(ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
[WebGet(ResponseFormat = WebMessageFormat.Xml, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
List<Student> GetStudentList();

是否可能?如果是,那么如何?

3 个答案:

答案 0 :(得分:19)

可以在.NET 4.0中使用,但不能按照指定的方式使用。 .NET 4.0为WebHttp行为添加了新参数:

  <endpointBehaviors>
    <behavior name="WebHttp">
      <webHttp automaticFormatSelectionEnabled="true" />
    </behavior>
  </endpointBehaviors>

使用自动格式选择时,响应的格式基于:

  • 接受请求中的标头
  • 请求的内容类型
  • 操作中指定的默认格式
  • webHttp行为中指定的默认格式

因此,如果您使用JSON请求调用REST服务,您将获得JSON。如果您使用POX请求调用它,您将获得XML。有关自动格式选择的完整说明,请参见MSDN

答案 1 :(得分:3)

我认为不可能使用一次调用将对象作为Json和XML返回。在这方面,可以将WCF视为正常的方法调用;你调用一个方法,你得到一个序列化的返回值。一旦服务向呼叫者返回了一个响应,呼叫就完成了。

仔细考虑为什么要使用这两种响应类型;它们都是对象序列化的信息性通用标准,并且使用WCF,如果直接使用序列化响应文本,则只需要两者。如果可能的话,我会重构客户端以使用相同的响应类型。

最简单的解决方法,如果真的需要两种类型,就是提供这种方法的两个“重载”,并使每个客户端类型足够聪明,以便知道它需要进行哪个调用。因为差异不在方法签名中,所以它不是真正的重载;您必须通过名称(GetStudentListJSON与GetStudentListXML)或通过在不同的服务类中查找方法来分隔它们。

您还可以始终返回一种响应类型,并在需要以其他格式序列化的对象时通过反序列化/重新序列化在客户端进行转换。这确实要求您使用在控制的客户端控制的.NET代码。

答案 2 :(得分:1)

我不知道从服务操作中获取2个输出的方法。您始终可以获取XML(序列化DataContract),然后“JSON Serialize”。这是你如何做到的。

List<Student> studentList = GetStudent();
string jsonString = JsonSerialize(studentList.GetType(), studentList);

然后将此函数添加到实用程序类:

public static string JsonSerialize(Type type, object objectGraph)
        {
            MemoryStream memoryStream = new MemoryStream();

            try
            {
                System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(type);
                serializer.WriteObject(memoryStream, objectGraph);
                return Encoding.Default.GetString(memoryStream.ToArray());
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (memoryStream != null) memoryStream.Close();
            }
        }