0

私はこの質問に対する答えを探していましたが、実際に非常によく似たこの質問を見つけました。しかし、そこに投稿された解決策は私にとってはうまくいかないようです...質問の年齢と関係があるのでしょうか。

次の URL を指定します。

/my/items/6

この URL に対する HTTP PUT リクエストを 1 つのアクション メソッドで処理し、HTTP DELETE リクエストを別のアクション メソッドで処理する必要があります。以下は私が定義したルートです(これらは特定の地域に基づいていることに注意してください。それcontextAreaRegistrationContext重要な場合はインスタンスです):

context.MapRoute(null,
    "my/items/{id}",
    new { area = "AreaName", controller = "ControllerName", action = "Replace" },
    new
    {
        httpMethod = new HttpMethodConstraint("POST", "PUT"),
    }
);

context.MapRoute(null,
    "my/items/{id}",
    new { area = "AreaName", controller = "ControllerName", action = "Destroy" },
    new
    {
        httpMethod = new HttpMethodConstraint("POST", "DELETE"),
    }
);

URL 生成はこれらのルートの両方で正常に機能しますが、着信要求をルーティングするときに問題があります。最初に宣言されたルートのみが、それぞれのアクションに正しくマップされます。

ソースコードを掘り下げたところ、パラメーターHttpMethodConstraintは気にせず、 ."X-HTTP-Method-Override"HttpContext.Request.HttpMethod

この問題は、次のカスタム ルート制約クラスで解決できました。

public class HttpMethodOverrideConstraint : HttpMethodConstraint
{
    public HttpMethodOverrideConstraint(params string[] allowedMethods) 
        : base(allowedMethods) { }

    protected override bool Match(HttpContextBase httpContext, Route route, 
        string parameterName, RouteValueDictionary values, 
        RouteDirection routeDirection)
    {
        var methodOverride = httpContext.Request
            .Unvalidated().Form["X-HTTP-Method-Override"];

        if (methodOverride == null)
            return base.Match(httpContext, route, parameterName, 
                values, routeDirection);

        return 
            AllowedMethods.Any(m => 
                string.Equals(m, httpContext.Request.HttpMethod, 
                    StringComparison.OrdinalIgnoreCase))
            &&
            AllowedMethods.Any(m => 
                string.Equals(m, methodOverride, 
                    StringComparison.OrdinalIgnoreCase))
        ;
    }
}

...そしてこれらのルート定義:

context.MapRoute(null,
    "my/items/{id}",
    new { area = "AreaName", controller = "ControllerName", action = "Replace" },
    new
    {
        httpMethod = new HttpMethodOverrideConstraint("POST", "PUT"),
    }
);

context.MapRoute(null,
    "my/items/{id}",
    new { area = "AreaName", controller = "ControllerName", action = "Destroy" },
    new
    {
        httpMethod = new HttpMethodOverrideConstraint("POST", "DELETE"),
    }
);

私の質問: これを達成するためにカスタム ルート制約が本当に必要ですか? または、標準の MVC およびルーティング クラスを使用してすぐに使用できるようにする方法はありますか?

4

1 に答える 1

0

アクションフィルターはあなたの友達です...

HttpDeleteAttributeHttpPutAttributeHttpPostAttributeHttpGetAttribute

于 2012-06-06T18:41:34.257 に答える