4

使用以下路线:

routes.MapHttpRoute(
           name: "Set",
           routeTemplate: "api/set/{id}",
           defaults: new { controller = "Set", id = RouteParameter.Optional }
           );

映射到以下方法:

    [HttpDelete]
    [AcceptVerbs("DELETE")]
    public HttpResponseMessage DeleteSet(int id)
    {
     //stuff
    }

我可以通过这个调用删除集合:

   DELETE api/set/1

在此处输入图像描述

但是,如果我删除上述路由以支持属性路由:

    [HttpDelete("api/set/{id}")]
    [AcceptVerbs("DELETE")]
    public HttpResponseMessage DeleteSet(int id)
    {
     //stuff
    }

并添加到我的配置中:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        var cors = new EnableCorsAttribute("http://localhost:11089", "*", "*");
        config.MapHttpAttributeRoutes(); // new, working with stuff other than delete
        config.EnableCors(cors);  // already working, not new
     }
 }

由于 CORS 问题,相同的请求中断:

在此处输入图像描述

在图像中,您会看到一个查询参数,但这适用于仅具有 id 的简单 DELETE 查询。到底他妈发生了什么?我们在属性映射上投入了大量时间,但因为 DELETE 不起作用,所以必须回滚所有内容会很臭。

这是另一个使用简单 id 中断的 DELETE 实例:

在此处输入图像描述

以上来自这个请求:

var options = {
            url: apiEndpoint + 'card/' + id,
            type: 'DELETE',
            dataType: 'json',
            xhrFields: {
                withCredentials: true
            }
        };

        return $.ajax(options)

更新 如果我们在所有删除方法中加上“ [AcceptVerbs("OPTIONS")]”,那么它就可以工作。似乎不优雅,如果有人有权威的答案,我想保持开放状态。

4

1 回答 1

4

您似乎遇到了将 CORS 与属性路由结合使用的已知问题。以下问题目前正在跟踪。

http://aspnetwebstack.codeplex.com/workitem/954

这是由于 Attribute Routing 在生成路由时创建的 httpmethod 约束。

解决方法(您有几个选项在这里):

  • 也使用 HttpOptions 动词属性显式装饰操作,以便添加此约束并且您的 OPTIONS 请求可以通过。

  • 创建一个自定义路由构建器,它将 OPTIONS 添加到所有路由(如果您愿意,您可以修改此行为)。一些示例代码:

    config.MapHttpAttributeRoutes(new CustomRouteBuilder());
    
    public class CustomRouteBuilder : HttpRouteBuilder
    {
        public override IHttpRoute BuildHttpRoute(HttpRouteValueDictionary defaults, HttpRouteValueDictionary constraints, 
                                                    string routeTemplate)
        {
            HttpMethodConstraint currentMethodConstraint = (HttpMethodConstraint)constraints["httpMethod"];
            List<HttpMethod> methods = currentMethodConstraint.AllowedMethods.ToList();
            if (!methods.Contains(HttpMethod.Options))
            {
                methods.Add(HttpMethod.Options);
            }
    
            HttpMethodConstraint newMethodConstraint = new HttpMethodConstraint(methods.ToArray());
            HttpRouteValueDictionary newConstraints = new HttpRouteValueDictionary();
            newConstraints["httpMethod"] = newMethodConstraint;
            return base.BuildHttpRoute(defaults, newConstraints, routeTemplate);
        }
    }
    
于 2013-07-23T01:20:26.473 回答