ASP.NET DefaultModelBinder не связывает объекты коллекции JSON - PullRequest
0 голосов
/ 06 ноября 2011

Вот мой контроллер:

public class TagsController : Controller
{
  public ActionResult Attach(TagsAttach model)
  {
    // ...
  }
}

Вот мои модели представления:

public class TagsAttach
{
  public int GroupID { get; set; }
  public List<Tag> Tags { get; set; }
}

public class Tag
{
  public int ID { get; set; }
}

А вот код Javascript, который я использую, чтобы попытаться представить свои данные:

var data = {
  GroupID: 12,
  Tags: []
};

data.Tags.push({ ID: 3 });
data.Tags.push({ ID: 4 });

$.push('/Tags/Attach', data);

Однако, когда я отлаживаю свое действие контроллера, я нахожу все, кроме значений ID в каждом из объектов Tag.

Таким образом, мой параметр 'model' выглядит следующим образом:

model
  GroupID  12
  Tags
    Tag
      ID   0
    Tag
      ID   0

Почему это?Что мне нужно сделать, чтобы ASP.NET MVC правильно связывал мои значения идентификаторов?

(Примечание: то, что я делаю, выглядит почти так же, как this . Так почемуу меня не работает?)

Ответы [ 2 ]

3 голосов
/ 06 ноября 2011

ASP.NET MVC 3 имеет встроенную JsonValueProviderFactory , которая позволяет отправлять JSON-запросы к действиям контроллера, и механизм связывания модели по умолчанию сможет преобразовать эту строку JSON в соответствующую модель представления. Вы можете использовать метод $.ajax следующим образом:

var dataToSend = { 
    // model is the name of the action parameter
    // this nesting could be omitted
    model: { 
        GroupID: 12, 
        Tags: [ { ID: 3 }, { ID: 4 } ] 
    } 
};

// the following will also work but assumes that you have a single
// action argument. And since your actions should take only the view model
// as action argument it is also a good way: 
// var dataToSend = { GroupID: 12, Tags: [ { ID: 3 }, { ID: 4 } ] };

$.ajax({
    url: '@Url.Action("Attach", "Tags")',
    type: 'POST',
    contentType: 'application/json; charset=utf-8',
    data: JSON.stringify(dataToSend),
    success: function(result) {
        alert('success');
    }
});

Это позволяет вам отправлять произвольные сложные литералы JavaScript в действия контроллера.

Важные замечания:

  • contentType: 'application/json; charset=utf-8' устанавливает заголовок запроса Content-Type так, чтобы сервер знал, что мы отправляем запрос JSON.

  • JSON.stringify - это метод, который сериализует литерал javascript в строку JSON. Этот метод изначально встроен в современные браузеры, но если вам нужно поддерживать устаревшие браузеры, вы можете добавить на свою страницу скрипт json2.js .

2 голосов
/ 06 ноября 2011

При дальнейшем рассмотрении выясняется, что это невозможно из-за базовой несовместимости между процессором JQuery JSON, который используется $ .post, и DefaultModelBinder в ASP.NET MVC.

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

SearchTagID=1&ApplicationType=0&Items[0].ID=2&Items[1].ID=672

Обратите внимание, что используется нотация с точкой, например: Items [0] .ID = 2.

Код jQuery использует обозначение в квадратных скобках, как показано ниже:

SearchTagID=1&ApplicationType=0&Items[0][ID]=2&Items[1][ID]=672

Так что, если нет способа заставить jQuery использовать вместо него точечную нотацию, я думаю, мне придется найти какой-то обходной путь.

...