WebAPI接受通过Fiddler发送的破碎JSON

本文关键字:破碎 JSON Fiddler WebAPI | 更新日期: 2023-09-27 18:10:14

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

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

这是一个创建User的方法。

    // 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);
        }
    }

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

我的问题是,动作名称的目的是什么?我怎样才能使它成为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 }
        );

感谢您的宝贵时间

两次

/

WebAPI接受通过Fiddler发送的破碎JSON

我怎样才能使它在URL中是必须的?

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

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

为什么它同时接受JSON请求,我如何让它接受一个或另一个。

因为Web API使用JSON。

如果您在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调用创建不同的控制器,这是我过去所做的。