私はこの質問に対する答えを探していましたが、実際に非常によく似たこの質問を見つけました。しかし、そこに投稿された解決策は私にとってはうまくいかないようです...質問の年齢と関係があるのでしょうか。
次の URL を指定します。
/my/items/6
この URL に対する HTTP PUT リクエストを 1 つのアクション メソッドで処理し、HTTP DELETE リクエストを別のアクション メソッドで処理する必要があります。以下は私が定義したルートです(これらは特定の地域に基づいていることに注意してください。それcontext
がAreaRegistrationContext
重要な場合はインスタンスです):
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 およびルーティング クラスを使用してすぐに使用できるようにする方法はありますか?