Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ms-access/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 如何注入自定义ModelMetadata属性并在Html帮助程序中使用它们_Asp.net Mvc_Asp.net Mvc 3_Metadata - Fatal编程技术网

Asp.net mvc 如何注入自定义ModelMetadata属性并在Html帮助程序中使用它们

Asp.net mvc 如何注入自定义ModelMetadata属性并在Html帮助程序中使用它们,asp.net-mvc,asp.net-mvc-3,metadata,Asp.net Mvc,Asp.net Mvc 3,Metadata,其思想(简化)是在字典中包含的ViewModel中具有用户可定义的属性。大致如下: public class MyViewModel { [Required] public string Name { get; set; } [DisplayName("User address")] public string Address { get; set; } // ... public IDictionary<string, string&

其思想(简化)是在字典中包含的ViewModel中具有用户可定义的属性。大致如下:

public class MyViewModel
{
    [Required]
    public string Name { get; set; }

    [DisplayName("User address")]
    public string Address { get; set; }

    // ...

    public IDictionary<string, string> MetaData { get; set; }
}
我还想使用这些附加属性:

Html.TextBox("PhoneNumber")
我的研究让我继承了
DataAnnotationsModelMetadataProvider
(因为它还需要支持标准属性的标准DataAnnotations属性),并试图找出要覆盖的内容,以便将其他属性作为其他ModelMetadata元素注入,但我有点被卡住了

我走对了吗?这里还有什么可以帮我的吗


感谢

另一种选择可能是构造一个类似于MVC 3中的ViewBag/ViewData的动态对象。您可以通过
Model.MetaData.Foo
访问一个对象,
Foo
实际上会映射到字典中的一个键

支持ViewBag对象的类型为;这个类是内部的并且是密封的,所以您必须对它进行自定义实现(除非有更好的选项我不知道)。快速浏览一下MVC 3源代码,可以得出以下结论:

internal sealed class DynamicViewDataDictionary : DynamicObject {
    private readonly Func<ViewDataDictionary> _viewDataThunk;

    public DynamicViewDataDictionary(Func<ViewDataDictionary> viewDataThunk) {
        _viewDataThunk = viewDataThunk;
    }

    private ViewDataDictionary ViewData {
        get {
            ViewDataDictionary viewData = _viewDataThunk();
            Debug.Assert(viewData != null);
            return viewData;
        }
    }

    // Implementing this function improves the debugging experience as it provides the debugger with the list of all
    // the properties currently defined on the object
    public override IEnumerable<string> GetDynamicMemberNames() {
        return ViewData.Keys;
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result) {
        result = ViewData[binder.Name];
        // since ViewDataDictionary always returns a result even if the key does not exist, always return true
        return true;
    }

    public override bool TrySetMember(SetMemberBinder binder, object value) {
        ViewData[binder.Name] = value;
        // you can always set a key in the dictionary so return true
        return true;
    }
}
内部密封类DynamicViewDataDictionary:DynamicObject{
私有只读函数_viewDataThunk;
公共动态视图数据字典(Func viewDataThunk){
_viewDataThunk=viewDataThunk;
}
私有ViewDataDictionary ViewData{
得到{
ViewDataDictionary viewData=\u viewDataThunk();
Assert(viewData!=null);
返回视图数据;
}
}
//实现此函数可以改善调试体验,因为它为调试器提供了所有
//对象上当前定义的属性
公共重写IEnumerable GetDynamicMemberNames(){
返回ViewData.key;
}
公共重写bool TryGetMember(GetMemberBinder绑定器,输出对象结果){
结果=视图数据[binder.Name];
//由于ViewDataDictionary始终返回结果,即使键不存在,也始终返回true
返回true;
}
public override bool TrySetMember(SetMemberBinder绑定器,对象值){
ViewData[binder.Name]=值;
//您始终可以在字典中设置一个键,以便返回true
返回true;
}
}

与修改ModelMetadataProvider相比,此解决方案的一个可能优势是,您不必花费时间为您的场景构建所有自定义组件—默认的提供程序应该足够了。

您确定要有一个字典,可以在其中抛出任何内容并基于此创建视图吗?在开始之前,我会重新思考这个问题。我想说的是,这样的解决方案往往以复杂的黑客行为而告终,变得无法维护。更不用说你将如何使用它执行绑定了——它可能需要另一个黑客程序。好吧,我同意你的观点,在一个定制的单个MVC项目中使用它将是维护的噩梦。问题是,这是打算用于我们定制的CMS,其中一个要求是具备上述功能。使用自定义模型活页夹时,绑定部件应该不会有问题。谢谢您的回答。我来看看在我们的例子中是否有类似的东西是可行的。为什么_viewDataThunk被定义为Func而不是ViewDataDictionary。这样做有什么好处?@JRoppert这是一个表演技巧。通过将对象包装在
Func
中,它可以有效地充当惰性加载程序。这样,所包含的
ViewDataDictionary
在被使用之前不会执行。
internal sealed class DynamicViewDataDictionary : DynamicObject {
    private readonly Func<ViewDataDictionary> _viewDataThunk;

    public DynamicViewDataDictionary(Func<ViewDataDictionary> viewDataThunk) {
        _viewDataThunk = viewDataThunk;
    }

    private ViewDataDictionary ViewData {
        get {
            ViewDataDictionary viewData = _viewDataThunk();
            Debug.Assert(viewData != null);
            return viewData;
        }
    }

    // Implementing this function improves the debugging experience as it provides the debugger with the list of all
    // the properties currently defined on the object
    public override IEnumerable<string> GetDynamicMemberNames() {
        return ViewData.Keys;
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result) {
        result = ViewData[binder.Name];
        // since ViewDataDictionary always returns a result even if the key does not exist, always return true
        return true;
    }

    public override bool TrySetMember(SetMemberBinder binder, object value) {
        ViewData[binder.Name] = value;
        // you can always set a key in the dictionary so return true
        return true;
    }
}