如何根据参数从RESTful WCF调用返回CSV或JSON

本文关键字:返回 调用 CSV JSON WCF RESTful 何根 参数 | 更新日期: 2023-09-27 18:28:14

想象一下,我需要返回一个用户列表,结果必须是CSV或JSON格式。

/用户?format=json返回json/用户?format=csv返回csv

我试图通过一个返回对象的方法来实现它:

// interface
[OperationContract]
[WebInvoke(Method = "GET", UriTemplate = "users?format={format}", BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
[ServiceKnownType(typeof(List<UserInfo>))]
[ServiceKnownType(typeof(Stream))]
object GetUsers(string format);

实现返回流或用户列表:

    public object GetUsers(string format)
    {
        if (format == null) format = "json";
        switch (format.ToLower())
        {
            case "json":
                return GetUsersJson(); // returns List<UserInfo>
            case "csv":
                return GetUsersCsv(); // returns MemoryStream
            default:
                return BadRequest("Invalid content format: " + format);
        }
    }

当我运行这个时,JSON版本可以工作,但CSV版本失败,出现序列化异常:

System.Runtime.Serialization.Serialization异常:类型具有数据协定名称的"System.IO.MemoryStream"'内存流:http://schemas.datacontract.org/2004/07/System.IO'是不应为。

如果我用ServiceKnownType(typeof(MemoryStream))替换ServiceKnownType(typeof(Stream)),也没有例外,但下载的文件包含MemoryStream:的JSON表示

{"__identity":null,"_buffer":[78,97109,…,0,0,0,0],"_capacity":256,"_expandable":true,"_exposable":true,"_isOpen":true、"_length":74,"_origin":0,"_position":74,"_writeable":true}

这并不是我在返回流时所想的:)

那么,有没有一种方法可以多态地返回Stream,或者我必须使用两个不同的调用?

如何根据参数从RESTful WCF调用返回CSV或JSON

您的响应格式设置为WebMessageFormat.Json,这就是WCF返回JSON的原因。实现所需功能的一种方法是使用WCF"Raw"编程模型,这意味着将方法的返回类型更改为Stream。完成此操作后,您将告诉WCF您希望控制响应,并且它不会对数据应用任何格式。然后,您可以使用内置的DataContractJsonSerializer(或任何其他序列化程序)将JSON字符串序列化为流。在任何一种情况下,都要确保将WebOperationContext.Current.OutgoingResponse.ContentType设置为适当的值。