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

これは、ルートの生成時に属性ルーティングが作成する httpmethod 制約によるものです。

回避策(ここにはいくつかのオプションがあります):

  • この制約も追加され、OPTIONS リクエストが通過できるように、アクションを HttpOptions 動詞属性でも明示的に装飾します。

  • すべてのルートに 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 に答える