Вернуть неструктурированный BsonDocument как свойство класса в ApiController

Подобно этому вопросу, у меня есть класс с несколькими различными типами свойств, включая BsonDocument.

public class Report
{
    [BsonId, JsonIgnore]
    public ObjectId _id { get; set; }

    public string name { get; set; }

    [JsonIgnore]
    public BsonDocument layout { get; set; }

    [BsonIgnore, JsonProperty(PropertyName = "layout")]
    public string layout2Json
    {
        get { return layout.ToJson(); }
    }
}

Причина наличия BsonDocument в том, что свойство макета неструктурировано, и у меня не может быть строго типизированных подклассов. Теперь, когда ApiController возвращает этот класс, я получаю что-то вроде этого:

{
    name: "...",
    layout: "{type: "...", sth: "..."}"
}

Но мне нужно свойство макета как объект, а не строка.

Есть ли способ в JSON.NET подключить строку json, которая уже является действительной json, как объект, а не строку?

Следующие работы, но кажутся довольно расточительным:

[BsonIgnore, JsonProperty(PropertyName = "layout")]
public JObject layout2Json
{
    get { return JObject.Parse(layout.ToJson()); }
}

person Benjamin E.    schedule 14.10.2012    source источник


Ответы (1)


У меня была аналогичная проблема. Я решил эту проблему, реализовав собственный JsonConverter, который ничего не будет делать, кроме как записывать необработанные значения (которые уже являются Json) в средство записи Json:

public class CustomConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return true;
    }

    public override object ReadJson(Newtonsoft.Json.JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override void WriteJson(Newtonsoft.Json.JsonWriter writer, object value, JsonSerializer serializer)
    {
        writer.WriteRaw((string)value);
    }
}

Затем вы используете этот пользовательский преобразователь для украшения свойства, которое возвращает строковое представление вашего объекта BsonDocument:

public class Report
{
    [BsonId, JsonIgnore]
    public ObjectId _id { get; set; }

    public string name { get; set; }

    [JsonIgnore]
    public BsonDocument layout { get; set; }

    [BsonIgnore, JsonProperty(PropertyName = "layout")]
    [JsonConverter(typeof(CustomConverter))]
    public string layout2Json
    {
        get { return layout.ToJson(); }
    }
}

Таким образом, вы избавитесь от проблемы с двойными кавычками, а неструктурированный объект будет возвращен как действительный объект Json, а не как строка. Надеюсь, это поможет.

person user1478550    schedule 24.10.2012