0

ビュー内のオブジェクトを保護するためにカスタム属性を設定しています。カスタム属性の定義は次のとおりです。

[AttributeUsage(AttributeTargets.Property)]
public class SecureObjectAttribute : Attribute, IMetadataAware
{
    public void OnMetadataCreated(ModelMetadata metadata)
    {
        if(!metadata.AdditionalValues.ContainsKey("isSecure"))
        {
            if (ObjectId == 1)
            {
                metadata.AdditionalValues.Add("isSecure", true);
            }
            else
            {
                metadata.AdditionalValues.Add("isSecure", false);
            }
        }
    }
    public int ObjectId { get; set; }
}

ここに私のビューモデルがあります:

public class HomeViewModel
{
    [SecureObject(ObjectId = 1)]
    [Display(Name = "Name")]
    public string Name { get; set; }

    [Display(Name = "Address")]
    public string Address { get; set; }
}

Secure Labels と Secure TextBoxes のヘルパーを定義しています。ここに私のヘルパー関数があります:

    public static MvcHtmlString SecureLabelFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression)
    {
        var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
        if ((bool)metadata.AdditionalValues["isSecure"])
        {
            return null;
        }
        else
        {
            return html.LabelFor(expression);
        }
    }

    public static MvcHtmlString SecureTextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression)
    {
        var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
        if ((bool)metadata.AdditionalValues["isSecure"])
        {
            return null;
        }
        else
        {
            return html.TextBoxFor(expression);
        }
    }

これはすべて正しく機能しますが、私が抱えている問題は、安全なラベルと安全なテキスト ボックスを定義するたびに、OnMetadataCreated メソッドが呼び出されることです。

オブジェクトの権限を取得するために OnMetadataCreated メソッド (例には示されていません) でデータベースにアクセスしていますが、1 つのオブジェクトに対して重複したアクセスを回避したいと考えています。

以下は、ビューで OnMetadataCreated が 2 回呼び出される原因となっているコードの例です。

    @Html.SecureLabelFor(m => m.Name)
    @Html.SecureTextBoxFor(m => m.Name)

OnMetadataCreated メソッドへの 2 回目の呼び出しを回避する方法、またはデータベースへの重複したトリップを回避する方法について何か提案はありますか?

4

1 に答える 1

0

クエリの実行結果をHttpContextに保存して、同じリクエスト内でデータベースへのラウンドトリップを回避できます。

public void OnMetadataCreated(ModelMetadata metadata)
{
    // TODO: if you are using a DI framework you could pass the context
    // as a constructor argument dependency and use HttpContextBase
    HttpContext context = HttpContext.Current;

    bool isSecure;
    string key = "isSecure_" + ObjectId;
    if (context.Items.Contains(key))
    {
        // The isSecure value was found in the HttpContext => 
        // no need to query the database once again within this request
        isSecure = (bool)context.Items[key];
    }
    else
    {
        // Get the value from the database
        isSecure = GetFromDb(context.User.Identity.Name, ObjectId);
        // and store into the HttpContext to avoid roundtrips to the database
        // within this request
        context.Items[key] = isSecure;
    }

    ...
}
于 2013-01-22T08:22:26.147 に答える