2012-06-22 3 views
5

Я получаю то, что я считаю странной проблемой связывания в ASP.NET MVC 4 RC Web API. У меня есть метод, предназначенный для приема почтовых запросов от клиента. Проблема в том, что ни один из параметров не является обязательным при вызове метода post, я добираюсь до точки прерывания строки и имени броска, а также по электронной почте. Если я изменяю тип запроса GET в JavaScript, то функция Get ниже вызывается с привязанными параметрами.ASP.NET MVC 4 RC Web API Параметр Binding Issue

Почему параметры не связаны для метода Post, и как я могу это исправить?

send: function(evt) { 
    evt.preventDefault(); 
    $.ajax({ 
     url: '/api/person', 
     data: this.model.toJSON(), 
     type: "POST", 
     dataType: "json", 
     success: function(data) { 
      console.log("Success"); 
     }, 
     error: function(data) { 
      console.log("Error"); 
     } 
    }); 
    } 

Ниже действия регулятора:

public void Get(string name, string email) { 
    throw new NotImplementedException(); 
} 

public void Post(string name, string email) { 
    throw new NotImplementedException(); 
} 

Примечания:

  • Я использую все настройки по умолчанию для ASP.NET MVC 4 RC Web API (так десериализатор должен быть Json.NET)
  • Вкладка «Сеть Chrome» на отладчике JS правильно отображает параметры в данных формы в сообщении.

ответ

13

В отличие от MVC (веб-страниц), простые типы параметров will not, by default, bind from the post body but instead from the URI. Таким образом, с вашим кодом как-то вам нужно передать параметры name и email в строке запроса или в качестве параметров маршрута.

Однако это можно легко решить, создав тип модели (в народном языке MVC) и используя это для параметров метода. На самом деле вы можете использовать его для обоих (в том случае, когда вы дали), если вы затем использовать [FromUri] на методе GET:

public class SomeParams { 
    public string name { get; set; } 
    public string email { get; set; } 
} 

//now an alternative way to write the Get method 
public MyResult Get([FromUri] SomeParams p){ 
    //members are bound from the query string (more like MVC traditional binding) 
    //note - as in MVC, SomeParams will need a default constructor for this to work. 
} 

public PostResult Post(SomeParams p){ 
    //'p' is bound from your JSON (assuming correct format) 
    //because 'complex' types are deserialized using formatters 
    //only one object can be read from the body with a formatter in Web API 
    //as the request body is not buffered; unlike MVC. 
} 

Я застрял в типах возврата к методам только потому, что им нужно что-то вернуть!

Я действительно рекомендую прочитать статью Майка Столла, ссылающуюся на выше (и многие другие).

Заманчиво предположить, что веб-API, поскольку он разделяет те же парадигмы и даже имена классов MVC, на самом деле совпадает с MVC, но это не так. Сначала я задавался вопросом, почему это было так (поскольку я написал много сервисов REST поверх MVC и нашел, что это довольно круто, когда вы написали несколько полезных классов и улучшений базового класса), но они правильно рассмотрели проблемы написания веб-API, и я думаю, что они, вероятно, правы, чтобы внести изменения в подход, который у них есть.

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

+0

Мой параметр get не пусто, на самом деле он даже не существует. Возможно, я не был ясен, но только там можно проиллюстрировать, что функциональность работает в GET и не работает в POST. – Cody

+1

Хорошо - хорошо, тогда это нормально :). Короче говоря, если вы связываете несколько параметров с телом запроса, в основном проще всего написать простой тип модели, как я показал. –

+0

Спасибо за ссылку на статью Майка Столла, это было очень информативно о том, что происходит. Я только что предположил, что Web API использует ту же стратегию привязки, что и MVC. Создание пользовательского класса для получения параметров работало как прелесть, я не поклонник этого решения, но я не могу понять, почему, поэтому я, вероятно, просто упрям. :) В любом случае это решение, которое я буду использовать. Благодаря!:) – Cody

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