Преобразование JObject & CamelCase с помощью JSON.Net

Как я могу преобразовать общий JObject в прямую строку json camelCase? Я пробовал с JsonSerializerSettings, но не работает (Newtonsoft.Json 4.5.11)

[Test]
public void should_convert_to_camel_case()
{
    var serializer = JsonSerializer.Create(new JsonSerializerSettings()
    {
        ContractResolver = new CamelCasePropertyNamesContractResolver()
    });

    var jo = new JObject();
    jo["CamelCase"] = 1;

    var stringWriter = new StringWriter();
    var writer = new JsonTextWriter(stringWriter);
    serializer.Serialize(writer,jo);

    var serialized = stringWriter.ToString();

    Assert.AreEqual("{\"camelCase\":1}", serialized);
}

UPDATE Согласно http://json.codeplex.com/workitem/23853, который не может быть выполнен (tnx to @nick_w для ссылки)

Ответ 1

Этот вопрос начинается с JObject и хочет работать с объектом JSON с верблюжьей оболочкой. Если вы действительно начинаете с объекта и хотите попасть в объект JObject, который уже есть на камне, вы можете сделать это:

var serializer = new JsonSerializer()
{
    ContractResolver = new CamelCasePropertyNamesContractResolver()
};
var jo = JObject.FromObject(someDataContract, serializer);

Получаемый "jo" будет спрятан на камне.

Ответ 2

Согласно this, при сериализации JObject таким образом, распознаватель контракта игнорируется. Вдохновленный обходным путем на этой странице, вы можете сделать что-то вроде этого:

var jo = new JObject();
jo["CamelCase"] = 1;

string json = JsonConvert.SerializeObject(jo);
var jObject = JsonConvert.DeserializeObject<ExpandoObject>(json);

var settings = new JsonSerializerSettings()
{
    ContractResolver = new CamelCasePropertyNamesContractResolver()
};

var serialized = JsonConvert.SerializeObject(jObject, settings);

Assert.AreEqual("{\"camelCase\":1}", serialized);

Edit:

Хорошая мысль о Dictionary<string, object>. Таким образом, это пропускает дополнительный JsonConvert.SerializeObject, но также уменьшает необходимость в ExpandoObject, что важно, если вы используете .NET 3.5.

Dictionary<string, object> jo = new Dictionary<string, object>();
jo.Add("CamelCase", 1);

var settings = new JsonSerializerSettings()
{
    ContractResolver = new CamelCasePropertyNamesContractResolver()
};

var serialized = JsonConvert.SerializeObject(jo, settings);

Assert.AreEqual("{\"camelCase\":1}", serialized);

Ответ 3

По состоянию на this 8 мая 2013 г. в блоге Джеймса Ньютона-короля относительно выпуска Json.NET версии 5.0 это было рассмотрено с помощью добавление "DefaultSettings". Ниже приведен пример с этой страницы, но читайте страницу для деталей для сторонних библиотек.

// settings will automatically be used by JsonConvert.SerializeObject/DeserializeObject
JsonConvert.DefaultSettings = () => new JsonSerializerSettings
    {
    Formatting = Formatting.Indented,
    ContractResolver = new CamelCasePropertyNamesContractResolver()
    };

Employee e = new Employee
    {
    FirstName = "Eric",
    LastName = "Example",
    BirthDate = new DateTime(1980, 4, 20, 0, 0, 0, DateTimeKind.Utc),
    Department = "IT",
    JobTitle = "Web Dude"
    };

string json = JsonConvert.SerializeObject(e);
// {
//   "firstName": "Eric",
//   "lastName": "Example",
//   "birthDate": "1980-04-20T00:00:00Z",
//   "department": "IT",
//   "jobTitle": "Web Dude"
// }