2014-01-29 3 views
0

Я работаю с веб-API и нашел интересное замечание, которое я не могу понять.Почему ModelBinding не работает с FormData, но работает с RequestPayload?

Контроллер:

 
public class UserController: ApiController 
{ 
    public void Post(MyViewModel data) 
    { 
     //data is null here if pass in FormData but available if its sent through Request Payload 
    } 
} 

ViewModel

 
public class MyViewModel{ 
     public long SenderId { get; set; } 
     public string MessageText { get; set; }  
     public long[] Receivers { get; set; } 
} 

JS, что не работает

 
var usr = {}; 
usr.SenderId = "10"; 
usr.MessageText = "test message"; 
usr.Receivers = new Array(); 
usr.Receivers.push("4"); 
usr.Receivers.push("5"); 
usr.Receivers.push("6"); 

$.ajax(
{ 
    url: '/api/User', 
    type: 'POST', 
    data: JSON.stringify(usr), 
    success: function(response) { debugger; }, 
    error: function(error) {debugger;} 
}); 

JS, который работает

 
var usr = {}; 
usr.SenderId = "10"; 
usr.MessageText = "test message"; 
usr.Receivers = new Array(); 
usr.Receivers.push("4"); 
usr.Receivers.push("5"); 
usr.Receivers.push("6"); 

$.post("/api/User", usr) 
.done(function(data) { 
debugger; 
});

Итак, если я перехожу на $.ajax с множеством других конфигураций, например type, contentType, accept и т. Д., Он по-прежнему не привязывает модель правильно, но в случае $.post он работает.

Может ли кто-нибудь объяснить ПОЧЕМУ?

+0

Каков тип контента, который вы видите в случае запроса '$ .ajax' и в случае' $ .post'? Обратите внимание, что тип содержимого важен для веб-api, поскольку он пытается использовать правильный форматтер на основе этого, чтобы десериализовать содержимое запроса. –

+0

Тип контента - это приложение \ json, я хочу знать, почему он работает для запроса полезной нагрузки, а не для данных формы. –

ответ

0

Попробуйте взглянуть на то, что получает POSTED, когда вы попробуйте его с помощью $.ajax (например, с помощью Fiddler из инструментов F12 по вашему выбору). Очень хорошо, что jQuery передает данные как строку с кодировкой URL, а не как JSON-литерал.

Чтобы исправить проблему, попробуйте указать dataType вместе с параметром contentType. Кроме того, я не думаю, что вам нужно JSON.stringify, просто передать JSON буквальным вы создаете:

$.ajax({ 
    data: usr, 
    dataType: 'json', 
    contentType: 'application/json', 
    /* The rest of your configuration. */ 
}); 

Вот метод машинопись, который мы используем в одном из наших проектов (ko.toJSON возвращает строку, представляющую собой JSON литерал, передаваемый в качестве параметра метода):

public static callApi(url: string, type?: string, data?: any): RSVP.Promise { 
    return new RSVP.Promise((resolve, reject) => { 
     $.ajax('/api/' + url, { 
      type: type || 'get', 
      data: data != null ? ko.toJSON(data) : null, 
      dataType: 'json', 
      contentType: 'application/json; charset=utf-8', 
      success:() => { 
       resolve.apply(this, arguments); 
      }, 
      error:() => { 
       reject.apply(this, arguments); 
      } 
     }); 
    }); 
} 

Надеюсь, что это поможет.

+0

Я уже сделал это. Когда вы передаете его через $ .ajax, он отправляется в раздел данных формы запроса, но когда вы передаете его через $ .post, он отправляется на запрос полезной нагрузки. –

+0

@PrashantLakhlani Не уверен, что вы имеете в виду, но просто сравниваете два необработанных POST-запроса, и вы будете сразу увидеть разницу. Кроме того, я не думаю, что вам нужно 'JSON.stringify', просто передайте литерал JSON, который вы создаете. – volpav

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