C# Web Api 2 PUT 和 POST 请求“不支持”

Posted

技术标签:

【中文标题】C# Web Api 2 PUT 和 POST 请求“不支持”【英文标题】:C# Web Api 2 PUT and POST requests "not supported" 【发布时间】:2015-10-05 01:21:37 【问题描述】:

到目前为止,我的 ASP.NET Web api 正确地为员工执行获取请求并使用 JQuery 填写字段。删除请求也有效,但我一直收到:

Message=The requested resource does not support http method 'PUT'.

使用 405 http 方法不允许错误。这可能是因为我的 put/post 请求同时包含一个对象、字符串作为参数,而不是简单地将 url 的 id 获取到 GET 和 DELETE。这是一个从一个站点到另一个站点的跨域请求,因此我在 web.config 文件中有 enableCors() 以及 WEBDAV 的删除:

<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules runAllManagedModulesForAllRequests="true">
  <remove name="WebDAVModule" />
  <remove name="FormsAuthentication" />
</modules>
<httpProtocol>
  <customHeaders>
    <clear />
    <add name="Access-Control-Allow-Origin" value="https://chad-dev.clas.uconn.edu" />
    <add name="Access-Control-Allow-Headers" value="Content-Type" />
    <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
  </customHeaders>
</httpProtocol>
<handlers>
  <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
  <remove name="WebDAV" />
  <remove name="OPTIONSVerbHandler" />
  <remove name="TRACEVerbHandler" />
  <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers></system.webServer>

这是我的 WebApiConfig 注册函数:

public static class WebApiConfig

    public static void Register(HttpConfiguration config)
    
        // Web API configuration and services
        // Configure Web API to use only bearer token authentication.
        config.SuppressDefaultHostAuthentication();
        //config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));

        var cors = new EnableCorsAttribute("*", "*", "*");
        config.EnableCors(cors);

        // Web API routes
        config.MapHttpAttributeRoutes();

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

        config.Routes.MapHttpRoute(
            "WithAction",
            "api/controller/action/id",
            new  controller = "Commitments", action = "GetCommitment" 
        );

我的控制器:

[HttpPut]
    public IHttpActionResult PutEmployee([FromBody]EmployeeModel employeeModel, string netId)
         
        var chadResult = new CLASWebApiResponse
        
            Success = true,
            ResponseMessage = "Success",
            Data = null
        ;
        try
        
            employee employeeUpdate = masterDb.employees.Find(employeeModel.Id);

            if (employeeUpdate == null)
            
                chadResult.ResponseMessage = "Employee not found";
                chadResult.Success = false;
                return Ok(chadResult);
            

            employeeUpdate.netid = employeeModel.NetId;
            employeeUpdate.enumber = employeeModel.Enumber;
            employeeUpdate.peoplesoft = employeeModel.Peoplesoft;
            employeeUpdate.email = employeeModel.Email;
            employeeUpdate.tenure_year = employeeModel.TenureYear;
            employeeUpdate.tenure_indicator = employeeModel.TenureIndicator;
            employeeUpdate.hire_date = employeeModel.HireDate;
            employeeUpdate.gender = employeeModel.Gender;
            employeeUpdate.birth_date = employeeModel.BirthDate;
            employeeUpdate.updated_by = netId;
            masterDb.SaveChanges();

            chadResult.Success = true;
            chadResult.ResponseMessage = "Success";
            return Ok(chadResult);
        

        catch (Exception e)
        
            chadResult.ResponseMessage = e.Message;
            chadResult.Success = false;
            return Ok(chadResult);
        
    

最后(对不起代码量),我的ajax请求:

$.ajax(
            type: "PUT",
            url: "https://chad-test4.clas.uconn.edu/api/Employees/PutEmployee",
            dataType: "json",
            contentType: "application/json",
            data: JSON.stringify(employeeModel:employeeData, netId:'22'),
            traditional: true,
            success: function() 
                console.log(employeeModel);
                alert("Saved Successfully.");
            ,
            error: function(response) 
                console.log(employeeModel);
                alert("Employee data failed to save to server. Error message: " + jQuery.parseJSON(response.responseText).Message);
            
        );

【问题讨论】:

为什么你的控制器方法不叫Put?另外,根据您的路由配置,您应该将netId 参数重命名为id,然后将值放入URL 而不是请求正文中。 我不仅传递了 netId 字符串,还传递了整个员工对象。这可以适合所有的 URL 吗?我认为这会进入 JSON 请求正文 如果employeeModel 已经有一个netId,为什么还要传递一个? 为 PUT 和 POST 传递的 netId 是进行 put 更改的人。它用于我们数据库中的 created_by/updated_by 字段。 如果您使用 WebAPI,您应该使用正确的 REST 语法:https://chad-test4.clas.uconn.edu/api/Employees/123 其中 123 应该是您正在更新的资源的 ID(即员工记录)。然后你的EmployeeModel 在请求正文中。如果您确实需要,可以将netId 添加到查询字符串中。这将匹配您的 DefaultApi 路由配置。 【参考方案1】:

根据this article,Web api 将尝试从 URL 中获取字符串值,并且您在请求正文中提供它。

尝试将您的 ajax 调用更改为:

$.ajax(
        type: "PUT",
        url: "https://chad-test4.clas.uconn.edu/api/Employees/PutEmployee?netId=22",
        dataType: "json",
        contentType: "application/json",
        data: JSON.stringify(employeeModel:employeeData),
        traditional: true,
        success: function() 
            console.log(employeeModel);
            alert("Saved Successfully.");
        ,
        error: function(response) 
            console.log(employeeModel);
            alert("Employee data failed to save to server. Error message: " + jQuery.parseJSON(response.responseText).Message);
        
    );

您不需要使用 [FromBody] 注释 EmployeeModel,因为它是一个复杂的对象。 Web Api 默认序列化会默认尝试从body中获取。

注意:如果 netID 是更新资源的用户的 ID,最好在 EmployeeModel 中有一个属性 UpdatedBy。 遵循 REST 原则,PUT 请求应该在 URL 中具有 resource 的 ID

【讨论】:

以上是关于C# Web Api 2 PUT 和 POST 请求“不支持”的主要内容,如果未能解决你的问题,请参考以下文章

asp.net mvc 和 web api 哪个更好 Http POST 或 PUT

ASP.NET Core Web API - PUT 与 PATCH

在Web Api中实现Http方法(Get,Put,Post,Delete)

C# Web API 405 方法没有路由到我的 PUT,总是点击我的 GET

VB.NET Web API CORS PUT 预检 405 错误

在 C# Web api 上进行用户身份验证的最佳实践是啥?