问题标签 [modelmetadata]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
asp.net-mvc - 动态对象的 MVC3/4 安全和模型绑定
我真的需要对这个问题进行第二次观察,所以我希望你们中的一些人能给我一些反馈,我想我已经盯着它太久了。
我正在尝试使用 ASP.NET MVC3 设置一个网站,在这个网站中我需要创建动态对象的灵活性。但我的意思是在我的数据库中设置了一系列表来存储有关这些动态对象中包含的结构和数据的信息。我正在使用一个预先存在的数据库,所以我(在一定程度上)我可以修改的内容是有限的。当我在数据库中查询一个动态对象(不是 .NET 4.0 的动态对象)时,我传入了我的 Id,我得到的是一个简单的对象,它可能有一些属性,这些属性仅供内部使用,还有一个属性是一个集合,其中包含我的动态对象的所有属性。因此,如果我的动态对象是针对具有 Name、DoB 和 Sex 的人,那么我的集合将包含三个对象,每个属性一个。这允许站点管理员在运行时添加新字段,并且网站将自动呈现它们,允许更新等。现在我的模型绑定当前可以用于此数据结构的显示和回发,对于集合中的每个对象,我渲染两条数据,属性的唯一 ID(目前是隐藏字段,Id 是 Guid)和属性的值。我的问题是安全方面。
如果我正在处理强类型对象,我可以创建自定义 ViewModel 并完成它,或者将 Bind() 属性添加到操作的签名中,但由于这些对象的属性是灵活的集合,我不知道如何处理它。操作级别的安全性很简单,我可以创建一个自定义的 Authorize 属性并查询数据库的权限,但我需要能够限制集合行为以根据用户权限显示和接受信息。例如,如果我要为 person 对象添加一个社会安全号码属性,我不希望它为某些人呈现到屏幕上。但是因为属性是可以在运行时改变的,所以权限也可以。
就我的想法而言,这就是我所处的位置......
因此,我需要一种方法来确定属性集合中的哪些对象可以呈现到屏幕或绑定到回发,具体取决于用户权限。对于显示对象,我认为我别无选择,只能以某种方式将权限包含在 ViewModel 对象中,并在用于属性集合中的对象类型的 DisplayTemplate 中查询这些权限。或者我可以编写某种自定义 ModelBinder,因为它用于调用 Html.Display() 和 Html.Editor() 并考虑过滤 ModelBinder 内的列表。
不过,我对回发也有类似的问题。当它被发回时,我有一组数据被传回,只有一个 Guid 和一个值。但是我需要确保用户没有将自己的字段注入到表单中,并且我还需要确保对于传递回操作的属性,用户具有足够的权限。理想情况下,我想将此检查集成到模型绑定中,并在可能的情况下重用从 MetaData 填充的一些信息,例如,这样它就可以简单地忽略传入的用户无权更改的数据,或者如果不这样做,请检查用户是否有权访问他们尝试在处理回发的操作开始时完成的 IsValid 检查中设置的所有属性。
然后是 MetaData 的动态构建,用于根据数据库中的信息为每个属性调用 Html.Display() 和 Html.Editor(),因为我没有物理属性是我可以装饰的类数据注释。
问题是,当涉及到覆盖 ModelBinders、ModelMetaDataProviders 或 ModelValidationProviders 之类的默认实现时,我不熟悉 MVC 的内部结构。
您能否就您能想到的实现我所描述的最佳方式提供一些建议,或者如果您知道涵盖此示例的其他文章,我非常希望看到它们,但我对 Google 的运气并不好到目前为止,关于这个特定主题。
编辑:有关我所做的全部详细信息,请参阅下面的答案
编辑:我让元数据提供程序工作。只需要实现我自己的类并从 ModelMetadataProvider 继承。
第一部分非常自我解释,首先使用 GetMetadataForType() 填充元数据,方法是传入与从中提取数据的列名称最匹配的 .NET 类型。(我的编辑器模板通过动态选择定义该数据的数据结构中定义的数据所在的列来帮助解决此问题)
使用起来有点奇怪,但就像我说的,它是一个预先存在的数据结构。
在 switch 语句之后是奇怪的地方。据我了解,在 MVC2 中,该GetMetadataForProperty()
方法不再将模型本身作为参数并使用 查找属性propertyName
,而是传入一个类型的表达式,该表达式Func<object>
指向 MVC 需要元数据的属性。这带来了一个问题,因为我需要根模型使用不同的属性来确定结构细节。我在这里找到了另一个解决方案,说您可以使用反射来获取模型,但它需要反射。不是我所希望的,但它有效。在我拥有模型之后,我将到目前为止的元数据和模型传递给一个创建的方法,然后我将从那里设置MVC 使用的对象AddSupplimentalMetadata()
的其余属性。DataAnnotationsModelMetadata
现在我只需要找出一种方法来根据用户权限动态选择渲染或不渲染某些属性。我想我可能需要做的是在将模型传递给视图之前过滤属性列表,使用 LINQ 或类似的东西。我不喜欢将业务逻辑放在 Display/EditorTemplate 中的想法。为了保存更改,我仍然需要查看验证系统,看看我是否可以使用该系统来验证用户尝试传递信息的属性。
asp.net-mvc - asp.net mvc中编辑器模板中复杂类型的模型元数据
我有一个包含 TestThing 类型的复杂属性的视图模型,该属性声明为:
我有一个针对这种类型的 EditorTemplate,我希望能够在其中访问每个子属性的元数据。例如,如果模板是一个字符串,我可以使用 访问提示文本@ViewData.ModelMetadata.Watermark
,但因为它是一个复杂类型,我不能使用这种方法。
有替代方案吗?
asp.net - asp.net mvc 3 Html.GetUnobtrusiveValidationAttributes 和嵌套模型
这是情况。我有一些包含嵌套复杂模型类型的 ViewModel。这是其中一个模型的片段(这不是一个完整的类):
以及 ContactModel 类的一个片段(不完整):
我的问题是我需要能够从嵌套模型类型 ContactModel 中获取验证属性以进行客户端验证。我在大多数视图中使用手动方法,因为我不使用 *For() 辅助方法。这是我所做的:
这就像一个冠军,并从模型中产生预期的验证属性,只有当视图的模型是应用了“验证”属性的模型时。 当具有“验证”属性的模型位于嵌套模型对象中时,这不起作用。我正在努力弄清楚如何获取此场景的验证属性。视图很复杂,我无法将其进一步分解为模型的多个视图,因此我需要它与嵌套模型一起使用。
我已经尝试了许多方法,但还没有深入了解它们以试图获得无污染的答案。我会说我已经尝试使用我的绑定前缀以及通过一些静态“ModelMetadata”类来钻入我的嵌套模型结构,但到目前为止还没有运气。任何帮助表示赞赏。
让我知道您还需要什么帮助。
我还阅读了很多 Brad Wilson 的博客文章以及他所在领域的其他人,但到目前为止还没有运气。
asp.net-mvc-3 - ASP.NET MVC 3 数据属性 - 以编程方式从控制器设置 UIHint
如果我有这样的ViewModel:
并使用EditorFor呈现表单字段:
它会渲染<input type="text">
. 凉爽的。
但在这种特殊情况下,我已经从不同的来源检索了电子邮件,我希望用这些数据预先填写表格,并显示一个标签而不是文本框(因为我不希望他们更改他们的电子邮件 -不要担心为什么)。
我知道我可以使用[UIHint]
,但我可以从控制器以编程方式执行此操作吗?
例如:
解决这个问题的最佳方法是什么?我应该完全使用单独的 ViewModel,这可能意味着将我的视图从强类型更改为存在dynamic
,或者我不应该使用EditorFor
,还是应该使用自定义编辑器模板?
建议/建议将不胜感激。
asp.net-mvc - 如何在 ASP.NET MVC 中提供我自己的 ICustomTypeDescriptor?
我正在为 ASP.NET MVC 3 开发一个小型库,该库应该提供更好的模型元数据可重用性以及从数据实体到自定义视图模型的轻松映射。为此,我需要能够为 ASP.NET MVC 的三个不同领域提供我自己的 ICustomTypeDescriptor 实现:
- 脚手架
- 验证
- 模型绑定
这似乎可以通过设置 System.Web.Mvc.ModelMetadataProviders.Current
为我自己的 CustomMetaDataProvider 来完成,但这还不足以涵盖上述所有三点。
问题是 System.Web.Mvc 中有几个类直接调用到 thisSystem.Web.TypeDescriptorHelper
中,这是不可扩展的,因为它看起来像这样:
我发现的唯一解决方案非常笨拙,需要从 System.Web.Mvc 子类化许多类型才能使其工作。我什至不得不完全重新实现CustomModelBinderDictionary
,只覆盖一两行代码。所以它可以工作,但它是一个非常混乱的 hack,并且可能会在我下次更新到新的 ASP.NET MVC 版本时中断。
所以这就是我想知道的:我错过了任何简单的方法吗?
额外的问题:如果不是并且您来自 MVC 团队,您是否可以考虑在 MVC 4 中创建一个适当的可扩展点;-)?
编辑:回答为什么我需要编写自己的 TypeDescriptor 的问题:这有几个原因: 1. 最重要的是:我需要解决https://forums.asp.net/t/1614439中描述的问题的方法.aspx/1 2. 另外,由于各种原因,我需要动态插入元数据。例如,我想编写自己的 Bind 属性,但 BindAttribute 是密封的。因此,当检测到我自己的绑定属性实现时,我不是从它派生,而是从 TypeDescriptor 动态发出匹配的 BindAttribute。
custom-attributes - 使用 CreateMetadata 自定义 ModelMetadata
当用户第一次从选择列表中选择一个值时,我们会显示一个带有 textPick one
和 value的默认选项-1
。
为了帮助解决这个问题,我们有一个自定义属性NotEqualAttribute
。当需要下拉列表时,我们必须使用这两个属性才能使其正常工作。
我们的虚拟机看起来像:
我们更喜欢使用这个:
另一个 StackOverflow 问题讨论了如何使不可为空的属性变为可选,除非该Required
属性被显式设置。
我尝试这样做,但很困惑如何将新属性添加到IEnumerable<Attribute>
集合和/或将其添加到ModelMetadata
元数据提供程序中:
c# - 实体框架 - 从实体获取表名
我正在使用带有代码优先方法的实体框架 4.1。我能够获取我的实体的存储模型类型和列名:
我需要的是获取实体映射到的真实表名。有不同的方法来指定(通过使用 Fluent-API .ToTable()、DataAnnotation [TableAttribute])。
有没有什么通用的方法来获取这些信息?
asp.net-mvc-3 - 如何从控制器获取 AdditionMetadata 属性?
在某个类中,比如说 A 类,我有一个属性(B 类):
稍后,在我的控制器中,我将这个类实例化并使其成为模型:
现在,稍后,我有一个 B 类的自定义编辑器模板(即部分视图),我知道我可以通过以下方式获取 AdditionalMetadata:ViewData.ModelMetadata.AdditionalValues["foo"];
但是:有没有办法从控制器更早地获取元数据属性?
c# - 检索模型元数据的 HtmlHelper 方法中的行为不一致
我正在追踪 MVC3 中的意外行为,这与它如何获取模型元数据有关。
我之前曾与我的一位开发人员讨论过使用相同的 EditorTemplate 处理在系统的两个不同区域收集的一些数据。除了 [Required] 属性外,数据字段几乎相同。在一个页面中,某些字段是必需的,而在另一页面中则不是。理论上,这可以通过使用在每个字段上具有公共属性的基本模型并继承这些模型、覆盖属性并添加额外的验证属性来实现。例如:
然后视图可以被强类型化为 BaseModel,并且在视图中调用 @Html.EditorFor(m=>m.MyLabel) 应该选择正确的属性,这取决于模型的实际实例是 BaseModel 还是 RequiredModel。
这就是理论。
事实上,如果您使用“旧的”HTML 帮助器,例如@Html.TextBox(“MyLabel”),它会很好地工作。这些调用 ModelMetadata.FromStringExpression(field),如果具体模型实例是RequiredModel,它会正确地从RequiredModel 获取元数据。较新的辅助方法调用 ModelMetadata.FromLambdaExpression(expression),它不能正确地从正确的具体实例中获取元数据。
这是MVC中的错误吗?故意行为?是否有解决方法或更好的方法来解决此问题?
这当然是一个简单的例子,我们正在处理的实际代码有大约 20 个字段,其中包含一些复杂的业务规则和交互,这在两个页面上都是相同的,除了需要哪些字段。
c# - ModelMetaData、自定义类属性和一个难以形容的问题
我想做的事情似乎很简单。
在我的 index.cshtml 中,我想显示WizardStepAttribute
值
因此,用户将在每个页面的顶部看到,Step 1: Enter User Information
我有一个名为WizardViewModel
. 这个 ViewModel 有一个属性是IList<IStepViewModel> Steps
每个“步骤”都实现了接口 IStepViewModel,它是一个空接口。
我有一个名为 Index.cshtml 的视图。此视图显示EditorFor()
当前步骤。
我有一个自定义 ModelBinder,它将视图绑定到IStepViewModel
基于WizardViewModel.CurrentStepIndex
属性实现的具体类的新实例
我创建了一个自定义属性WizardStepAttribute
。
我的每个 Steps 类都是这样定义的。
我有几个问题。
我的视图是强类型的,WizardViewModel
不是每个步骤。我不想为每个具体实现创建一个视图IStepViewModel
我以为我可以向接口添加一个属性,但是我必须在每个类中显式地实现它。(所以这并没有更好)
我想我可以在接口中使用反射来实现它,但是你不能在接口的方法中引用实例。