【问题标题】:ASP.NET MVC Editor-Templates/UIHint with parametersASP.NET MVC Editor-Templates/UIHint 带参数
【发布时间】:2023-03-11 05:01:01
【问题描述】:

过去我一直在使用 Editor-Templates,方法是应用以下数据注释:

[UIHint("SomeTemplate")]
 

视图模型:

 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; }
 }

如果我想使用特定的日期选择器控件而不是常规控件,可以按如下方式实现。

示例:

@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'    
        });    
    });      
</script>  

对于我的 ID 字段,我想使用 jQuery 自动完成组件。

问题:

对于LabSampleTypeIDLabSampleDetailID,我将如何将其他参数传递给UIHint 部分视图? (因为我希望有一个自动完成的编辑器模板,例如,它将采用 URL 和属性名称)

我认为我的自动完成编辑器模板/部分应该是这样的:

$(".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]
                    }
                }));
            }
        })
    }
});

【问题讨论】:

  • 仅供参考,您不需要 DateTime 的 UIHint。它已经是一个DateTime,所以它已经使用了一个DateTime.cshtml 模板(如果它存在的话)。对于与模板名称不同类型的其他名称,您确实需要它。

标签: asp.net-mvc asp.net-mvc-3 asp.net-mvc-4


【解决方案1】:

您可以使用AdditionalMetadata 属性:

[UIHint("DateTime")]
[AdditionalMetadata("foo", "bar")]
public DateTime Date { get; set; }

在模板中:

@ViewData.ModelMetadata.AdditionalValues["foo"]

所以如果你想传递一个 url:

[UIHint("DateTime")]
[AdditionalMetadata("controller", "somecontroller")]
[AdditionalMetadata("action", "someaction")]
[AdditionalMetadata("property", "someproperty")]
public DateTime Date { get; set; }

在您的模板中:

@{
    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"]']
                        }
                    })
                );
            }
        });
    }                    
});
</script>

【讨论】:

  • UHint 类具有带有附加 params object[] controlParameters 的构造函数。这样做的目的是什么?
  • UHint controlParameters 似乎更适合这个
【解决方案2】:

您可以使用不带 AdditionalMetadata 属性的 UHint,但需要一些额外的代码

[UIHint("DateTime", null, "key1", "value1", "key2", "value2")]
public DateTime Date { get; set; }

覆盖 CreateMetadata:

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:

    public static void Application_Start()
    {
        ModelMetadataProviders.Current = new CustomMetadataProvider();
    }

在你的模板中:

    @{
        IDictionary<string, object> values = (IDictionary<string, object>)
ViewData.ModelMetadata.AdditionalValues[CustomMetadataProvider.UiHintControlParameters];
    }

【讨论】:

  • 您好,我尝试了您的代码,但在尝试注册自定义提供程序时,它说它无法将目标类型转换为 System.Web.Mvc.ModelMetadataProvider,有什么想法吗?
  • 我们创建的覆盖是从“DataAnnotationsModelMetadataProvider”扩展而来,就像您的示例一样,但“ModelMetadataProviders.Current”需要一个 ModelMetadataProvider。
  • Ciaran,确保你从 System.Web.Mvc 命名空间覆盖 DataAnnotationsModelMetadataProvider,而不是 System.Web.Http.Metadata.Providers
猜你喜欢
  • 1970-01-01
  • 2021-06-13
  • 1970-01-01
  • 2011-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-20
相关资源
最近更新 更多