我正在嘗試創建自定義ModelMetadataProvider
以爲JQuery UI自動填充小部件提供不顯眼的屬性。ModelMetadata TemplateHint始終爲空
我有一個看起來像這樣的自定義屬性:
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public sealed class AutocompleteAttribute : Attribute, IMetadataAware
{
public void OnMetadataCreated(ModelMetadata metadata)
{
metadata.TemplateHint = "Autocomplete";
}
}
和看起來像這樣的編輯模板:
@{
var attributes = new RouteValueDictionary
{
{"class", "text-box single-line"},
{"autocomplete", "off"},
{"data-autocomplete-url", "UrlPlaceholder" },
};
}
@Html.TextBox("", ViewContext.ViewData.TemplateInfo.FormattedModelValue, attributes)
我有一個視圖模型與包括string
類型的屬性AutocompleteAttribute
是這樣的:
public class MyViewModel
{
[Autocomplete]
public string MyProperty { get; set; }
}
當我用th在我看來viewModel我檢查生成的HTML,我得到一個<input>
標記,它具有這樣的屬性:data-autocomplete-url="UrlPlaceholder"
。
我想接下來做的是能夠指定在我看來,使用我的ViewModel這樣的網址:
@model MyViewModel
@{ ViewBag.Title = "Create item"; }
@Html.AutoCompleteUrlFor(p => p.MyProperty, UrlHelper.GenerateUrl(null, "Autocomplete", "Home", null, Html.RouteCollection, Html.ViewContext.RequestContext, true))
// Other stuff here...
<div>
@Html.ActionLink("Back to List", "Index")
</div>
我AutoCompleteForUrl
幫手只是保存生成的URL在字典中,使用屬性名稱作爲一個關鍵。
接下來我創建了一個自定義ModelMetadataProvider
並在global.asax中使用這行代碼ModelMetadataProviders.Current = new CustomModelMetadataProvider();
進行了註冊。
我想要做的就是將由JQuery UI Autocomplete小部件使用的URL插入metadata.AdditionalValues
字典中,以供Autocomplete編輯器模板使用。
我定製ModelMetadataProvider
看起來是這樣的:
public class CustomModelMetadataProvider : DataAnnotationsModelMetadataProvider
{
protected override ModelMetadata CreateMetadata(IEnumerable<System.Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName)
{
var metadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
if (metadata.TemplateHint == "Autocomplete")
{
string url;
if(htmlHelpers.AutocompleteUrls.TryGetValue(metadata.propertyName, out url)
{
metadata.AdditionalValues["AutocompleteUrl"] = url;
}
}
return metadata;
}
}
和我更新的編輯模板看起來是這樣的:
@{
object url;
if (!ViewContext.ViewData.ModelMetadata.TryGetValue("AutocompleteUrl", out url))
{
url = "";
}
var attributes = new RouteValueDictionary
{
{"class", "text-box single-line"},
{"autocomplete", "off"},
{"data-autocomplete-url", (string)url },
};
}
@Html.TextBox("", ViewContext.ViewData.TemplateInfo.FormattedModelValue, attributes)
的問題是,在TemplateHint
財產總是不等於「自動完成」我的自定義模型元數據提供程序,所以我的邏輯來生成URL永遠不會被調用。我會認爲在這一點上,TemplateHint
屬性將被設置爲我所稱的DataAnnotationsModelMetadataProvider
的CreateMetadata
的基本實現。
這是我可以證實:
- 的
CustomModelMetadataProvider
正確註冊,因爲它包含了獲取調用其他代碼。 - 由於生成的Html包含一個名爲
"data-autocomplete-url"
的屬性,正確的編輯器模板正在被拾取。 - 如果我在自動填充模板中放置了斷點,Visual Studio將轉到調試器。
所以,任何人都可以爲我擺脫這個燈嗎?我對ModelMetadataProvider
系統有什麼誤解?