gpt4 book ai didi

c# - 从自定义 AdditionalMetadataAttribute (asp.net mvc 5) 访问模型类实例

转载 作者:太空宇宙 更新时间:2023-11-03 15:49:38 24 4
gpt4 key购买 nike

我遇到以下情况 - 我需要编写一个自定义的附加元数据属性,它基于另一个属性值(来自同一模型),向 AdditionalValues 字典添加一个值。现在,我的问题是我无法访问属性类中的模型实例。

[AttributeUsage(AttributeTargets.Property)]
public class ExtendedAdditionalMetadataAttribute : Attribute, IMetadataAware
{
#region Private properties
private string extraFieldToCheck { get; set; }

private string extraFieldValueToCheck { get; set; }

private string fieldToBeAdded { get; set; }

private string fieldValueToBeAdded { get; set; }
#endregion

#region Constructor
public ExtendedAdditionalMetadataAttribute(string extraFieldToCheck, string extraFieldValueToCheck,
string fieldToBeAdded, string fieldValueToBeAdded)
{
this.extraFieldToCheck = extraFieldToCheck;
this.extraFieldValueToCheck = extraFieldValueToCheck;
this.fieldToBeAdded = fieldToBeAdded;
this.fieldValueToBeAdded = fieldValueToBeAdded;
}
#endregion

public void OnMetadataCreated(ModelMetadata metadata)
{
// HOW TO GET THE MODEL CLASS INSTANCE???
// metadata.ContainerType is correct by metadata.Container is null.
}
}

正如您从代码注释中看到的,在 OnMetadataCreated 内部我需要访问 Model 类实例,但是尽管 ContainerType 是正确的,但 Container 属性为 NULL。

你能给我一些关于这个问题的提示吗?

提前致谢!

埃夫丁

稍后编辑

考虑到我没有给出太多解释,我还将在此处粘贴一个示例,说明我想如何在模型类上使用此属性:

/// <summary>
/// Gets or sets the IsAccountCreated
/// </summary>
/// <value>The IsAccountCreated.</value>
[UIHint("FormFieldStringTemplate")]
[ExtendedAdditionalMetadata("IsExternalAccount", "true", "ReadOnly", "true")]
public override Boolean IsAccountCreated { get; set; }

/// <summary>
/// Gets or sets the IsAccountEnabled
/// </summary>
/// <value>The IsAccountEnabled.</value>
[Display(Name = "Este cont activ?")]
[UIHint("FormFieldStringTemplate")]
[ExtendedAdditionalMetadata("IsExternalAccount", "true", "ReadOnly", "true")]
public override Boolean IsAccountEnabled { get; set; }

/// <summary>
/// Gets or sets the IsExternalAccount
/// </summary>
/// <value>The IsExternalAccount.</value>
[Display(Name = "Este cont extern?")]
[UIHint("FormFieldStringTemplate")]
[AdditionalMetadata("ReadOnly", "true")]
public override Boolean IsExternalAccount { get; set; }

后期和后期编辑

尽管@stephen-muecke 给出的响应在当前情况下更加简单和可接受,但为了编程挑战,我寻找了其他选项,并发现了以下可能性:实现自定义 DataAnnotationsModelMetadataProvider类。简单地说 - 它有效并且我能够获得模型类实例但是只有当模型类是一个简单类时,否则会有很多缺点 - 例如如果你有一个模型类并且你在你的 View 中使用它那么没关系,但是如果您在另一个类中有一个类( View 模型中的模型),则此方法不再可用。

再次感谢@stephen-muecke!

最佳答案

由于您似乎需要访问模型的多个属性,因此属性应该以 class (AttributeTargets.Class) 为目标并应用于模型,而不是属性.这可能意味着您需要添加另一个属性,即您尝试将其应用到的属性的名称。注意 metadata.ContainerType 只为您提供 type,而不是此实例,因此您只能获取其属性的默认值。

编辑

如果属性需要应用于模型中的多个属性,则无法访问 OnMetadataCreated 中的容器,因为元数据是从最里面的属性创建的,所以模型的元数据尚未创建.

根据 OP 的评论,更好的解决方案是创建自定义 html 帮助程序。例如根据另一个属性的值生成一个只读的文本框

namespace MyHelpers.Html
{
public static class ReadOnlyHelpers
{
public static MvcHtmlString ReadOnlyTextBoxIf<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression, bool isReadOnly)
{
object attributes = isReadOnly ? new { @readonly = "readonly" } : null;
return InputExtensions.TextBoxFor(helper, expression, attributes);
}
}
}

并在您的 View 中用作

@Html.ReadOnlyTextBoxIf(m => m.SomeTextProperty, Model.SomeBooleanValue)

创建“只读”复选框有点困难,因为 readonly 属性对 checkbox 没有影响。为了防止用户交互,您需要禁用它,但这意味着该值不会回发

public static MvcHtmlString ReadOnlyCheckBoxIf<TModel>(this HtmlHelper<TModel> helper, Expression<Func<TModel, bool>> expression, bool isReadOnly)
{
if (isReadOnly)
{
// If you want to 'visually' render a checkbox (otherwise just render a div with "YES" or "NO")
ModelMetadata metaData = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
StringBuilder html = new StringBuilder();
// Add a hidden input for postback
html.Append(InputExtensions.HiddenFor(helper, expression).ToString());
// Add a visual checkbox without name so it does not post back
TagBuilder checkbox = new TagBuilder("input");
checkbox.MergeAttribute("type", "checkbox");
checkbox.MergeAttribute("disabled", "disabled");
if ((bool)metaData.Model)
{
checkbox.MergeAttribute("checked", "checked");
}
html.Append(checkbox.ToString());
return MvcHtmlString.Create(html.ToString());
}
else
{
// return normal checkbox
return InputExtensions.CheckBoxFor(helper, expression);
}
}

并在您的 View 中用作

@Html.ReadOnlyCheckBoxIf(m => m.IsAccountCreated, Model.IsExternalAccount)

关于c# - 从自定义 AdditionalMetadataAttribute (asp.net mvc 5) 访问模型类实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26482305/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com