【问题标题】:WebAPI CORS not allowing Post requestsWebAPI CORS 不允许发布请求
【发布时间】:2014-12-20 23:36:48
【问题描述】:

我已经用尽了所有关于 Cors 的资源,但在从 Angular 的 $http 服务(通过 Chrome)发送请求时仍然收到以下错误消息:

POST http://localhost:61459/api/LoginAuth/PostLoginByHandle 500 (Internal Server Error) 

获取请求工作得很好。我发现了一百种似乎对其他人有用的类似指令,但我就是无法破解这个指令。我会发布我的代码。

WebApiConfig:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {

        // Web API configuration and services




        // Web API routes
        config.MapHttpAttributeRoutes();

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

        //var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
        //jsonFormatter.SerializerSettings = new CamelCasePropertyNamesContractResolver();

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




    }
}

据我了解,这应该足以允许全球范围内的任何 Cors 请求。另外,我用以下标记控制器:

[EnableCors(origins: "*", headers: "*", methods: "*")]

我尝试使用我在网上找到的各种东西来修改我的 web.config,但我读到以编程方式进行时没有必要。知道我做错了什么吗?

我已将这篇文章标记为 angularjs,以防我在那里做错了什么,因为我对它很陌生。这是我的电话:

    $http.post("http://localhost:61459/api/LoginAuth/PostLoginByHandle",this.LoginRequest).success(function(data){
  testCtrl.user = data;
  console.log("Retrieved: " + data);
});

**编辑:当我删除 top 方法时,我可以用 Postman 击中控制器。知道为什么这些会冲突吗?邮递员给出了这个错误:

"Message": "An error has occurred.",
"ExceptionMessage": "Multiple actions were found that match the request: \r\nLoginByKey on type RecruitingTool.Web.Controllers.LoginAuthController\r\nPostLoginByHandle on type RecruitingTool.Web.Controllers.LoginAuthController"

这里是控制器代码。我不明白为什么这些会发生冲突:

    [HttpPost]
    public LoginResult LoginByKey(LoginRequest req)
    {
        LoginResult l = new LoginResult();
        if (!string.IsNullOrEmpty(req.Key) &&
            HttpContext.Current.Cache["credentials." + req.Username.ToUpper()].ToString() == req.Key)
        {
            l.Success = true;
        }
        else
        {
            l.Success = false;
            l.ErrorMessage = "The credentials key is not valid.";
        }
        return l;
    }


    [HttpPost]
    [EnableCors(origins: "*", headers: "*", methods: "POST")]
    public LoginResult PostLoginByHandle(LoginRequest req)
    {
        LoginResult l = new LoginResult();
        if (req.Username.ToUpper() == "TESTUSER" && req.Password == "test")
        {
            //change to authenticate against DB
            l.Success = true;
            l.CredentialsKey = Guid.NewGuid().ToString();
            l.ErrorMessage = "";
            HttpContext.Current.Cache["credentials." + req.Username.ToUpper()] = Guid.NewGuid().ToString();
        }
        else
        {
            l.Success = false;
            l.ErrorMessage = "The username or password is not correct. Please check your information and try again.";
        }

        return l;
    }

**编辑 2:问题是两种方法的默认路由之间存在冲突。我不确定为什么会这样,但是一旦我为它们指定了一个明确的路线,它就解决了。如果有人知道,我仍然很想知道答案。谢谢大家!

【问题讨论】:

    标签: angularjs asp.net-mvc asp.net-web-api asp.net-web-api2


    【解决方案1】:

    如果您在 Web API POST 控制器操作中设置断点,它不会命中它吗? HTTP 500 通常表示您的代码存在问题(未处理的异常)。

    如果它没有触发该控制器操作,则它必须在管道中更早。您是否尝试过从 POSTman 之类的工具直接发布到您的 API 方法?非常有用的 Chrome 扩展..

    【讨论】:

    • 是的。尝试使用 Postman 或 Fiddler 提出请求,以便 cors 不在图片中,看看它是否有效。我同意问题可能出在其他地方。
    • 它没有击中控制器。 Postman 会有同样的 Cors 问题吗?我对究竟什么是跨域有点模糊。我正在从 WebStorm 内置服务器运行前端,该服务器也是具有不同端口号的本地主机。因此,我很惊讶一开始就收到了错误。
    • 我已经通过删除我刚刚进行的编辑的顶部方法来点击控制器。我会弄乱路由,但这种冲突对我来说很奇怪。
    • 当我明确指定路线时,问题就消失了。不知道为什么会这样,但如果有人知道原因,我很想知道。
    【解决方案2】:

    1- 你的方法参数缺少 [FromBody] 属性,所以应该是这样的

    public LoginResult PostLoginByHandle([FromBody]LoginRequest req)
    

    2- 此外,两种方法在参数数量和 req 参数的数据类型方面具有完全相同的签名。

    希望有帮助。

    【讨论】:

      【解决方案3】:

      WebAPI 支持基于约定的路由:

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

      您确定那里没有两种方法,一种称为 PostXXX,另一种称为 XXX?或者也许名为 POSTxxx 的那个正在触发基于约定的路由。我见过提到“约定可能导致路由表中的冲突,匹配不正确的操作。”

      尝试将您的方法重命名为 Postxxx、Getxxx 以外的其他名称...

      [PS Attribute-routing 好多了]

      【讨论】:

      • 我列出的两种方法是该控制器中仅有的两种。对他们来说真的没什么。也许有一个基于登录前缀的约定?不管怎样,我已经吸取了教训——从现在开始我将使用属性。
      • 我可以在没有属性的情况下点击控制器。多么奇怪的约定副作用!
      • 啊……您的默认路由不包含该操作,因此它正在寻找任何匹配的方法。见stackoverflow.com/a/21153696/224370
      • 太棒了。谜团已揭开。谢谢。我是一名 MVC 开发人员,在专业领域只有 1 年的时间,所以我很欣赏这些知识。
      • 我同意之前的帖子:属性路由是要走的路。
      【解决方案4】:

      我今天遇到了同样的问题。事实证明,问题出在飞行前的 OPTIONS 请求中。我使用了这个解决方案:Handling CORS Preflight requests to ASP.NET MVC actions

      此外,我在响应中添加了标头,并从项目中删除了 Microsoft.AspNet.WebApi.Cors:

      protected void Application_BeginRequest()
      {
          //CORS
          if (Request.Headers.AllKeys.Contains("Origin"))
          {
              Response.Headers.Add("Access-Control-Allow-Origin", string.IsNullOrWhiteSpace(ConfigurationManager.AppSettings["CORS_ORIGIN"]) ? "*" : ConfigurationManager.AppSettings["CORS_ORIGIN"]);
              Response.Headers.Add("Access-Control-Allow-Methods", "OPTIONS, GET, POST, PUT, DELETE");
              Response.Headers.Add("Access-Control-Allow-Headers", "Access-Control-Allow-Methods, Access-Control-Allow-Origin, Content-Type, Accept, X-Requested-With, Session");
              //handle CORS pre-flight requests
              if (Request.HttpMethod == "OPTIONS")
                  Response.Flush();
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2023-03-10
        • 2018-07-28
        • 1970-01-01
        • 2015-03-09
        • 2016-09-15
        • 2019-07-02
        • 2016-11-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多