0

出于某种原因,我可以将这两个 JSON 请求发送到我的 WebAPI,它会接受并创建一个用户。一个带双引号,一个不带。

{"Username":"Bob", "FirstName":"Foo", "LastName":"Bar", "Password":"123", "Headline":"Tuna"}

{Username:"Bob", FirstName:"Foo", LastName:"Bar", Password:"123", Headline:"Tuna"}

这是创建用户的方法。

    // localhost:12345/api/controller/create
    [ActionName("create")]
    public HttpResponseMessage PostUser(User user)
    {
        if (ModelState.IsValid)
        {
            db.Users.Add(user);
            db.SaveChanges();

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

但是,我可以在没有/createURL 末尾的情况下发出成功的 POST 请求。我假设 POST 请求成功的原因是因为无论操作名称是否存在,它都会Post在方法名称中搜索 a 。

所以我的问题是,动作名称的目的是什么?我怎样才能使它成为 URL 中的必须项?还有为什么它同时接受 JSON 请求,我怎样才能让它接受一个或另一个。

编辑:

config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

// Routing by Action-name
config.Routes.MapHttpRoute(
            name: "ActionApi",
            routeTemplate: "api/{controller}/{action}/{username}",
            defaults: new { username = RouteParameter.Optional }
        );

感谢您的时间

/两次

4

2 回答 2

1

我怎样才能使它成为 URL 中的必须项?

通过更改您的路由定义~/App_Start/WebApiConfig.cs并使操作名称显式出现在您的路由中:

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{action}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

还有为什么它同时接受 JSON 请求,我怎样才能让它接受一个或另一个。

因为 Web API 使用 JSON.NET 作为接受这两者的 JSON 序列化程序。

于 2013-04-22T11:37:34.250 回答
0

如果您查看App_Start为您的 API 调用注册的路由,您将看到:

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

您会注意到没有action指定。如果要映射到操作名称,可以将其更改为:

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{action}/{id}",
    defaults: new { action = "get", id = RouteParameter.Optional }
);

但是你总是需要设置一个动作(除非它GET是默认的)。您不能再POST直接使用控制器,您总是需要添加一个action.

根据此链接,默认行为是查找以使用的 HTTP 方法开头的方法:

为了找到该操作,Web API 会查看 HTTP 方法,然后查找名称以该 HTTP 方法名称开头的操作。例如,对于 GET 请求,Web API 会查找以“Get...”开头的操作,例如“GetContact”或“GetAllContacts”。此约定仅适用于 GET、POST、PUT 和 DELETE 方法。您可以通过使用控制器上的属性来启用其他 HTTP 方法。我们稍后会看到一个例子。

另一种选择是为您的不同GET调用创建不同的控制器,这是我过去所做的。

于 2013-04-22T11:36:21.100 回答