Проблема с jQuery .serialize()

#c# #jquery #asp.net-mvc

#c# #jquery #asp.net-mvc

Вопрос:

У меня возникла странная проблема при сериализации формы для отправки обратно в метод контроллера. Некоторые из передаваемых полей имеют значение null (в случае строк или значений с нулевым значением) или ноль (в случае числовых значений). Например, с помощью этой простой конфигурации:

ViewModel:

 public class HomeViewModel
{
    public int FakeId { get; set; }
    public string StringDataValue { get; set; }
    public int IntegerDataValue { get; set; }

    public HomeViewModel() { }

    public HomeViewModel(int fakeId)
    {
        FakeId = fakeId;
        StringDataValue = "This is some string data";
        IntegerDataValue = 42;
    }
}
 

Контроллер:

 public class HomeController : Controller
{
    public ActionResult Index()
    {
        HomeViewModel viewModel = new HomeViewModel(15);
        return View(viewModel);
    }

    [HttpPost]
    public JsonResult PostData(HomeViewModel model)
    {
        return JsonResult
        {
            Data = new
            {
                FakeId = model.FakeId,
                StringData = model.StringDataValue,
                IntegerData = model.IntegerDataValue
            }
        };
    }
}
 

Вид:

 @model WebApplication1.Models.HomeViewModel

@{
    ViewBag.Title = "Home Page";
}

@using(Html.BeginForm())
{
    @Html.HiddenFor(m => m.FakeId)
    <div>
        Fake ID: @Html.DisplayFor(m => m.FakeId)
    </div>
    <div>
        String Data: @Html.TextBoxFor(m => m.StringDataValue)
    </div>
    <div>
        Integer Data: @Html.TextBoxFor(m => m.IntegerDataValue)
    </div>
    <button id="btnPost">Post</button>
}

@section scripts
{
    <script type="text/javascript">
        $(function () {
            $("#btnPost").on("click", function (e) {
                e.preventDefault();
                var model = $("form").serialize();
                console.log(model);
                $.post("PostData", JSON.stringify(model))
                    .success(function (d) {
                        console.log(d);
                    })
                    .error(function () {
                        console.log("error");
                    })
            })
        })
    </script>
}
 

Если я нажму кнопку Post, я получу этот вывод для двух console.log() строк:

console.log(модель):
FakeId=15amp;StringDataValue=This is some string dataamp;IntegerDataValue=42
console.log(d):
Object {FakeId: 0, StringData: "This is some string data", IntegerData: 0}

Как вы можете видеть, только значение StringDataValue фактически попало в контроллер. Однако, если я добавлю @Html.Hidden("dummy") в представление чуть выше скрытого поля для модели.Затем я получаю следующий вывод:

console.log(модель):
dummy=amp;FakeId=15amp;StringDataValue=This is some string dataamp;IntegerDataValue=42
console.log(d):
Object {FakeId: 15, StringData: "This is some string data", IntegerData: 0}

Это немного лучше, но значение IntegerDataValue все еще не попало в контроллер. Однако, если я добавлю @Html.Hidden("dummy2") где-нибудь после того, где модель.В представлении отображается значение IntegerDataValue, я получаю следующий вывод:

console.log(модель):
dummy=amp;FakeId=15amp;StringDataValue=This is some string dataamp;IntegerDataValue=42amp;dummy2=
console.log(d):
Object {FakeId: 15, StringData: "This is some string data", IntegerData: 42}

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

Это только я? Может ли кто-нибудь еще повторить это поведение? Я что-то упустил?

Ответ №1:

Извлеките JSON.stringify и попробуйте это. Итак, что-то вроде

  <script type="text/javascript">
        $(function () {
            $("#btnPost").click(function(e) {
                e.preventDefault();
                var model = $("form").serialize();
                console.log(model);
                $.post("Home/PostData", model)
                    .success(function(d) {
                        console.log(d);
                    })
                    .error(function() {
                        console.log("error");
                    });
            });
        });
    </script>
 

Комментарии:

1. Большое вам спасибо! Это определенно «Ого!» момент, поскольку я даже не подумал, что мне не нужен вызов JSON.stringify() . Очень признателен!

2. Приветствую! Спасибо, что дали мне мой первый ответ, за который проголосовали.