MVC-Web API:不允许使用 405 方法

Posted

技术标签:

【中文标题】MVC-Web API:不允许使用 405 方法【英文标题】:MVC-Web API: 405 method not allowed 【发布时间】:2014-06-11 04:58:16 【问题描述】:

所以,我陷入了一种奇怪的行为,也就是说,我可以使用Postman (plugin of chrome)RESTClient(extension of Firefox) 发送(或发布)数据,

但无法从位于项目外部的我的 html 文件发送它。当我在 chrome 中打开 html 时,它显示以下错误:

OPTIONS http://localhost:1176/api/user/ 405 (Method Not Allowed)
XMLHttpRequest cannot load http://localhost:1176/api/user/. Invalid HTTP status code 405 

我无法弄清楚为什么会发生这种情况。以下是详细信息,您可能需要帮助我解决我的错误:

UserController.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using WebAPIv2.Models;

namespace WebAPIv2.Controllers

    public class UserController : ApiController
    
        static IUserRepository userRepository = new UserRepository();

        [HttpGet]
        public List<TableUser> GetAllUsers()
        
            return userRepository.GetAll();
        

        [HttpGet]
        public HttpResponseMessage GetUser(int id)
        
            TableUser user = userRepository.Get(id);
            if (user == null)
            
                return Request.CreateErrorResponse(HttpStatusCode.NotFound, "User Not found for the Given ID");
            

            else
            
                return Request.CreateResponse(HttpStatusCode.OK, user);
            
        

        [HttpPost]
        public HttpResponseMessage PostUser(TableUser user)
        
            user = userRepository.Add(user);
            var response = Request.CreateResponse<TableUser>(HttpStatusCode.Created, user);
            string uri = Url.Link("DefaultApi", new  id = user.UserId );
            response.Headers.Location = new Uri(uri);
            return response;
        

        [HttpPut]
        public HttpResponseMessage PutUser(int id, TableUser user)
        
            user.UserId = id;
            if (!userRepository.Update(user))
            
                return Request.CreateErrorResponse(HttpStatusCode.NotFound, "Unable to Update the User for the Given ID");
            
            else
            
                return Request.CreateResponse(HttpStatusCode.OK);
            
        

        [HttpDelete]
        public HttpResponseMessage DeleteProduct(int id)
        
            userRepository.Remove(id);
            return new HttpResponseMessage(HttpStatusCode.NoContent);
        
    

User.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace WebAPIv2.Models

    public class User
    
        public int UserId  get; set; 
        public string UserName  get; set; 
        public string Password  get; set; 
        public string FirstName  get; set; 
        public string LastName  get; set; 
        public string Email  get; set; 
    

IUserRepository.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WebAPIv2.Models

    interface IUserRepository
    
        List<TableUser> GetAll();
        TableUser Get(int id);
        TableUser Add(TableUser user);
        void Remove(int id);
        bool Update(TableUser user);
    

UserRepository.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace WebAPIv2.Models

    public class UserRepository : IUserRepository
    
        MastarsFriendsMVCDatabaseEntities userEntities;

        public UserRepository()
        
            userEntities = new MastarsFriendsMVCDatabaseEntities();
        

        public List<TableUser> GetAll()
        
            //throw new NotImplementedException();

            return userEntities.TableUsers.ToList();
        

        public TableUser Get(int id)
        
            //throw new NotImplementedException();

            var users = userEntities.TableUsers.Where(x => x.UserId == id);
            if (users.Count() > 0)
            
                return users.Single();
            
            else
            
                return null;
            
        

        public TableUser Add(TableUser user)
        
            //throw new NotImplementedException();

            if (user == null)
            
                throw new ArgumentNullException("item");
            
            userEntities.TableUsers.Add(user);
            userEntities.SaveChanges();
            return user;
        

        public void Remove(int id)
        
            //throw new NotImplementedException();

            TableUser user = Get(id);
            if (user != null)
            
                userEntities.TableUsers.Remove(user);
                userEntities.SaveChanges();
            
        

        public bool Update(TableUser user)
        
            //throw new NotImplementedException();

            if (user == null)
            
                throw new ArgumentNullException("student");
            

            TableUser userInDB = Get(user.UserId);

            if (userInDB == null)
            
                return false;
            

            userEntities.TableUsers.Remove(userInDB);
            userEntities.SaveChanges();

            userEntities.TableUsers.Add(user);
            userEntities.SaveChanges();

            return true;
        
    

WebApiConfig.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Headers;
using System.Web.Http;

namespace WebAPIv2

    public static class WebApiConfig
    
        public static void Register(HttpConfiguration config)
        
            // Web API configuration and services

            // Web API routes
            config.MapHttpAttributeRoutes();
            //config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/controller/id",
                defaults: new  id = RouteParameter.Optional 
            );
        
    

index.html:

<!DOCTYPE html>
<html>
    <head>
        <title>TODO supply a title</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">

        <!--<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>-->
        <script src="http://code.jquery.com/jquery-2.1.0.min.js"></script>
    </head>
    <body>
        <script>
            $(document).ready(function() 
//                jQuery.support.cors = true;
//                $.ajax(
//                    url: "http://localhost:1176/api/user/1",
//                    headers: "Accept": "application/json",
//                    type: "GET",
//                    success: function(data) 
//                        alert(JSON.stringify(data));
//                    ,
//                    error: function() 
//                        alert("Error");
//                    
//                );
//            );

                var user = 
                    UserName: "Disha",
                    Password: "disha123",
                    FirstName: "Disha",
                    LastName: "Vora",
                    Email: "disha@pixielit.com"
                ;

                $.ajax(
                    url: 'http://localhost:1176/api/user/',
                    type: 'POST',
                    data: JSON.stringify(user),
                    crossDomain: true,
                    headers: "Accept":"application/json" , "Content-Type":"application/json",
                    success: function(data) 
                        alert('User added Successfully');
                    ,
                    error: function() 
                        alert('User not Added');
                    
                );
            );
        </script>
    </body>
</html>

Web.config:

<?xml version="1.0" encoding="utf-8"?>
<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=301879
  -->
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <appSettings></appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.5">
      <assemblies>
        <add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
      </assemblies>
    </compilation>
    <httpRuntime targetFramework="4.5" />
  </system.web>
  <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <modules runAllManagedModulesForAllRequests="true">
      <remove name="WebDAVModule" />
    </modules>
    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Request-Headers:" value="*" />
        <add name="Access-Control-Request-Method:" value="*" />
        <add name="Access-Control-Allow-Methods" value="*" />
        <!--<add name="Allow" value="*"/>-->
      </customHeaders>
    </httpProtocol>
    <handlers>
      <remove name="WebDAV" />
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <remove name="OPTIONSVerbHandler" />
      <remove name="TRACEVerbHandler" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
    <directoryBrowse enabled="true" />
  </system.webServer>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="v11.0" />
      </parameters>
    </defaultConnectionFactory>
  </entityFramework>
  <connectionStrings>
    <add name="MastarsFriendsMVCDatabaseEntities" connectionString="metadata=res://*/Model.csdl|res://*/Model.ssdl|res://*/Model.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=WIN-WWU3DMLR6PX\PIXIELIT;initial catalog=MastarsFriendsMVCDatabase;persist security info=True;user id=sa;password=sa_12345;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
  </connectionStrings>
</configuration>

【问题讨论】:

看看这是否有帮助***.com/questions/19162825/… @MilindAnantwar 先生,我已经在我的项目中应用了该解决方案。但是,没有成功... :( 【参考方案1】:

好的。在@martennis 回答的帮助下解决了这个问题,但稍作修正。

一切都很完美,只是需要注意的是,我们需要在包管理器控制台中输入以下命令:

Install-Package Microsoft.AspNet.WebApi.Cors –IncludePrerelease

与@martennis 提供的链接中显示的不同,之后,我的 WebApiConfig.cs 更新如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
using System.Web.Http.Cors;

namespace WebApiRESTfulwithJSON

    public static class WebApiConfig
    
        public static void Register(HttpConfiguration config)
        
            // Web API configuration and services
            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 
            );
        
    

因此,解决了问题...!!!

现在,我可以在任何地方使用我的网络服务,从移动应用程序、网络应用程序或桌面应用程序调用它。

对于如何从头开始创建它们,我为此写了我的第一篇博客(...尽管是 android 开发人员,但从未尝试为 Android 写博客 :-P 不管怎样...)

链接:http://programmingwithease.wordpress.com/2014/06/18/learning-asp-net-web-api-2-using-c/

【讨论】:

解决了我的问题!【参考方案2】:

WebApi 可能会阻止 CORS 请求。要在 WebApi 上启用 CORS,请使用 Microsoft.AspNet.WebApi.Cors 包。更多详情,请查看http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api

【讨论】:

【参考方案3】:

不需要webconfig,只需要添加:

  services.AddCors(o => o.AddPolicy("MyPolicy", builder =>
            
                builder.AllowAnyOrigin()
                       .AllowAnyMethod()
                       .AllowAnyHeader();
            ));

【讨论】:

【参考方案4】:

从控制器类中删除“使用 System.Web.MVC”为我解决了这个问题。

【讨论】:

以上是关于MVC-Web API:不允许使用 405 方法的主要内容,如果未能解决你的问题,请参考以下文章

Rest API - 不允许使用 405 方法 [重复]

在 DELETE 上不允许使用 Owin 自托管 Web API 405 方法

405 方法不允许 - ASP.NET Web API

discord oauth2 api 调用返回“405:不允许的方法”

“无法在已发布的 Web API 上发布数据” – 405(不允许的方法)

Flutter - 错误:不允许使用 HTTP 405 方法