У кого-нибудь есть пример URL-адреса RESTful в ASP.NET MVC 2 RC, который работает?

Я пробовал код здесь:

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.


person John Campion    schedule 29.01.2010    source источник


Ответы (1)


Я выяснил, почему - HttpMethodConstraint не проверяет поле X-HTTP-Method-Override, и поэтому, например, в этой статье для HttpMethodConstraint было установлено только разрешение "PUT", но, конечно, "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; }

}
person John Campion    schedule 30.01.2010
comment
Вы проверяли последние изменения RESTful на github? Может там это исправлено. - person Arnis Lapsa; 30.01.2010
comment
Простой комментарий, глаголы в HTTP чувствительны к регистру, с чем нужно быть осторожным :) - person SerialSeb; 02.02.2010
comment
Чувак, ты только что ответил на мой вопрос. Отлично. - person Ruprict; 03.01.2011
comment
Не совсем уверен, в чем разница, но мне пришлось изменить строку httpContext.Request["X-HTTP..." на httpContext.Request.Headers["X-HTTP...", чтобы это работало. - person Paul Stovell; 03.01.2012