Csharp/C#教程:ModelMetaData,自定义类属性和难以形容的问题分享


ModelMetaData,自定义类属性和难以形容的问题

我想做的事情似乎很简单。

在我的index.cshtml中,我想显示WizardStepAttribute

因此,用户将在每个页面的顶部看到, Step 1: Enter User Information


我有一个名为WizardViewModel的ViewModel。 此ViewModel具有IList Steps的属性

每个“步骤”实现接口IStepViewModel,这是一个空接口。

我有一个名为Index.cshtml的视图。 此视图显示EditorFor()当前步骤。

我有一个自定义的ModelBinder,它将View绑定到一个基于WizardViewModel.CurrentStepIndex属性实现IStepViewModel的具体类的新实例

我创建了一个自定义属性WizardStepAttribute

我的每个步骤类都是这样定义的。

 [WizardStepAttribute(Name="Enter User Information")] [Serializable] public class Step1 : IStepViewModel .... 

我有几个问题。

对于WizardViewModel我的视图是强类型, WizardViewModel不是每一步。 我不想为IStepViewModel每个具体实现创建一个视图

我以为我可以在界面中添加属性,但是我必须在每个类中明确地实现它。 (所以这不是更好)

我想我可以使用界面中的reflection来实现它,但是,你不能在接口中的方法中引用实例。

它可以做到,但既不容易也不漂亮。

首先,我建议在WizardStepAttribute类StepNumber中添加第二个字符串属性,以便您的WizardStepAttribute类如下所示:

 [AttributeUsage(AttributeTargets.All, AllowMultiple = false)] public class WizardStepAttribute : Attribute { public string StepNumber { get; set; } public string Name { get; set; } } 

然后,每个class级必须装饰:

 [WizardAttribute(Name = "Enter User Information", StepNumber = "1")] public class Step1 : IStepViewModel { ... } 

接下来,您需要创建自定义DataAnnotationsModelMetadataProvider,以获取自定义属性的值并将它们插入Step1模型的元数据中:

 public class MyModelMetadataProvider : DataAnnotationsModelMetadataProvider { protected override ModelMetadata CreateMetadata( IEnumerable attributes, Type containerType, Func modelAccessor, Type modelType, string propertyName) { var modelMetadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName); var additionalValues = attributes.OfType().FirstOrDefault(); if (additionalValues != null) { modelMetadata.AdditionalValues.Add("Name", additionalValues.Name); modelMetadata.AdditionalValues.Add("StepNumber", additionalValues.StepNumber); } return modelMetadata; } } 

然后,为了呈现您的自定义元数据,我建议您创建一个自定义HtmlHelper来为每个视图创建标签:

  [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")] public static MvcHtmlString WizardStepLabelFor(this HtmlHelper htmlHelper, Expression> expression) { return WizardStepLabelFor(htmlHelper, expression, null /* htmlAttributes */); } [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")] public static MvcHtmlString WizardStepLabelFor(this HtmlHelper htmlHelper, Expression> expression, object htmlAttributes) { return WizardStepLabelFor(htmlHelper, expression, new RouteValueDictionary(htmlAttributes)); } [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "Users cannot use anonymous methods with the LambdaExpression type")] [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")] public static MvcHtmlString WizardStepLabelFor(this HtmlHelper htmlHelper, Expression> expression, IDictionary htmlAttributes) { if (expression == null) { throw new ArgumentNullException("expression"); } ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData); var values = metadata.AdditionalValues; // build wizard step label StringBuilder labelSb = new StringBuilder(); TagBuilder label = new TagBuilder("h3"); label.MergeAttributes(htmlAttributes); label.InnerHtml = "Step " + values["StepNumber"] + ": " + values["Name"]; labelSb.Append(label.ToString(TagRenderMode.Normal)); return new MvcHtmlString(labelSb.ToString() + "r"); } 

如您所见,自定义帮助程序使用您的自定义元数据创建h3标记。

然后,最后,在您看来,输入以下内容:

 @Html.WizardStepLabelFor(model => model) 

两个注意事项:首先,在Global.asax.cs文件中,将以下内容添加到Application_Start():

  ModelMetadataProviders.Current = new MyModelMetadataProvider(); 

其次,在Views文件夹的web.config中,确保为自定义HtmlHelper类添加命名空间:

             

瞧。

counsellorben

在我们的例子中,我们只需要一个实现IMetadataAware接口的属性:

https://msdn.microsoft.com/en-us/library/system.web.mvc.imetadataaware(v=vs.118).aspx

在您的情况下,这可能是:

上述就是C#学习教程:ModelMetaData,自定义类属性和难以形容的问题分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!

 public class WizardStepAttribute : Attribute, IMetadataAware { public string Name; public void OnMetadataCreated(ModelMetadata metadata) { if (!metadata.AdditionalValues.ContainsKey("WizardStep")) { metadata.AdditionalValues.Add("WizardStep", Name); } } } 

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/cdevelopment/959381.html

(0)
上一篇 2021年11月23日
下一篇 2021年11月23日

精彩推荐