【问题标题】:How to serialize a raw json field?如何序列化原始 json 字段?
【发布时间】:2013-03-27 14:34:34
【问题描述】:

我在数据库中有一个存储 json 字符串的字段 我希望当我以 json 结果返回它时,该结果将作为 json 原始数据返回,而不是用引号作为字符串扭曲。

更新 1(更多信息): 如果您查看图像字段,它包含原始 json 字符串值
但是在使用 JsonResult 对其进行序列化之后,它会被引号扭曲,因为它是一种字符串, 如何告诉序列化程序将图像字段视为原始 json 数据?

        var db = new ModelsContainer();
        var res = db.Images.OrderByDescending(i=>i.DateCreated).Skip(skip).Take(take).Select( i => new {
            id = i.Id,
            dateCreated = i.DateCreated,
            images =  i.Images ,
            user = new {
                id = i.User.Id,
                facebookId = i.User.FacebookId,
                displayName = i.User.DisplayName
            },
            tags = i.Tags.Select( t => t.Value )
        }).ToList();

        return Json(res, JsonRequestBehavior.AllowGet);

     [
        {
            "id":"5c528e88-f3a7-4b30-9746-980867325fd1",
            "dateCreated":"\/Date(1364381593000)\/",
            "images":"[{\"source\":\"http://localhost:9242/images/f4956702/6d34/42db/b28a/397d0eaf3097.jpg\",\"width\":237,\"height\":237},{\"source\":\"http://localhost:9242/images/87d47041/1522/4d10/9325/105851aae259.jpg\",\"width\":633,\"height\":633},{\"source\":\"http://localhost:9242/images/2a639272/9067/42fb/83ee/e88f0a0878f8.jpg\",\"width\":547,\"height\":547},{\"source\":\"http://localhost:9242/images/37caa7b2/e183/4efc/96eb/487e556501b2.jpg\",\"width\":1024,\"height\":1024}]",
            "user":{"id":"ea39616d-6ff9-424b-b99b-7bee53e674bb","facebookId":"608215901","displayName":"Yonathan Garti"},
            "tags":["test","test","test"]
        },
        ...
    ]

【问题讨论】:

    标签: c# asp.net-mvc linq json.net javascriptserializer


    【解决方案1】:

    使用 Json.net,您可以定义自己的 JsonConverters 来应用特定的序列化行为。您可以将其应用于特定类型,或者,如果您有视图模型,则可以应用于特定属性。

    在您的情况下,您想使用 JsonWriter.WriteRawValue 将图像字符串写为原始字符串。

    即。

    public class PlainJsonStringConverter : Newtonsoft.Json.JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(string);
        }
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            return reader.Value;
        }
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            writer.WriteRawValue((string)value);
        }
    }
    
    public class MyViewModel
    {
        public string id { get; set; }
        [Newtonsoft.Json.JsonConverter(typeof(PlainJsonStringConverter))]
        public string images { get; set; }
        /* ...  */
    }
    

    【讨论】:

    • 您的解决方案很棒!!!但不幸的是我无法实现它,因为我的类是由实体框架生成的。有没有办法告诉序列化程序需要类型转换器的一个字段而不是使用属性?
    • 另一种解决方案是,如果您有自定义类型,则 JsonConverter 可以处理,但在您的情况下,我相信它是一个纯字符串,因此无法正常工作。我的建议是创建一个自定义视图模型。在上面的代码中,您只需要使用该自定义视图模型而不是您初始化的匿名对象 (res)。
    • 天才!!!我怎么没看到我只需要用某个模型替换匿名类型,然后我就可以应用该属性了!!!谢谢各位。
    • 即使你不能用属性装饰生成的属性,你也可以提供一个自定义的 ContractResolver 给序列化器,它会在运行时添加这个转换器。看看this question。在 CreateProperties 覆盖中,您需要检查您的特定类型并将转换器添加到 images 的 JsonProperty。
    【解决方案2】:

    您需要反序列化数据。 C# 提供了一个类来处理 JSON 数据。

    http://msdn.microsoft.com/en-us/library/system.runtime.serialization.json.datacontractjsonserializer.aspx

    摘自http://msdn.microsoft.com/en-us/library/bb412179.aspx

    通常,当您在通过启用 AJAX 的端点公开的服务操作中使用数据协定类型时,Windows Communication Foundation (WCF) 会自动处理 JSON 序列化和反序列化。但是,在某些情况下,您可能需要直接使用 JSON 数据 - 这是本主题演示的场景。

    //Deserialize the JSON-encoded data into a new instance of Person by using the ReadObject method of the DataContractJsonSerializer.
    
    stream1.Position = 0;   
    Person p2 = (Person)ser.ReadObject(stream1);
    
    //Show the results.
    
    Console.Write("Deserialized back, got name=");
    Console.Write(p2.name);
    Console.Write(", age=");
    Console.WriteLine(p2.age);
    

    【讨论】:

    • 我不认为你理解我的问题请阅读我的更新谢谢!
    猜你喜欢
    • 2019-05-17
    • 2022-11-24
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多