ModelMetadataProvider
JQuery UI Autocomplete ウィジェットに目立たない属性を提供するカスタムを作成しようとしています。
次のようなカスタム属性があります。
[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
ようなタイプのプロパティを持つviewModelがあります。
public class MyViewModel
{
[Autocomplete]
public string MyProperty { get; set; }
}
ビューでこのviewModelを使用すると、生成されたhtmlをチェックすると、次<input>
のような属性を持つタグが取得されますdata-autocomplete-url="UrlPlaceholder"
。
次にやりたいことは、viewModel を使用するビューで次のように URL を指定できるようにすることです。
@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 オートコンプリート ウィジェットで使用される URL をmetadata.AdditionalValues
ディクショナリに挿入して、オートコンプリート エディター テンプレートで使用できるようにすることです。
私のカスタム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
プロパティが設定されると思っていたでしょう。CreateMetadata
DataAnnotationsModelMetadataProvider
確認できることは次のとおりです。
CustomModelMetadataProvider
は、呼び出される他のコードが含まれているため、正しく登録されています。- 生成される Html に という属性が含まれているため、正しいエディター テンプレートが取得されます
"data-autocomplete-url"
。 - オートコンプリート テンプレートにブレークポイントを配置すると、Visual Studio はデバッガーに移動します。
だから、誰かが私のためにこれに光を当てることができますか? ModelMetadataProvider
システムについて誤解していることは何ですか?