1

我正在尝试从 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 对象作为字符串传递。

4

1 回答 1

1

JSON 数据在序列化并通过网络发送时,只是一个字符串。您的客户端需要了解 JSON 并将其反序列化到您的对象中。ServiceStack 中用于 C# 的 JsonClient 能够处理此问题,许多协助 AJAX 调用的 JavaScript 框架(jQuery、AngularJS 等)也是如此。

于 2013-05-30T12:44:44.893 回答