Как я могу опубликовать массив строк в ASP.NET MVC Controller без формы? - PullRequest
175 голосов
/ 21 ноября 2008

Я создаю небольшое приложение для обучения ASP.NET MVC и JQuery, и одна из страниц представляет собой список элементов, в которых некоторые из них могут быть выбраны. Затем я хотел бы нажать кнопку и отправить на мой контроллер список (или что-то эквивалентное), содержащий идентификаторы выбранных элементов, используя функцию Post в JQuery.

Мне удалось получить массив с идентификаторами выбранных элементов, и теперь я хочу опубликовать это. Один из способов сделать это - создать на своей странице фиктивную форму со скрытым значением, а затем установить скрытое значение с выбранными элементами и опубликовать эту форму; это выглядит грубым, хотя.

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

function generateList(selectedValues) {
   var s = {
      values: selectedValues //selectedValues is an array of string
   };
   $.post("/Home/GenerateList", $.toJSON(s), function() { alert("back") }, "json");
}

И тогда мой контроллер выглядит так

public ActionResult GenerateList(List<string> values)
{
    //do something
}

Все, что мне удалось получить, это "ноль" в параметре контроллера ...

Какие-нибудь советы?

Ответы [ 9 ]

239 голосов
/ 21 ноября 2008

Я изменил свой ответ, добавив код для тестового приложения, которое я сделал.

Обновление: я обновил jQuery, чтобы установить для традиционного параметра значение true, чтобы это снова сработало (для ответа @DustinDavis). Первый JavaScript:

function test()
{
    var stringArray = new Array();
    stringArray[0] = "item1";
    stringArray[1] = "item2";
    stringArray[2] = "item3";
    var postData = { values: stringArray };

    $.ajax({
        type: "POST",
        url: "/Home/SaveList",
        data: postData,
        success: function(data){
            alert(data.Result);
        },
        dataType: "json",
        traditional: true
    });
}

А вот код в моем классе контроллера:

public JsonResult SaveList(List<String> values)
{
    return Json(new { Result = String.Format("Fist item in list: '{0}'", values[0]) });
}

Когда я вызываю эту функцию javascript, я получаю предупреждение «Первый элемент в списке:« item1 »». Надеюсь, это поможет!

105 голосов
/ 27 марта 2010

К вашему сведению: JQuery изменил способ сериализации почтовых данных.

http://forum.jquery.com/topic/nested-param-serialization

Вы должны установить для параметра «Традиционный» значение true, в противном случае

{ Values : ["1", "2", "3"] }

выйдет как

Values[]=1&Values[]=2&Values[]=3

вместо

Values=1&Values=2&Values=3
24 голосов
/ 12 августа 2011

Спасибо всем за ответы. Другим быстрым решением будет использование метода jQuery.param с параметром традиционный , установленным на true , для преобразования объекта JSON в строку:

$.post("/your/url", $.param(yourJsonObject,true));
8 голосов
/ 21 ноября 2008

Не размещайте данные в виде массива. Для привязки к списку пары ключ / значение должны быть представлены с одинаковым значением для каждого ключа.

Вам не нужна форма для этого. Вам просто нужен список пар ключ / значение, которые вы можете включить в вызов $ .post.

6 голосов
/ 15 января 2015

В .NET4.5, MVC 5

Javascript:

объект в JS: enter image description here

механизм, который публикует.

    $('.button-green-large').click(function() {
        $.ajax({
            url: 'Quote',
            type: "POST",
            dataType: "json",
            data: JSON.stringify(document.selectedProduct),
            contentType: 'application/json; charset=utf-8',
        });
    });

C #

Объекты:

public class WillsQuoteViewModel
{
    public string Product { get; set; }

    public List<ClaimedFee> ClaimedFees { get; set; }
}

public partial class ClaimedFee //Generated by EF6
{
    public long Id { get; set; }
    public long JourneyId { get; set; }
    public string Title { get; set; }
    public decimal Net { get; set; }
    public decimal Vat { get; set; }
    public string Type { get; set; }

    public virtual Journey Journey { get; set; }
}

Контроллер:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Quote(WillsQuoteViewModel data)
{
....
}

Полученный объект:

enter image description here

Надеюсь, это сэкономит вам время.

4 голосов
/ 23 января 2015

Еще одна реализация, которая также работает со списком объектов, а не только со строками:

JS:

var postData = {};
postData[values] = selectedValues ;

$.ajax({
    url: "/Home/SaveList",
    type: "POST",
    data: JSON.stringify(postData),
    dataType: "json",
    contentType: "application/json; charset=utf-8",
    success: function(data){
        alert(data.Result);
    }
});

Предполагается, что selectedValues ​​является массивом объектов.

В контроллере параметр представляет собой список соответствующих ViewModels.

public JsonResult SaveList(List<ViewModel> values)
{    
    return Json(new { 
          Result = String.Format("Fist item in list: '{0}'", values[0].Name) 
    });
}
1 голос
/ 08 октября 2012

Как я уже говорил здесь ,

Если вы хотите передать пользовательский объект JSON в действие MVC, вы можете использовать это решение, оно работает как шарм.

    public string GetData()
    {
        // InputStream contains the JSON object you've sent
        String jsonString = new StreamReader(this.Request.InputStream).ReadToEnd();

        // Deserialize it to a dictionary
        var dic = 
          Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<String, dynamic>>(jsonString);

        string result = "";

        result += dic["firstname"] + dic["lastname"];

        // You can even cast your object to their original type because of 'dynamic' keyword
        result += ", Age: " + (int)dic["age"];

        if ((bool)dic["married"])
            result += ", Married";


        return result;
    }

Реальным преимуществом этого решения является то, что вам не требуется определять новый класс для каждой комбинации аргументов, а кроме этого вы можете легко приводить ваши объекты к их исходным типам.

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

public static Dictionary<string, dynamic> GetDic(HttpRequestBase request)
{
    String jsonString = new StreamReader(request.InputStream).ReadToEnd();
    return Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(jsonString);
}
0 голосов
/ 10 января 2018

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

jQuery.ajaxSettings.traditional = true;
0 голосов
/ 08 марта 2011

Ответ мне очень помог в моей ситуации, так что спасибо за это. Однако для дальнейшего использования люди должны связать модель и затем подтвердить ее. Этот пост от Фила Хаака описывает это для MVC 2. http://haacked.com/archive/2010/04/15/sending-json-to-an-asp-net-mvc-action-method-argument.aspx

Надеюсь, это кому-нибудь поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...