Не найдено ни одного действия, соответствующего URI запроса

1

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

public class ReservationsController : ApiController
{
    public HttpResponseMessage PostReservation(string eRaiderUserName, string SpaceNumbers)
    {
        char[] delimiter = { '|' };
        string[] spaces = SpaceNumbers.Split(delimiter);
        bool saved = true;
        foreach(string space in spaces)
        {
            var reservation = new Reservation { eRaiderUserName=eRaiderUserName, SpaceNumber=Convert.ToInt32(space) };
            if (true)
            {
                reservation.Game = db.Games.FirstOrDefault(g => g.ID == AppSettings.CurrentGameID);
                db.Reservations.Add(reservation);
                db.SaveChanges();

                //HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, reservation);
                //response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = reservation.ID }));
                //return response;
            }
            else
            {
                saved = false;
                //return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
            }
        }

        db.SaveChanges();
        if (saved)
        {
            HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created);
            response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = 1 }));
            return response;
        } else
        {
            return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
        }
    }
}

У меня есть форма, в которой указано, что я думаю, должна быть правильная информация, но я продолжаю получать эту ошибку:

{"$id":"1","Message":"No HTTP resource was found that matches the request URI 'http://localhost:58463/api/Reservations'.","MessageDetail":"No action was found on the controller 'Reservations' that matches the request."}

Метод (измененный) сохранения в api все еще определенно работает. Но что удерживает это от поиска контроллера веб-api? Вот вывод Firebug:

Изображение 174551

  • 2
    Можете ли вы показать нам, как вы настроили свою маршрутизацию?
  • 0
    Будет ли это работать, если ваше действие называется просто Post ?
Показать ещё 1 комментарий
Теги:
asp.net-mvc
asp.net-apicontroller
asp.net-mvc-4

3 ответа

5
Лучший ответ

Как отмечалось, проблема заключается в том, что действие POST может передавать только данные, отправленные в теле одному объекту (по техническим причинам).

Это означает, что вы можете получать данные из данных маршрута, из строки запроса и из тела, со следующими ограничениями:

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

Таким образом, наиболее общий способ решения вашей проблемы (т.е. Который может быть легко применен к другим классам, где вам необходимо передать сложные данные, даже более сложные, чем этот случай):

Сначала создайте класс, который обладает свойствами для всех необходимых данных, в вашем случае:

public class ReservationData
{
  public string eRaiderUserName { get; set; }
  public string SpaceNumbers  { get; set; }
}

Во-вторых, используйте этот класс как тип полученного параметра в вашем действии:

public HttpResponseMessage PostReservation(ReservationData reservationData)

С помощью этого кода форматер может сопоставить все данные в теле запроса с одним параметром в действии. Вы можете использовать форматы JSON или formdata, например, сгенерированные jQuery.

ПРИМЕЧАНИЕ. Имена свойств должны иметь случайное соответствие имени опубликованных параметров.

  • 0
    Пригвоздил - это тоже чище. Спасибо!!!
0

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

public HttpResponseMessage PostReservation(string eRaiderUserName, string SpaceNumbers)

{//...}

и вы пытаетесь вызвать с помощью jQuery:

$.ajax({  url: 'api/reservations', type: 'POST', data: { ... }, dataType: 'json', success: function (data) {alert(data);} }); 

К сожалению, веб-API не справляется с этим запросом, и вы получите ошибку. Но если вы передаете параметры с помощью строки запроса, Itll работает:

$.ajax({url: 'api/reservations? eRaiderUserName = 2012 & SpaceNumbers = test', type: 'POST', dataType: 'json', success: function (data) {alert (data);}});

Но это нехорошее решение и неприменимо для сложных объектов. Итак, вот несколько способов сделать это.

  1. Использование привязки модели (предпочтительно)
  2. Использование пользовательского привязки параметров
  3. FormDataCollection
  4. Строка запроса
0

Это связано с тем, что вы отправляете x-www-form-urlencoded данные в контроллер, для обработки этих данных вы должны использовать [FromBody] перед параметром, например

public HttpResponseMessage Post([FromBody] string name) { ... }

но этот подход имеет большое ограничение: 1) Может быть только один параметр, помеченный атрибутом [FromBody] (он может быть сложным типом) 2) Данные должны быть закодированы как = значение не как key = value. Вы можете прочитать его здесь описание и как заставить его работать здесь пример. Если это возможно, я рекомендую вам отправлять данные Json на контроллер без этих ограничений.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню