Подтвердить что ты не робот

Проводка данных JSON через jQuery для действия контроллера ASP.NET MVC 4

У меня возникли проблемы с попыткой передать сложный объект JSON в действие контроллера MVC 4. Поскольку содержимое JSON является переменным, я не хочу, чтобы MVC сопоставлял отдельные свойства/элементы JSON с параметрами в списке параметров метода действий. Я просто хочу получить данные как один строковый параметр JSON в действии контроллера.

Здесь подпись моего метода действия:

    [HttpPost]
    [ValidateInput(false)]
    public string ConvertLogInfoToXml(string jsonOfLog)

И вот моя попытка опубликовать некоторые данные JSON из моего браузера:

    data = {prop: 1, myArray: [1, "two", 3]}; 
    //'data' is much more complicated in my real application
    json = {jsonOfLog: data};

    $.ajax({
        type: 'POST',
        url: "Home/ConvertLogInfoToXml",
        data: JSON.stringify(json),
        success: function (returnPayload) {
            console && console.log ("request succeeded");
        },
        error: function (xhr, ajaxOptions, thrownError) {
            console && console.log ("request failed");
        },
        dataType: "xml",
        contentType: "application/json",            
        processData: false,
        async: false
    });

Когда я ударил точку останова в начале метода ConvertLogInfoToXML, jsonOfLog имеет значение null.

Если я изменю значение переменной json в JavaScript, чтобы свойство jsonOfLog было простой строкой, например.

json = { jsonOfLog: "simple string" };

тогда, когда моя точка останова в начале метода ConvertLogInfoToXML попадает, jsonOfLog - это значение строки (например, "простая строка" ).

Я попытался изменить тип параметра jsonOfLog в методе действий для объекта типа:

    [HttpPost]
    [ValidateInput(false)]
    public string ConvertLogInfoToXml(object jsonOfLog)

Теперь, с исходным кодом JavaScript (где я передаю более сложный объект данных), jsonOfLog получает значение {object}. Но отладчик не показывает больше деталей в окне просмотра, и я не знаю, какие методы я могу использовать для работы с этой переменной.

Как передать данные JSON в контроллер MVC, где переданные данные являются сложным сложным объектом?

Спасибо, Notre

4b9b3361

Ответ 1

Проблема заключается в вашем dataType и формате вашего параметра data. Я просто проверил это в песочнице и выполнил следующие работы:

С#

    [HttpPost]
    public string ConvertLogInfoToXml(string jsonOfLog)
    {
        return Convert.ToString(jsonOfLog);
    }

Javascript

<input type="button" onclick="test()"/>

    <script type="text/javascript">

        function test() {
            data = { prop: 1, myArray: [1, "two", 3] };
            //'data' is much more complicated in my real application
            var jsonOfLog = JSON.stringify(data);

            $.ajax({
                type: 'POST',
                dataType: 'text',
                url: "Home/ConvertLogInfoToXml",
                data: "jsonOfLog=" + jsonOfLog,
                success: function (returnPayload) {
                    console && console.log("request succeeded");
                },
                error: function (xhr, ajaxOptions, thrownError) {
                    console && console.log("request failed");
                },

                processData: false,
                async: false
            });
        }

    </script>

Обратите особое внимание на data, при отправке текста вам необходимо отправить переменную, которая соответствует имени вашего параметра. Это некрасиво, но вы получите свою желанную неформатированную строку.

При запуске этого процесса функция jsonOfLog выглядит так:

    jsonOfLog   "{\"prop\":1,\"myArray\":[1,\"two\",3]}"    string

Заголовок HTTP POST:

Key Value
Request POST /Home/ConvertLogInfoToXml HTTP/1.1
Accept  text/plain, */*; q=0.01
Content-Type    application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With    XMLHttpRequest
Referer http://localhost:50189/
Accept-Language en-US
Accept-Encoding gzip, deflate
User-Agent  Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)
Host    localhost:50189
Content-Length  42
DNT 1
Connection  Keep-Alive
Cache-Control   no-cache
Cookie  EnableSSOUser=admin

Тело HTTP POST:

jsonOfLog={"prop":1,"myArray":[1,"two",3]}

Заголовок ответа:

Key Value
Cache-Control   private
Content-Type    text/html; charset=utf-8
Date    Fri, 28 Jun 2013 18:49:24 GMT
Response    HTTP/1.1 200 OK
Server  Microsoft-IIS/8.0
X-AspNet-Version    4.0.30319
X-AspNetMvc-Version 4.0
X-Powered-By    ASP.NET
X-SourceFiles   =?UTF-8?B?XFxwc2ZcaG9tZVxkb2N1bWVudHNcdmlzdWFsIHN0dWRpbyAyMDEyXFByb2plY3RzXE12YzRQbGF5Z3JvdW5kXE12YzRQbGF5Z3JvdW5kXEhvbWVcQ29udmVydExvZ0luZm9Ub1htbA==?=

Тело ответа:

{"prop":1,"myArray":[1,"two",3]}

Ответ 2

Я думаю, вы найдете ответ, если ссылаетесь на этот пост: Deserialize JSON в динамический объект С#?

Существуют различные способы достижения того, что вы хотите здесь. Подход System.Web.Helpers.Json(несколько ответов ниже) кажется самым простым.

Ответ 3

ВЕРСИЯ VB.NET

Хорошо, поэтому я потратил несколько часов на поиски жизнеспособного метода для публикации нескольких параметров в MVC 4 WEB API, но большинство из того, что я нашел, было либо для действия GET, либо просто плоский не работает. Тем не менее, я, наконец, получил эту работу, и я решил поделиться своим решением.

  • Используйте пакеты NuGet для загрузки JSON-js json2 и Json.NET. Шаги по установке пакетов NuGet:

    (1) В Visual Studio перейдите в Веб-сайт > Управление пакетами NuGet... enter image description here

    (2) Введите json (или что-то в этом роде) в строку поиска и найдите JSON-js json2 и Json.NET. Дважды щелкнув по ним, эти пакеты будут установлены в текущий проект. enter image description here

    (3) NuGet автоматически поместит json файл в ~/Scripts/json2.min.js в каталог проекта. Найдите файл json2.min.js и перетащите его в голову вашего сайта. Примечание. Инструкции по установке файлов .js(javascript) читайте это решение.

  • Создайте объект класса, содержащий требуемые параметры. Вы будете использовать это для доступа к параметрам в контроллере API. Пример кода:

    Public Class PostMessageObj
    
    Private _body As String
    Public Property body As String
        Get
            Return _body
        End Get
        Set(value As String)
            _body = value
        End Set
    End Property
    
    
    Private _id As String
    Public Property id As String
        Get
            Return _id
        End Get
        Set(value As String)
            _id = value
        End Set
    End Property
    End Class
    
  • Затем мы настраиваем фактический MVC 4 API-интерфейс API, который мы будем использовать для действия POST. В нем мы будем использовать Json.NET для десериализации строкового объекта при его публикации. Не забудьте использовать соответствующие пространства имен. Продолжая предыдущий пример, вот мой код:

    Public Sub PostMessage(<FromBody()> ByVal newmessage As String)
    
    Dim t As PostMessageObj = Newtonsoft.Json.JsonConvert.DeserializeObject(Of PostMessageObj)(newmessage)
    
    Dim body As String = t.body
    Dim i As String = t.id
    
    End Sub
    
  • Теперь, когда у нас есть наш контроллер API, настроенный для получения нашего стробированного объекта JSON, мы можем свободно вызывать действие POST с клиентской стороны с помощью $.ajax; Продолжая предыдущий пример, вот мой код (замените localhost + rootpath соответствующим образом):

    var url = 'http://<localhost+rootpath>/api/Offers/PostMessage';
    var dataType = 'json'
    var data = 'nothn'
    var tempdata = { body: 'this is a new message...Ip sum lorem.',
        id: '1234'
    }
    var jsondata = JSON.stringify(tempdata)
    $.ajax({
        type: "POST",
        url: url,
        data: { '': jsondata},
        success: success(data),
        dataType: 'text'
    });
    

Как вы можете видеть, мы в основном создаем объект JSON, преобразовывая его в строку, передавая его как один параметр, а затем восстанавливая его через фреймворк JSON.NET. Я не включил возвращаемое значение в наш контроллер API, поэтому я просто поместил произвольное строковое значение в функцию success().


Заметки автора

Это было сделано в Visual Studio 2010 с использованием ASP.NET 4.0, WebForms, VB.NET и MVC 4 Web API Controller. Для тех, у кого есть проблемы с интеграцией MVC 4 Web API с VS2010, вы можете скачать патч, чтобы сделать это возможным. Вы можете загрузить его из Microsoft Центр загрузки.

Вот несколько дополнительных ссылок, которые помогли (в основном на С#):

Ответ 4

//простой объект json в asp.net mvc

var model = {"Id": "xx", "Name":"Ravi"};
$.ajax({    url: 'test/[ControllerName]',
                        type: "POST",
                        data: model,
                        success: function (res) {
                            if (res != null) {
                                alert("done.");
                            }
                        },
                        error: function (res) {

                        }
                    });


//model in c#
public class MyModel
{
 public string Id {get; set;}
 public string Name {get; set;}
}

//controller in asp.net mvc


public ActionResult test(MyModel model)
{
 //now data in your model 
}

Ответ 5

Несколько месяцев назад я столкнулся с странной ситуацией, когда мне также нужно было отправить некоторую дату в формате Json на мой контроллер. Вот что я придумал после вытягивания волос:

Мой класс выглядит следующим образом:

public class NodeDate
{
    public string nodedate { get; set; }
}
public class NodeList1
{
    public List<NodeDate> nodedatelist { get; set; }
}

и мой код С# следующим образом:

        public string getTradeContribs(string Id, string nodedates)
    {            
        //nodedates = @"{""nodedatelist"":[{""nodedate"":""01/21/2012""},{""nodedate"":""01/22/2012""}]}";  // sample Json format
        System.Web.Script.Serialization.JavaScriptSerializer ser = new System.Web.Script.Serialization.JavaScriptSerializer();
        NodeList1 nodes = (NodeList1)ser.Deserialize(nodedates, typeof(NodeList1));
        string thisDate = "";
        foreach (var date in nodes.nodedatelist)
        {  // iterate through if needed...
            thisDate = date.nodedate;
        }   
    }

и поэтому мне удалось десериализовать параметр nodedates Json object в объекте "nodes"; естественно, конечно, используя класс "NodeList1", чтобы заставить его работать.

Надеюсь, это поможет... Боб

Ответ 6

Ну, моя клиентская сторона (файл cshtml) использовала DataTables для отображения сетки (теперь она отлично управляет контролем Infragistics). И как только пользователь нажал на строку, я захватил событие строки и дату, связанную с этой записью, чтобы вернуться на сервер и сделать дополнительные серверные запросы для сделок и т.д. И нет - я НЕ УСТАНАВЛИВАЯ...

Определения DataTables начались как это (оставляя много вещей), а событие click видно ниже, где я PUSH на свой объект Json:

    oTablePf = $('#pftable').dataTable({         // INIT CODE
             "aaData": PfJsonData,
             'aoColumnDefs': [                     
                { "sTitle": "Pf Id", "aTargets": [0] },
                { "sClass": "**td_nodedate**", "aTargets": [3] }
              ]
              });

   $("#pftable").delegate("tbody tr", "click", function (event) {   // ROW CLICK EVT!! 

        var rownum = $(this).index(); 
        var thisPfId = $(this).find('.td_pfid').text();  // Find Port Id and Node Date
        var thisDate = $(this).find('.td_nodedate').text();

         //INIT JSON DATA
        var nodeDatesJson = {
            "nodedatelist":[]
        };

         // omitting some code here...
         var dateArry = thisDate.split("/");
         var nodeDate = dateArry[2] + "-" + dateArry[0] + "-" + dateArry[1];

         nodeDatesJson.nodedatelist.push({ nodedate: nodeDate });

           getTradeContribs(thisPfId, nodeDatesJson);     // GET TRADE CONTRIBUTIONS 
    });