2

我试图修改我的一个 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 中的(修改后的)保存方法肯定仍在进行中。但是是什么阻止了它找到 web api 控制器?这是萤火虫的输出:

在此处输入图像描述

4

3 回答 3

6

正如所指出的,问题在于 POST 操作只能将发布在正文中的数据传输到单个对象(出于技术原因)。

这意味着您可以从路由数据、查询字符串和正文中获取数据,但有以下限制:

  • 来自查询字符串或路由数据的数据必须是任意数量的单个值(即它们不能是类)
  • 您只能使用来自请求正文的数据的操作参数,但这可能是一个复杂的类
  • 您可以对此进行任意组合,即来自主体的单个或复杂参数,以及来自路由数据或查询字符串的任意数量的单个参数。

因此,解决您的问题的最通用方法(即可以轻松应用于需要传递复杂数据的其他类,甚至比这种情况更复杂)是:

首先,在您的情况下,创建一个具有所有所需数据属性的类:

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

其次,在您的操作中使用此类作为接收参数的类型:

public HttpResponseMessage PostReservation(ReservationData reservationData)

使用此代码,格式化程序可以将请求正文中的所有数据映射到操作中的单个参数。您可以使用 JSON 或 formdata 格式,如 jQuery 生成的。

注意:属性名称必须区分大小写与发布参数的名称匹配。

于 2014-07-16T13:47:58.993 回答
1

这是因为您将 x-www-form-urlencoded 数据发送到控制器,要处理此数据,您必须在参数之前使用[FromBody]

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

但是这种方法有很多限制:1)只能有一个参数标记为 [FromBody] 属性(可以是复杂类型) 2)数据必须编码为 =value 而不是 key=value 。您可以在此处阅读描述 以及如何使其在此处工作的示例。如果可能的话,我建议您将 Json 数据发送到控制器,而不受此限制。

于 2014-07-16T08:52:56.433 回答
0

Web API 对将 POST 表单变量映射到 Web API 方法的简单参数的支持有限。Web API 不处理多个发布的内容值,您只能将单个内容值发布到 Web API Action 方法。

public HttpResponseMessage PostReservation(string eRaiderUserName, string SpaceNumbers)

{ //...}

并且您正在尝试使用 jQuery 进行调用:

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

不幸的是,Web API 不能处理这个请求,你会得到错误。但是,如果您使用查询字符串传递参数,它将起作用:

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

但这不是很好的解决方案,不适用于复杂的对象。所以这里有不同的方法来做到这一点。

  1. 使用模型绑定(首选)
  2. 使用自定义参数绑定
  3. 表单数据集合
  4. 请求参数
于 2014-07-16T10:06:50.213 回答