有人在ASP.NET MVC 2 RC中有一个RESTful URL的例子吗?

时间:2010-01-29 23:17:32

标签: asp.net-mvc rest

我在这里尝试了代码:

http://dotnetslackers.com/articles/aspnet/Implementing-RESTful-Routes-and-Controllers-in-ASP-NET-MVC-2-0.aspx#s-reststyle-routes--controllers

但我无法使用ASP.NET MVC 2.0 RC - PUT和DELETE动词不会被使用。输出似乎是正确的,但路由处理程序似乎忽略了HttpMethodOverride。

我禁用了默认路由,现在当我尝试提交覆盖设置为PUT的表单时,不允许出现错误“用于访问路径的HTTP动词POST'/ contacts / 2'。”即将到来。所以它似乎忽略了MethodOverride。

1 个答案:

答案 0 :(得分:3)

我发现了原因--HttpMethodConstraint没有检查X-HTTP-Method-Override字段,因此,例如,在那篇文章中,HttpMethodConstraint被设置为仅允许“PUT”,但是couurse“POST”是被HttpContext返回,所以它失败了。

我写了自己的RouteConstraint并将其发布在此处,以便其他人可以从我的麻烦中学习。

    public class HttpVerbConstraint : IRouteConstraint {

    public HttpVerbConstraint(params string[] allowedMethods) {
        if (allowedMethods == null) {
            throw new ArgumentNullException("allowedMethods");
        }
        this.AllowedMethods = allowedMethods.ToList<string>().AsReadOnly();
    }

    protected virtual bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) {
        if (httpContext == null) {
            throw new ArgumentNullException("httpContext");
        }
        if (route == null) {
            throw new ArgumentNullException("route");
        }
        if (parameterName == null) {
            throw new ArgumentNullException("parameterName");
        }
        if (values == null) {
            throw new ArgumentNullException("values");
        }

        string method = httpContext.Request["X-HTTP-Method-Override"] ?? httpContext.Request.HttpMethod;

        switch (routeDirection) {
            case RouteDirection.IncomingRequest:
                return AllowedMethods.Any(v =>
                v.Equals(method, StringComparison.OrdinalIgnoreCase));
            case RouteDirection.UrlGeneration:
                string verb = "GET";
                if (values.ContainsKey(parameterName))
                    verb = values[parameterName].ToString();
                return AllowedMethods.Any(v =>
                    v.Equals(verb, StringComparison.OrdinalIgnoreCase));
        }
        return true;
    }

    bool IRouteConstraint.Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) {
        return this.Match(httpContext, route, parameterName, values, routeDirection);
    }

    public ICollection<string> AllowedMethods { get; set; }

}