1

注:この質問に回答した後、この特定の質問は OData に非常に関連しており、一般的な C# には関連していないように見えることに注意してください。

奇妙な問題があります。AuthorizeAttributeクラスからApiAuthorize属性を派生させました。この属性は、標準のログイン手順とは別に、ACL に似た追加のチェックを行います。

この属性をクラス全体に適用すると、すべてのメソッドで期待どおりに機能します。ただし、メソッドに個別に適用すると、すべてのメソッドで機能しません。

以下は、OData と Web Api を使用したコードの一部です。

public class UsersController : EntitySetController<User, int>
{
    [ApiAuthorize]
    public override IQueryable<User> Get()
    {
        DoSomething();
    }

    [ApiAuthorize]
    protected override User GetEntityByKey(int key)
    {
        DoSomethingElse();
    }
}

Getを使用してメソッドを呼び出すと、クラス/odata/UsersOnAuthorizationメソッドApiAuthorizeが適切に呼び出されます。属性を使用してGetEntityByKeyメソッドを呼び出すと、完全に無視され、プログラムはメソッド内ですぐにジャンプします。しかし、前に述べたように、メソッドから属性を削除してクラス全体に適用すると、実際に属性が呼び出されます。/odata/Users(1284)ApiAuthorizeGetEntityByKeyApiAuthorize

これ自体はもちろん奇妙ですが、OData に移行する前 (したがってApiController、現在使用されている の代わりに an を使用EntitySetController) は、この属性が適用された方法に関係なく常に機能していたため、さらに奇妙です。それで、これがEntitySetController壊れているようです。

OData が何らかの形でこの実装を壊している可能性はありますか?

アップデート

Josh E の質問に答えるには:

派生属性は非常に大きいので、些細なことなので、それを否定したバージョンは質問に寄与しないと思いますが、次のようになります。

public class ApiAuthorize : AuthorizeAttribute
{
    public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
        HttpRequestHeaders headers = actionContext.Request.Headers;
        NameValueCollection getParams = HttpUtility.ParseQueryString(actionContext.Request.RequestUri.Query);

        DoALotOfThings();
    }
}

これは派生属性のごく一部にすぎませんが、コードは少なくともOnAuthorizationメソッド内に到着する必要があります。このメソッドは、基本クラスから実際にオーバーライドする唯一のメソッドであり、残りは単に継承されることに注意してください。

4

1 に答える 1

1

現在お気づきの動作GetEntityByKeyは想定されたものです。代わりに、メソッドをオーバーライドしGet([FromODataUri] TKey key)て属性を適用する必要があります。その場合、期待どおりの動作が見られます。

以下は からのソースコードですEntitySetController。GetEntityByKey は Get([FromODataUri] TKey key) アクション内から呼び出されます。

    /// <summary>
    /// Handles GET requests that attempt to retrieve an individual entity by key from the entity set.
    /// </summary>
    /// <param name="key">The entity key of the entity to retrieve.</param>
    /// <returns>The response message to send back to the client.</returns>
    public virtual HttpResponseMessage Get([FromODataUri] TKey key)
    {
        TEntity entity = GetEntityByKey(key);
        return EntitySetControllerHelpers.GetByKeyResponse(Request, entity);
    }
于 2013-07-15T15:11:06.090 に答える