Передача динамического json-объекта на контроллер С# MVC

Я выполняю некоторую работу с .Net 4, MVC 3 и jQuery v1.5

У меня есть объект JSON, который может меняться в зависимости от того, какая страница его вызывает. Я хотел бы передать объект контроллеру.

{ id: 1, title: "Some text", category: "test" }

Я понимаю, что если я создаю пользовательскую модель, например

[Serializable]
public class myObject
{
    public int id { get; set; }
    public string title { get; set; }
    public string category { get; set; }
}

и использовать это в моем контроллере, например

public void DoSomething(myObject data)
{
    // do something
}

и передать объект с помощью jQuery.ajax, например:

$.ajax({ 
    type: "POST", 
    url: "/controller/method", 
    myjsonobject,  
    dataType: "json", 
    traditional: true
});

Это отлично работает, мой объект JSON сопоставляется с моим объектом С#. То, что я хотел бы сделать, это передать объект JSON, который может измениться. Когда он изменяется, я не хочу добавлять элементы в свою модель С# каждый раз, когда изменяется объект JSON.

Возможно ли это? Я попытался сопоставить объекты с Словарем, но значение данных просто закончилось бы нулевым.

Спасибо

Ответ 1

Предположительно действие, принимающее вход, используется только для этой конкретной цели, поэтому вы можете просто использовать объект FormCollection, а затем все ваши json-свойства вашего объекта будут добавлены в коллекцию строк.

[HttpPost]
public JsonResult JsonAction(FormCollection collection)
{
    string id = collection["id"];
    return this.Json(null);
}

Ответ 2

Вы можете отправить JSON и проанализировать его как динамически, если вы используете такую ​​оболочку:

JS:

var data = // Build an object, or null, or whatever you're sending back to the server here
var wrapper = { d: data }; // Wrap the object to work around MVC ModelBinder

С#, InputModel:

/// <summary>
/// The JsonDynamicValueProvider supports dynamic for all properties but not the
/// root InputModel.
/// 
/// Work around this with a dummy wrapper we can reuse across methods.
/// </summary>
public class JsonDynamicWrapper
{
    /// <summary>
    /// Dynamic json obj will be in d.
    /// 
    /// Send to server like:
    /// 
    /// { d: data }
    /// </summary>
    public dynamic d { get; set; }
}

С#, действие контроллера:

public JsonResult Edit(JsonDynamicWrapper json)
{
    dynamic data = json.d; // Get the actual data out of the object

    // Do something with it

    return Json(null);
}

Раздражать, чтобы добавить обертку на стороне JS, но просто и чисто, если вы можете пройти мимо нее.

Update

Вы также должны переключиться на Json.Net в качестве парсера JSON по умолчанию, чтобы это работало; в MVC4 по какой-то причине они заменили почти все на Json.Net, кроме сериализации и десериализации контроллера.

Это не очень сложно - следуйте этой статье: http://www.dalsoft.co.uk/blog/index.php/2012/01/10/asp-net-mvc-3-improved-jsonvalueproviderfactory-using-json-net/

Ответ 3

Используя пользовательский ModelBinder, вы можете получить JsonValue в качестве параметра действия. Это в основном даст вам динамически типизированный объект JSON, который может быть создан на клиенте с любой формой, какой вы хотите. Этот метод описан в этом сообщении в блоге.

Ответ 5

Как и принятый ответ FormCollection, динамические объекты также могут отображаться в произвольный JSON.

Единственное предостережение заключается в том, что вам нужно привести каждое свойство к предполагаемому типу, иначе MVC будет жаловаться.

Например, в TS/JS:

var model: any = {};
model.prop1 = "Something";
model.prop2 = "2";

$http.post("someapi/thing", model, [...])

MVC С#:

[Route("someapi/thing")]
[HttpPost]
public object Thing(dynamic input)
{
    string prop1 = input["prop1"];
    string prop2 = input["prop2"];

    int prop2asint = int.Parse(prop2);

    return true;
}