Строки данных AJAX POST в MVC всегда равны нулю

Может ли кто-нибудь помочь мне в следующем. Я пытаюсь отправить данные JSON в контроллер, но контроллер никогда не заполняет переменную данными.

Это контроллер, и он всегда отображает ноль.

Это контроллер.

public ActionResult SyncMail(List<MailSyncDTO> emailLst)
{
    return null;
}

Вид выглядит так;

foreach (var item in Model)
    <td><input name = "emailLst.emailSource" id = "emailSource" type = "text" value = "@item.emailSource" /></td>
    <td><input name = "emailLst.emailDestination" id = "emailDestination" type = "text" value = "@item.emailDestination" /></td>
    <td><input name = "emailLst.SyncMail" id = "SyncMail" type = "checkbox" /></td>
    <td><input name = "emailLst.ID" id = "ID" type = "text" value = "@item.ID" hidden /></td>
</tr>
}

    function Update() {
        var emailLst = [];
        $('#tblEmails tr').each(function () {
            var obj = new Object();
            var emailSource = $(this).find("input").each(function () {
                if (this.id == 'emailSource' && this.value != '') {
                    obj.emailSource = this.value;
                }
                else if (this.id == 'emailDestination' && this.value != '') {
                    obj.emailDestination = this.value;
                }
                else if (this.id == 'SyncMail' && this.value != '') {
                    obj.SyncMail = this.value;
                }
                else if (this.id == 'ID' && this.value != '') {
                    obj.ID = this.value;
                }
            })
            emailLst.push(obj);
        });

        $.ajax({
            contentType: 'application/json; charset=utf-8',
            dataType: 'json',
            type: 'POST',
            url: '/MailSyncDBs/SyncMail',
            data: JSON.stringify({ emailLst: emailLst })
        });
    }

Я вижу в Fiddler, что данные отправляются.

POST http://localhost:53545/MailSyncDBs/SyncMail HTTP/1.1
Content-Type: application/json; charset=utf-8
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
Referer: http://localhost:53545/MailSyncDBs/Index
Accept-Language: en-GB
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko
Content-Length: 336
Host: localhost:53545
Connection: Keep-Alive
Pragma: no-cache
{"emailLst":[{},{"emailSource":"[email protected]","emailDestination":"[email protected]","SyncMail":"on","ID":"1"},{"emailSource":"[email protected]","emailDestination":"[email protected]","SyncMail":"on","ID":"2"},{"emailSource":"[email protected]","emailDestination":"[email protected]","SyncMail":"on","ID":"3"}]}

Это DTO, на который делается ссылка;

public class MailSyncDTO
{
    public string ID { get; set; }
    public string emailSource { get; set; }
    public string emailDestination { get; set; }
    public string SyncMail { get; set; }
}
Я проголосовал против, потому что (и вы отправляете коллекцию объектов, а не набор строк)
user3559349 21.03.2018 23:01
Как сделать HTTP-запрос в Javascript?
Как сделать HTTP-запрос в Javascript?
В JavaScript вы можете сделать HTTP-запрос, используя объект XMLHttpRequest или более новый API fetch. Вот пример для обоих методов:
3
1
86
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваш контроллер хочет получить List<string>, но вы ему его не отправляете. Исходя из того, как вы создали свой контроллер, отправляемый вами Json должен выглядеть примерно так:

["[email protected]","[email protected]","[email protected]"]

Вы можете создать DTO в своем проекте C#, который будет точно отражать ваш Json и будет автоматически отображаться в вашем контроллере.

Я тестировал это с помощью этого метода javascript:

function testIt() {
    var emailLst = [];

    // Replace bellow part with yours
    var obj = new Object();
    obj.EmailDestination = "[email protected]";
    obj.Source = "[email protected]";
    obj.SyncMail = "on";
    obj.Id = "1";
    emailLst.push(obj);
    // Replace above part with yours


    // Adding this before sending will make sure that you are not sending any empty objects.
    emailLst.forEach(function(item, i) {         
        if ($.isEmptyObject(item)) {
            emailLst.splice(i, 1);
        }
    });

    $.ajax({
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        type: 'POST',
        url: '/MailSyncDBs/SyncMail',
        data: JSON.stringify(emailLst)  // And not JSON.stringify({emailLst : emailLst })
    });
}

Попробуйте добавить такой класс:

public class SyncMailDto
{
    public string EmailSource {get; set;}
    public string EmailDestination {get; set;}
    public string SyncMail {get; set;}
    public string Id {get; set;}    
}

И измените подпись вашего метода контроллера на:

[HttpPost]
public JsonResult SyncMail(List<SyncMailDto> emailLst){

    foreach(var mail in emailLst){
         // Do something with your mail
    }

    return Json("It Works !");
}

Если вы хотите использовать именно тот JavaScript, который вы написали, вам придется добавить еще один класс DTO, чтобы обернуть список. Потому что это то, что вы сделали с JSON.stringify({EmailLst : EmailLst}).

public class MailListWrapperDto{
    public List<SyncMailDto> EmailLst {get;set;}
}

И подпись вашего метода POST:

public JsonResult SyncMail(MailListWrapperDto emailLst)

Спасибо, Антуан, попробую утром. Я новичок в Json и MVC, но думал, что json.stringify преобразовывает данные в строку перед ее отправкой. Это не неправильно?

Nathan Linus 21.03.2018 23:54

Это не так уж и неправильно, но данные, которые вы хотите преобразовать, представляют собой список объектов, а не список строк. И если быть точным, если я прав, вам не нужно структурировать json.

Antoine Thiry 22.03.2018 06:27

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

Nathan Linus 22.03.2018 14:18

@NathanLinus Я отредактировал свой ответ с помощью кода javascript и протестировал его в Visual Studio 2017, и он работает нормально. Настоящая проблема заключалась в том, как вы отправляли свой Json.

Antoine Thiry 22.03.2018 14:36

Пожалуйста, отметьте это как ответ, если это вам помогло.

Antoine Thiry 22.03.2018 16:09

Нет, все еще не работает. Теперь он берет первую партию данных, но не другие записи.

Nathan Linus 22.03.2018 16:34

@NathanLinus Я отредактировал бит javascript, чтобы он удалял пустые элементы из json. (Вы должны стараться не копировать / вставлять код в разделе комментариев)

Antoine Thiry 22.03.2018 16:49

Теперь он работает. Я добавил идентификатор к строке, которая зацикливается, и изменил JavaScript, чтобы использовать идентификатор, а не общую строку таблицы. Теперь он успешно проходит цикл и обновляет переменную контроллера. Еще раз спасибо, Антуан, за вашу помощь! (Код я удалил, спасибо за совет)

Nathan Linus 22.03.2018 17:29

Другие вопросы по теме