ASP.NET MVC Editor-Templates/UIHint with parameters
过去,我通过应用以下数据注释来像这样一直使用Editor-Templates:
1 | [UIHint("SomeTemplate")] |
ViewModel:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public class MicroViewModel { public IEnumerable<LabMicro> Micros { get; set; } [UIHint("DateTime")] public DateTime Date { get; set; } public int CaseNo { get; set; } [UIHint("SampleTypes")] public int LabSampleTypeID { get; set; } [UIHint("SampleDetails")] public int LabSampleDetailID { get; set; } } |
如果我想使用 相对于常规日期选择器控件,它可以按以下方式实现。
示例:
1 2 3 4 5 6 7 8 9 10 11 12 |
@model DateTime? @Html.TextBox("", String.Format("{0:yyyy-MM-dd}", Model.HasValue ? Model : DateTime.Today), new { @class ="dp", style="width:100px" }) <script type="text/javascript"> $(document).ready(function () { $(".dp").datepicker({ changeMonth: true, changeYear: true, dateFormat: 'yy-mm-dd' }); }); |
对于我的ID字段,我想使用jQuery 自动完成组件。
问题:
如何将其他参数传递给LabSampleTypeID和LabSampleDetailID的UIHint部分视图? (因为我想拥有一个自动完成的Editor-Template,该模板将使用URL和属性名作为示例)
我认为我的自动完成的Editor-Template / Partial应该如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
$(".auto").autocomplete({ source: function(request, response) { $.ajax({ url: '[#URL_TO_USE]', dataType:"json", data: { filter: request.term }, success: function(data) { response($.map(eval(data), function(item) { return { label: item.[#PROPERTY_TO_USE] } })); } }) } }); |
- 仅供参考,您不需要UIHint作为DateTime。 它已经是一个DateTime,因此如果存在,它将已经使用DateTime.cshtml模板。 对于与模板名称类型不同的其他类型,您确实需要它。
您可以使用AdditionalMetadata属性:
1 2 3 |
[UIHint("DateTime")] [AdditionalMetadata("foo","bar")] public DateTime Date { get; set; } |
并在模板中:
1 | @ViewData.ModelMetadata.AdditionalValues["foo"] |
因此,如果您想传递网址:
1 2 3 4 5 |
[UIHint("DateTime")] [AdditionalMetadata("controller","somecontroller")] [AdditionalMetadata("action","someaction")] [AdditionalMetadata("property","someproperty")] public DateTime Date { get; set; } |
并在您的模板中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
@{ var values = ViewData.ModelMetadata.AdditionalValues; } <script type="text/javascript"> $('.auto').autocomplete({ source: function (request, response) { $.ajax({ url: '@Url.Action((string)values["action"], (string)values["controller"])', dataType:"json", data: { filter: request.term }, success: function (data) { response( $.map(eval(data), function (item) { return { label: item['@values["property"]'] } }) ); } }); } }); |
- UHint类具有带有其他params object[] controlParameters的构造函数。 这样做的目的是什么?
- UHint controlParameters似乎对此更适合
您可以使用不带AdditionalMetadata属性的UHint,但是需要一些其他代码
1 2 |
[UIHint("DateTime", null,"key1","value1","key2","value2")] public DateTime Date { get; set; } |
覆盖CreateMetadata:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
public class CustomMetadataProvider : DataAnnotationsModelMetadataProvider { public const string UiHintControlParameters ="UiHintControlParameters"; protected override ModelMetadata CreateMetadata( IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName) { ModelMetadata metadata = base.CreateMetadata( attributes, containerType, modelAccessor, modelType, propertyName); IEnumerable<UIHintAttribute> uiHintAttributes = attributes.OfType<UIHintAttribute>(); UIHintAttribute uiHintAttribute = uiHintAttributes.FirstOrDefault(a => string.Equals(a.PresentationLayer,"MVC", StringComparison.OrdinalIgnoreCase)) ?? uiHintAttributes.FirstOrDefault(a => String.IsNullOrEmpty(a.PresentationLayer)); if (uiHintAttribute != null) { metadata.AdditionalValues.Add(UiHintControlParameters, uiHintAttribute.ControlParameters); } return metadata; } |
注册CustomMetadataProvider:
1 2 3 4 |
public static void Application_Start() { ModelMetadataProviders.Current = new CustomMetadataProvider(); } |
并在您的模板中:
1 2 3 4 |
@{ IDictionary<string, object> values = (IDictionary<string, object>) ViewData.ModelMetadata.AdditionalValues[CustomMetadataProvider.UiHintControlParameters]; } |
- 嗨,我尝试过您的代码,但是在尝试注册自定义提供程序时,它说它无法将目标类型转换为System.Web.Mvc.ModelMetadataProvider,有什么想法吗?
- 就像您的示例一样,我们创建的覆盖范围是从DataAnnotationsModelMetadataProvider扩展而来的,但是ModelMetadataProviders.Current期望使用ModelMetadataProvider。
- Ciaran,请确保从System.Web.Mvc命名空间而不是System.Web.Http.Metadata.Providers覆盖DataAnnotationsModelMetadataProvider