2013-10-10 6 views
1

У меня есть пользовательский интерфейс, который выглядит следующим образом:Json и ASP.NET MVC модель привязки

enter image description here

Я пытаюсь данным недавно созданной строки на сервере, так что сервер может сохранить его.

Я отправляю данные в формате JSON от клиента к моему приложению MVC. Вот мой Ajax запрос:

var values = []; // an array with each item being an object/associative array 

// more code to get values into variables 

for (var i = 0; i < cultures.length; i++) { 
    var cultureName = cultures[i]; 
    var valueTextBox = $(row).find(...); 
    var value = $(valueTextBox).val(); 

    var cultureNameAndValue = { 'CultureShortName' : cultureName, 'StringValue' : value }; 

    values.push(cultureNameAndValue); 
} 

var stringTableRow = 
    { 
    'ResourceKeyId': resourceKeyId, 
    'Key': resourceKeyName, 
    'CategoryId': categoryId, 
    'CategoryName': categoryName, 
    'StringValues': values 
    }; 

var stringified = JSON.stringify({ StringTableRow: stringTableRow }); 

$.ajax('/Strings/JsonCreateNew', 
     { 
     cache: false, 
     async: false, 
     type: 'POST', 
     contentType: 'application/json; charset=UTF-8', 
     data: stringified, 
     dataType: 'json', 
     error: SaveNewResourceClientSideHandler.OnError, 
     success: SaveNewResourceClientSideHandler.OnSuccess 
     }); 

Вот данные, которые он посылает (как показано в Firebug):

{"StringTableRow":{"ResourceKeyId":"","Key":"Foo", 
"CategoryId":"1","CategoryName":"JavaScript", 
"StringValues":[ 
{"CultureShortName":"en-US","StringValue":"Something"}, 
{"CultureShortName":"fr-FR","StringValue":""}] 
}} 

Вот мой сервер код сторона:

public ActionResult JsonCreateNew(StringTableRow row) 
{ 
    // CreateNewStringTableRow(row); 

    // return a success code, new resource key id, new category id 
    // return Json(
       new { Success = true, ResourceKeyId = row.ResourceKeyId, 
        CategoryId = row.CategoryId }, 
       JsonRequestBehavior.AllowGet); 

    return new EmptyResult(); 
} 

А вот бизнес-объект, Я хочу, чтобы мои входящие данные POST были связаны с:

public class StringTableRow 
{ 
    public StringTableRow() 
    { 
     StringValues = new List<CultureNameAndStringValue>(); 
    } 

    public long ResourceKeyId { get; set; } 

    public string Key { get; set; } 

    public long CategoryId { get; set; } 

    public string CategoryName { get; set; } 

    public IList<CultureNameAndStringValue> StringValues { get; set; } 
} 


public class CultureNameAndStringValue 
{ 
    public string CultureShortName { get; set; } 

    public string StringValue { get; set; } 
} 

Global.asax

public class MvcApplication : System.Web.HttpApplication 
    { 
     protected void Application_Start() 
     { 
      AreaRegistration.RegisterAllAreas(); 

      WebApiConfig.Register(GlobalConfiguration.Configuration); 
      FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 
      RouteConfig.RegisterRoutes(RouteTable.Routes); 
      BundleConfig.RegisterBundles(BundleTable.Bundles); 

      ValueProviderFactories.Factories.Add(new JsonValueProviderFactory()); 
     } 
    } 

Проблема:

Действие JsonCreateNew получает объект, который не является нулевым, но имеет все свойства неинициализированным, то есть все обнуляемых свойства равны нулю и значение свойства в их значения по умолчанию. Поэтому, фактически, я не получаю никаких данных вообще, даже когда клиент отправляет совершенно правильную строку Json.

Нужно ли выполнять индивидуальную привязку модели?

ответ

1

Хорошо, я решил свою проблему, и это может быть важным прозрением для других программистов, потому что я чему-то научился, решая мою собственную проблему.

Моего решение: я прибегал не используя JSON и вместо этого используется кодировка по умолчанию, HTTP использует для формы кодировок размещены значения, а затем я использовал что-то смахивает пользовательскую модель связывания (без фактического создания модели связующего) ,

Объяснение: Обычно, когда вы делаете Ajax запрос и передать данные от клиента на любой серверной платформе, если не указать кодировку, то есть параметр contentType в объекте настройки Аякса метода JQuery (или если вы используете какие-либо другие средства для создания ajax-запроса, отличного от jQuery, то, однако, эта штука устанавливает HTTP-заголовок ContentType - это то, что вам нужно), HTTP кодирует ваши опубликованные данные с использованием кодировки по умолчанию, что очень похоже на то, что вы публикуете с запросом GET после строки запроса, только он кодируется двоичным кодом и не отправляется как часть URL-адреса.

Если это так, и вы разместили коллекцию любого типа (IList, IEnumerable, ICollection, IDictionary и т.д.) в ASP.NET MVC, то не создать ассоциативный массив в JavaScript, чтобы воплотить коллекция. Даже не создавайте массив. Не создавайте ничего.

На самом деле, просто передать его внутри основного большого объекта с помощью конвенции:

data = 
{ /*scalar property */ Gar: 'har', 
    /* collection */ 'Foo[index++].Bar' : 'value1', 
    'Foo[index++].Bar' : 'value2' 
} 

И не использовать JSON. Это позволит решить половину проблемы.

На стороне сервера получайте опубликованные данные в FormCollection и используйте методы IValueProvider (GetValue), чтобы выкопать нужные данные. Вам не нужно явно создавать привязку модели для этого. Вы можете сделать это в частном методе своего контроллера.

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

+0

Я тоже в аналогичном сценарии, когда я отправляю данные на сервер с помощью ajax-запроса, тогда мне нужно привязать все значения формы к json-формату, например var name = $ («Name»). Val(); var age = $ ("Age"). Val(); // build json object var squirrel = { Имя: фамилия, имя: Возраст: возраст, }; Есть ли какой-либо другой способ, с помощью которого мне не нужно вручную привязывать значения к json.Means, есть ли что-нибудь, что может напрямую преобразовать мою модель просмотра в json, а затем я могу получить ее в контроллере как объект? – Dragon

-2

Используйте магистраль или нокаут для связывания данных.

+0

Спасибо, Тарун. Я оставил нокаутом в качестве последнего средства. Я просто не хотел делегировать свою проблему абстракции, потому что я потерял бы контроль. Я создаю пользовательский интерфейс в jQuery, потому что я просто ушел от использования элементов управления DevExpress, еще одной абстракции. Я знал, что проблема связана с пользовательской привязкой к модели и не хочет возвращаться к абстракции, как нокаут (если у меня не было другого выбора). Я решил свою проблему и вскоре опубликую решение. –

Смежные вопросы