ASP.NET MVC как передать объект JSON из представления в контроллер в качестве параметра


у меня есть сложный объект JSON, который отправляется в представление без каких-либо проблем (как показано ниже), но я не могу понять, как сериализовать эти данные обратно в объект .NET, когда он передается обратно контроллеру через вызов AJAX. Детали различных частей ниже.

   var ObjectA = {
        "Name": 1,
        "Starting": new Date(1221644506800),

        "Timeline": [
            {
                "StartTime": new Date(1221644506800),
                "GoesFor": 200

            }
            ,
            {
                "StartTime": new Date(1221644506800),
                "GoesFor": 100

            }

        ]
    };

Я не уверен, как этот объект может быть передан методу контроллера, у меня есть этот метод ниже, где объект Timelines отражает вышеупомянутый объект JS с помощью свойств.

public JsonResult Save(Timelines person)

В jQuery я использую это:

        var encoded = $.toJSON(SessionSchedule);

        $.ajax({
            url: "/Timeline/Save",
            type: "POST",
            dataType: 'json',
            data: encoded,
            contentType: "application/json; charset=utf-8",
            beforeSend: function() { $("#saveStatus").html("Saving").show(); },
            success: function(result) {
                alert(result.Result);
                $("#saveStatus").html(result.Result).show();
            }
        });

Я видел этот вопрос, который похож, но не совсем такой, как я не использую формы для работы с данными. Как передать сложный тип с помощью json ASP.NET контроллер MVC

Я также видел ссылки на использование "JsonFilter" для ручной десериализации JSON, но мне было интересно, есть ли способ сделать это изначально, хотя ASP.NET MVC? Или каковы наилучшие методы передачи данных таким образом?

6   51   2009-02-18 13:49:07

6 ответов:

Edit:

этот метод больше не нужен с приходом MVC 3, так как он будет обрабатываться автоматически - http://weblogs.asp.net/scottgu/archive/2010/07/27/introducing-asp-net-mvc-3-preview-1.aspx


вы можете использовать этот ObjectFilter:

    public class ObjectFilter : ActionFilterAttribute {

    public string Param { get; set; }
    public Type RootType { get; set; }

    public override void OnActionExecuting(ActionExecutingContext filterContext) {
        if ((filterContext.HttpContext.Request.ContentType ?? string.Empty).Contains("application/json")) {
            object o =
            new DataContractJsonSerializer(RootType).ReadObject(filterContext.HttpContext.Request.InputStream);
            filterContext.ActionParameters[Param] = o;
        }

    }
}

затем вы можете применить его к вашим методам контроллера следующим образом:

    [ObjectFilter(Param = "postdata", RootType = typeof(ObjectToSerializeTo))]
    public JsonResult ControllerMethod(ObjectToSerializeTo postdata) { ... }

Так что в основном, если тип контента сообщения "application/json" это приведет к действию и сопоставит значения с объектом указанного типа.

вы говорите: "Я не использую формы для работы с данными.- Но вы же занимаетесь почтой. Поэтому вы, по сути, используете форму, даже если она пуста.

$.тип сообщает jQuery, какой тип сервера будет возвращение, а не то, что вы проходите. Сообщение может только передать форму. jQuery преобразует данные в пары ключ / значение и передать его в качестве строки запроса. Из документов:

данные для отправки на сервер. Это преобразуется в строку запроса, если нет уже ниточка. Он прилагается к url для GET-запросов. См. раздел processData возможность предотвратить это автоматически обработка. Объект должен быть ключом / значением пары. Если значение является массивом, jQuery сериализует несколько значений с одинаковыми ключ т. е. {foo: ["bar1", " bar2"]} становится '&foo=bar1&foo=bar2'.

таким образом:

  1. вы не передаете JSON на сервер. Вы передаете JSON в jQuery.
  2. модель привязка происходит так же, как и в любом другом случае.

другое взятие с простым плагином jQuery

хотя ответы на этот вопрос давно назрели, но я все еще публикую хорошее решение, с которым я пришел некоторое время назад, и делает его очень простым отправить сложный JSON Asp.net MVC действия контроллера, поэтому они привязаны к модели с любыми сильными параметрами типа.

плагин поддержка даты так же хорошо, поэтому они преобразуются в их DateTime аналог без a проблема.

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

все, что вам нужно сделать, это использовать этот плагин на стороне клиента. Запрос Ajax будет выглядеть так:

$.ajax({
    type: "POST",
    url: "SomeURL",
    data: $.toDictionary(yourComplexJSONobject),
    success: function() { ... },
    error: function() { ... }
});

но это только часть всей проблемы. Теперь мы можем отправить сложный JSON обратно на сервер, но поскольку он будет привязан к сложному типу, который может иметь атрибуты проверки свойства вещи могут потерпеть неудачу в этот момент. У меня есть решение для него также. Мое решение использует функциональность jQuery Ajax, где результаты могут быть успешными или ошибочными (как показано в верхнем коде). Поэтому, когда проверка завершится неудачей,error функция будет вызываться так, как это должно быть.

этот ответ является продолжением ответа DaRKoN_, который использовал фильтр объектов:

[ObjectFilter(Param = "postdata", RootType = typeof(ObjectToSerializeTo))]
    public JsonResult ControllerMethod(ObjectToSerializeTo postdata) { ... }

у меня возникла проблема с тем, как отправить несколько параметров в метод действия, и один из них будет объектом json, а другой-простой строкой. Я новичок в MVC и я просто забыл, что я уже решил эту проблему с ajaxed видом.

что бы я сделал, если бы мне понадобились, скажем, два разных объекта на виде. Я хотел бы создать класс модели представления. Так скажем, Мне нужен объект person и объект address, я бы сделал следующее:

public class SomeViewModel()
{
     public Person Person { get; set; }
     public Address Address { get; set; }
}

тогда я бы привязал представление к SomeViewModel. Вы можете сделать то же самое с JSON.

[ObjectFilter(Param = "jsonViewModel", RootType = typeof(JsonViewModel))] // Don't forget to add the object filter class in DaRKoN_'s answer.
public JsonResult doJsonStuff(JsonViewModel jsonViewModel)
{
     Person p = jsonViewModel.Person;
     Address a = jsonViewModel.Address;
     // Do stuff
     jsonViewModel.Person = p;
     jsonViewModel.Address = a;
     return Json(jsonViewModel);
}

тогда в представлении вы можете использовать простой вызов с JQuery следующим образом:

var json = { 
    Person: { Name: "John Doe", Sex: "Male", Age: 23 }, 
    Address: { Street: "123 fk st.", City: "Redmond", State: "Washington" }
};

$.ajax({
     url: 'home/doJsonStuff',
     type: 'POST',
     contentType: 'application/json',
     dataType: 'json',
     data: JSON.stringify(json), //You'll need to reference json2.js
     success: function (response)
     {
          var person = response.Person;
          var address = response.Address;
     }
});

в ответ на комментарий дан выше:

Я использую этот метод, чтобы реализовать то же самое, но почему-то я я получаю исключение на Метод ReadObject: "ожидающий элемент "корень" из пространства имен ".. Встречающийся "Нет" с именем ", пространство имен "." Есть идеи почему? - Дэн Эпплярд Апр 6 '10 в 17:57

У меня была та же проблема (MVC 3 build 3.0.11209.0), и сообщение ниже решило ее для меня. В основном json сериализатор пытается прочитать поток, который не находится в начале,поэтому перемещение потока в 0 'исправлено'...

http://nali.org/asp-net-mvc-expecting-element-root-from-namespace-encountered-none-with-name-namespace/