I am setting custom attributes to secure objects within a view. Here is the definition for my custom attributes:
[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; }
}
Here is my View Model:
public class HomeViewModel
{
[SecureObject(ObjectId = 1)]
[Display(Name = "Name")]
public string Name { get; set; }
[Display(Name = "Address")]
public string Address { get; set; }
}
I am defining helpers for Secure Labels and Secure TextBoxes. Here are my helper functions:
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);
}
}
All of this works correctly, however, the problem that I am having is that every time I define a secure label and a secure textbox, the OnMetadataCreated method is invoked.
I am making a trip to the database on the OnMetadataCreated method (not shown in the example) to get permissions for the object, and I want to avoid duplicate trips for a single object.
The following is an example of code that is causing the OnMetadataCreated to be invoked twice in my View:
@Html.SecureLabelFor(m => m.Name)
@Html.SecureTextBoxFor(m => m.Name)
Any suggestions on how I can avoid a second call to the OnMetadataCreated method, or avoid a duplicate trip to the database?
You could store the result of the execution of the query in the HttpContext to avoid roundtrips to the database within the same request: