Передача динамического 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, который может быть создан на клиенте с любой формой, какой вы хотите. Этот метод описан в этом сообщении в блоге.
Ответ 4
Другим решением является использование динамического типа в вашей модели. Я написал сообщение в блоге о том, как привязываться к динамическим типам с помощью ValueProviderFactory http://www.dalsoft.co.uk/blog/index.php/2012/01/10/asp-net-mvc-3-improved-jsonvalueproviderfactory-using-json-net/
Ответ 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;
}