我正在尝试从 Redis 获得类似 CouchDB 的响应 - 通过使用 ServiceStack WebServices 访问通过 ServiceStack .Net RedisTypedClient 存储到 Redis 上的数据。
现在 Web 服务被描述为在 Redis 上提供一个 CouchDB 层。但是,与对 CouchDB 的等效 CouchDB 调用不同,我从不返回 json,而只返回字符串- 需要明确的是,我确实返回了 json,但有效负载是字符串格式。
这适用于从 Redis List、Set 和 HashSet 集合中获取项目。通过 xml、json 或 csv Web 服务的所有项目始终将有效负载作为字符串传递。现在我可以看到存储在字符串中的类型的序列化形式 - 例如字符串的 json 数组或其他任何内容,但数据不是作为 json(或 csv 或 xml)传递,而是作为字符串传递。我在这些 Web 服务的任何自动生成的文档中都找不到查询标志(例如“格式 = json”)——这确实表明它将有效负载作为我看到的字符串提供。
除了通过 RedisTypedCLient 使用默认的 jsv 序列化器之外,我还尝试直接调用 ServiceStack json 序列化器来序列化为 json 而不是 jsv 以及 Newtonsoft json 序列化器。这些都没有任何区别。我也没料到它,因为我想默认服务可能只管理预期的 jsv 版本,并将其他任何东西作为字符串提供。但是我没想到内部序列化格式会这样。
那么是否有可能从 ServiceStack/Redis/Builtin-WebServices 获得 CouchDB 之类的 json 响应?
更新
这是通过 ServiceStack json Web 服务进行的典型查询:
http://myserver.com/redis/json/syncreply/GetAllItemsFromList?id=test
这是一个包含强类型项的 Redis 列表集合:
type TestItem( gr,eType,pillar,offset) =
let mutable _gr = gr
let mutable _eType = eType
let mutable _pillar = pillar
let mutable _offset = offset
member x.Gr with get()= _gr and set(v) = _gr <- v
member x.EType with get()= _eType and set(v) = _eType <- v
member x.Pillar with get()= _pillar and set(v) = _pillar <- v
member x.Offset with get()= _offset and set(v) = _offset <- v
override x.ToString() = sprintf "%s %s %s %M" x.Gr x.EType x.Pillar x.Offset
列表集合是使用 IRedisTypedClient 接口/API 添加的,我期待返回一个 json 对象的 json 列表 - 一组键/值对,每对对应于上述类型中的四个公共属性之一。相反,我得到
{"Items":[" {\"Gr\":\"BON13\",\"EType\":\"MARKET\",\"Pillar\":\"BON3.R0\",\"Offset\":0.0}","{\"Gr\":\"BOQ13\",\"EType\":\"MARKET\",\"Pillar\":\"BOQ3.R0\",\"Offset\":0.0}","{\"Gr\":\"BOU13\",\"EType\":\"MARKET\",\"Pillar\":\"BOU3.R0\",\"Offset\":0.0}","{\"Gr\":\"BOV13\",\"EType\":\"SETTLEPILLAR\",\"Pillar\":\"BOU3.R0\",\"Offset\":0.0}","{\"Gr\":\"BOZ16\",\"EType\":\"SETTLEPILLAR\",\"Pillar\":\"BOU3.R0\",\"Offset\":0.0}"],"ResponseStatus":{}}
换句话说,json 对象的字符串表示,而不是 json 对象本身。
再说一遍,在这种情况下,我怎样才能找回 json 对象的 json 列表而不是字符串的 json 列表。(与其他 NoSql 数据库一样,集合、字典和更基本的键控 json 文档也是如此)?
我在返回 csv 时遇到了同样的问题 - 它作为字符串返回,而不是键/值对的 csv 或键和值的 csv,在 XML 中,它再次作为字符串而不是 XML 格式返回键/值对。
更新 1
它不需要像上面那样是强类型的。它可以是字符串列表的列表。在这种情况下,我会返回一个 json 字符串列表,而不是一个包含包含 json 字符串列表的项目的 json 列表。
更新 2 虽然问题显然出在 ServiceStack webservice 实现中,尽管它声称它不像 CouchDB ,但这里有一些示例代码通过 ServiceStack 将数据放入 Redis。
open System
open System.Collections.Generic
open ServiceStack.Redis
open System.Linq
type Repository() =
static let mutable __port = 6379
static let mutable __host = "myserver.com"
static let mutable __client = new RedisClient(__host,__port)
static member Client = __client :> IRedisClient
type Repository<'T>() =
let _client = Repository.Client
member x.GetList key =
use client = _client.As<'T>()
match _client.GetEntryType key with
| RedisKeyType.List ->
client.Lists.Item key |> client.GetAllItemsFromList
| _ -> new List<'T>()
member x.SetList (key, values: List<'T>) =
if (values.Count <> 0) then
use client = _client.As<'T>()
let list = client.Lists.Item key
values |> Seq.iter (fun x -> client.AddItemToList(list, x))
用法
let repo = new Repository<List<string>>
let items = [["key0";"data0"];["key1";"data1"]]
|> Seq.map (fun kd -> List.init kd ))
|> List.init
repo.SetList("test",items)
这只是较长代码的剪切和粘贴。我已经在 c#、f# 和非默认序列化中尝试过,如前所述。也就是说,迄今为止我已经尝试了六种不同的方法,但没有一种方法仅通过 ServiceStack WebServices 将数据有效负载作为 json 对象作为字符串传递。