Add default `Display*()` templates
- first get old code in correct spot - then get default templates working in new world - usual things: `[NotNull]`, `var`, internal -> public - provide a `HtmlHelper.GenerateOption()` static method - pass an `ViewDataDictionary<object>` instance to `TemplateRenderer` constructor - run default templates synchronously with an IHtmlHelper<object> - copy over resources - add Microsoft.Data.Entity reference for EntityState type - use default templates in MVC sample - remove most on-disk overrides of the default templates
This commit is contained in:
parent
05a2319d84
commit
b8731621df
|
|
@ -28,11 +28,7 @@
|
||||||
<Content Include="Views\Home\ValidationSummary.cshtml" />
|
<Content Include="Views\Home\ValidationSummary.cshtml" />
|
||||||
<Content Include="Views\Link\Details.cshtml" />
|
<Content Include="Views\Link\Details.cshtml" />
|
||||||
<Content Include="Views\Shared\Components\Tags\Default.cshtml" />
|
<Content Include="Views\Shared\Components\Tags\Default.cshtml" />
|
||||||
<Content Include="Views\Shared\DisplayTemplates\Boolean.cshtml" />
|
|
||||||
<Content Include="Views\Shared\DisplayTemplates\Decimal.cshtml" />
|
<Content Include="Views\Shared\DisplayTemplates\Decimal.cshtml" />
|
||||||
<Content Include="Views\Shared\DisplayTemplates\Int32.cshtml" />
|
|
||||||
<Content Include="Views\Shared\DisplayTemplates\String.cshtml" />
|
|
||||||
<Content Include="Views\Shared\DisplayTemplates\User.cshtml" />
|
|
||||||
<Content Include="Views\Shared\HelloWorldPartial.cshtml" />
|
<Content Include="Views\Shared\HelloWorldPartial.cshtml" />
|
||||||
<Content Include="Views\Shared\MyView.cshtml" />
|
<Content Include="Views\Shared\MyView.cshtml" />
|
||||||
<Content Include="Views\Shared\_Layout.cshtml" />
|
<Content Include="Views\Shared\_Layout.cshtml" />
|
||||||
|
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
@using System.Globalization
|
|
||||||
|
|
||||||
@functions {
|
|
||||||
private bool? Value {
|
|
||||||
get {
|
|
||||||
if (ViewData.Model == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return Convert.ToBoolean(ViewData.Model, CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@if (ViewData.ModelMetadata.IsNullableValueType) {
|
|
||||||
<select class="list-box tri-state" disabled="disabled">
|
|
||||||
<option value=""@(Value.HasValue ? "" : "selected='selected'")>Not Set</option>
|
|
||||||
<option value="true"@(Value.HasValue && Value.Value ? "selected='selected'" : "")>True</option>
|
|
||||||
<option value="false"@(Value.HasValue && !Value.Value ? "selected='selected'" : "")>False</option>
|
|
||||||
</select>
|
|
||||||
} else {
|
|
||||||
<input type="checkbox" class="check-box" disabled="disabled" @(Value.HasValue && Value.Value ? "checked='checked'" : "") />
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
@using System.Globalization
|
@* Override default Decimal template to display value in bold. *@
|
||||||
|
@using System.Globalization
|
||||||
|
|
||||||
@functions {
|
@functions {
|
||||||
private object FormattedValue {
|
private object FormattedValue {
|
||||||
|
|
@ -10,4 +11,4 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@Html.Encode(FormattedValue)
|
<b>@Html.Encode(FormattedValue)</b>
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
@ViewData.TemplateInfo.FormattedModelValue
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
@Html.Encode(ViewData.TemplateInfo.FormattedModelValue)
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
@using System.Linq
|
|
||||||
|
|
||||||
<p>This is the DisplayForModel output. Once default templates are implemented this should go away.</p>
|
|
||||||
<p><strong>User Name: </strong>@ViewData.Model.Name</p>
|
|
||||||
<p><strong>User Model Metadata Property Count: </strong>@ViewData.ModelMetadata.Properties.Count()</p>
|
|
||||||
|
|
@ -85,7 +85,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div style="float: left; border: 5px solid blue; padding-right: 10px;">
|
<div style="float: left; border: 5px solid blue; margin: 5px; padding: 7px;">
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
|
|
@ -145,15 +145,11 @@
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
<div style="float: left; border: 5px solid red; margin: 5px;">
|
||||||
<div style="float: right; border: 5px solid red;">
|
|
||||||
@await Component.InvokeAsync("Tags", 15)
|
@await Component.InvokeAsync("Tags", 15)
|
||||||
<p style="padding: 0px 10px;">'@ViewBag.Title' should match page heading (still)</p>
|
<p style="padding: 0px 10px;">'@ViewBag.Title' should match page heading (still)</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div style="float: left; border: thick solid lightskyblue; margin: 5px; padding: 7px;">
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div style="float: left; border: thick solid lightskyblue; margin-bottom: 10px; margin-top: -180px; padding-right: 10px">
|
|
||||||
@using (Html.BeginForm(controllerName: "Home", actionName: "Hello", method: FormMethod.Post))
|
@using (Html.BeginForm(controllerName: "Home", actionName: "Hello", method: FormMethod.Post))
|
||||||
{
|
{
|
||||||
@Html.HiddenFor(m => m.Age)
|
@Html.HiddenFor(m => m.Age)
|
||||||
|
|
@ -273,10 +269,7 @@
|
||||||
</table>
|
</table>
|
||||||
@{ Html.EndForm(); }
|
@{ Html.EndForm(); }
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div style="float: left; border: 5px solid lightgreen; margin: 5px; padding: 7px;">
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div style="float: left; border: 5px solid green;">
|
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
|
|
@ -328,7 +321,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div style="float: left; border: 5px solid green; margin-left: 10px; margin-bottom: 10px; ">
|
<div style="float: left; border: 5px dashed green; margin: 5px; padding: 7px;">
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
|
|
@ -381,7 +374,7 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="float: left; border: 5px solid green;">
|
<div style="float: left; border: 5px solid darkgreen; margin: 5px; padding: 7px;">
|
||||||
@Html.DisplayForModel()
|
@Html.DisplayForModel()
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,7 @@
|
||||||
<Compile Include="Rendering\HtmlHelperValidationExtensions.cs" />
|
<Compile Include="Rendering\HtmlHelperValidationExtensions.cs" />
|
||||||
<Compile Include="Rendering\HtmlHelperValueExtensions.cs" />
|
<Compile Include="Rendering\HtmlHelperValueExtensions.cs" />
|
||||||
<Compile Include="Rendering\HtmlString.cs" />
|
<Compile Include="Rendering\HtmlString.cs" />
|
||||||
|
<Compile Include="Rendering\Html\DefaultDisplayTemplates.cs" />
|
||||||
<Compile Include="Rendering\Html\HtmlHelper.cs" />
|
<Compile Include="Rendering\Html\HtmlHelper.cs" />
|
||||||
<Compile Include="Rendering\Html\HtmlHelperOfT.cs" />
|
<Compile Include="Rendering\Html\HtmlHelperOfT.cs" />
|
||||||
<Compile Include="Rendering\Html\InputType.cs" />
|
<Compile Include="Rendering\Html\InputType.cs" />
|
||||||
|
|
|
||||||
|
|
@ -362,6 +362,54 @@ namespace Microsoft.AspNet.Mvc.Core
|
||||||
return string.Format(CultureInfo.CurrentCulture, GetString("Common_ValueNotValidForProperty"), p0);
|
return string.Format(CultureInfo.CurrentCulture, GetString("Common_ValueNotValidForProperty"), p0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// False
|
||||||
|
/// </summary>
|
||||||
|
internal static string Common_TriState_False
|
||||||
|
{
|
||||||
|
get { return GetString("Common_TriState_False"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// False
|
||||||
|
/// </summary>
|
||||||
|
internal static string FormatCommon_TriState_False()
|
||||||
|
{
|
||||||
|
return GetString("Common_TriState_False");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Not Set
|
||||||
|
/// </summary>
|
||||||
|
internal static string Common_TriState_NotSet
|
||||||
|
{
|
||||||
|
get { return GetString("Common_TriState_NotSet"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Not Set
|
||||||
|
/// </summary>
|
||||||
|
internal static string FormatCommon_TriState_NotSet()
|
||||||
|
{
|
||||||
|
return GetString("Common_TriState_NotSet");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// True
|
||||||
|
/// </summary>
|
||||||
|
internal static string Common_TriState_True
|
||||||
|
{
|
||||||
|
get { return GetString("Common_TriState_True"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// True
|
||||||
|
/// </summary>
|
||||||
|
internal static string FormatCommon_TriState_True()
|
||||||
|
{
|
||||||
|
return GetString("Common_TriState_True");
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ViewData value must not be null.
|
/// ViewData value must not be null.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -474,6 +522,22 @@ namespace Microsoft.AspNet.Mvc.Core
|
||||||
return string.Format(CultureInfo.CurrentCulture, GetString("HtmlHelper_WrongSelectDataType"), p0, p1, p2);
|
return string.Format(CultureInfo.CurrentCulture, GetString("HtmlHelper_WrongSelectDataType"), p0, p1, p2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The '{0}' template was used with an object of type '{1}', which does not implement '{2}'.
|
||||||
|
/// </summary>
|
||||||
|
internal static string Templates_TypeMustImplementIEnumerable
|
||||||
|
{
|
||||||
|
get { return GetString("Templates_TypeMustImplementIEnumerable"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The '{0}' template was used with an object of type '{1}', which does not implement '{2}'.
|
||||||
|
/// </summary>
|
||||||
|
internal static string FormatTemplates_TypeMustImplementIEnumerable(object p0, object p1, object p2)
|
||||||
|
{
|
||||||
|
return string.Format(CultureInfo.CurrentCulture, GetString("Templates_TypeMustImplementIEnumerable"), p0, p1, p2);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions.
|
/// Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,289 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Microsoft.AspNet.DependencyInjection;
|
||||||
|
using Microsoft.AspNet.Mvc.Core;
|
||||||
|
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Mvc.Rendering
|
||||||
|
{
|
||||||
|
public static class DefaultDisplayTemplates
|
||||||
|
{
|
||||||
|
public static string BooleanTemplate(IHtmlHelper<object> html)
|
||||||
|
{
|
||||||
|
bool? value = null;
|
||||||
|
if (html.ViewData.Model != null)
|
||||||
|
{
|
||||||
|
value = Convert.ToBoolean(html.ViewData.Model, CultureInfo.InvariantCulture);
|
||||||
|
}
|
||||||
|
|
||||||
|
return html.ViewData.ModelMetadata.IsNullableValueType ?
|
||||||
|
BooleanTemplateDropDownList(html, value) :
|
||||||
|
BooleanTemplateCheckbox(value ?? false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string BooleanTemplateCheckbox(bool value)
|
||||||
|
{
|
||||||
|
var inputTag = new TagBuilder("input");
|
||||||
|
inputTag.AddCssClass("check-box");
|
||||||
|
inputTag.Attributes["disabled"] = "disabled";
|
||||||
|
inputTag.Attributes["type"] = "checkbox";
|
||||||
|
if (value)
|
||||||
|
{
|
||||||
|
inputTag.Attributes["checked"] = "checked";
|
||||||
|
}
|
||||||
|
|
||||||
|
return inputTag.ToString(TagRenderMode.SelfClosing);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string BooleanTemplateDropDownList(IHtmlHelper<object> html, bool? value)
|
||||||
|
{
|
||||||
|
var selectTag = new TagBuilder("select");
|
||||||
|
selectTag.AddCssClass("list-box");
|
||||||
|
selectTag.AddCssClass("tri-state");
|
||||||
|
selectTag.Attributes["disabled"] = "disabled";
|
||||||
|
|
||||||
|
var builder = new StringBuilder();
|
||||||
|
builder.Append(selectTag.ToString(TagRenderMode.StartTag));
|
||||||
|
|
||||||
|
foreach (var item in TriStateValues(value))
|
||||||
|
{
|
||||||
|
var encodedText = html.Encode(item.Text);
|
||||||
|
var option = HtmlHelper.GenerateOption(item, encodedText);
|
||||||
|
builder.Append(option);
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.Append(selectTag.ToString(TagRenderMode.EndTag));
|
||||||
|
return builder.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Will soon need to be shared with the default editor templates implementations.
|
||||||
|
internal static List<SelectListItem> TriStateValues(bool? value)
|
||||||
|
{
|
||||||
|
return new List<SelectListItem>
|
||||||
|
{
|
||||||
|
new SelectListItem
|
||||||
|
{
|
||||||
|
Text = Resources.Common_TriState_NotSet,
|
||||||
|
Value = string.Empty,
|
||||||
|
Selected = !value.HasValue
|
||||||
|
},
|
||||||
|
new SelectListItem
|
||||||
|
{
|
||||||
|
Text = Resources.Common_TriState_True,
|
||||||
|
Value = "true",
|
||||||
|
Selected = (value == true),
|
||||||
|
},
|
||||||
|
new SelectListItem
|
||||||
|
{
|
||||||
|
Text = Resources.Common_TriState_False,
|
||||||
|
Value = "false",
|
||||||
|
Selected = (value == false),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string CollectionTemplate(IHtmlHelper<object> html)
|
||||||
|
{
|
||||||
|
var model = html.ViewData.ModelMetadata.Model;
|
||||||
|
if (model == null)
|
||||||
|
{
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
var collection = model as IEnumerable;
|
||||||
|
if (collection == null)
|
||||||
|
{
|
||||||
|
// Only way we could reach here is if user passed templateName: "Collection" to a Display() overload.
|
||||||
|
throw new InvalidOperationException(Resources.FormatTemplates_TypeMustImplementIEnumerable(
|
||||||
|
"Collection", model.GetType().FullName, typeof(IEnumerable).FullName));
|
||||||
|
}
|
||||||
|
|
||||||
|
var typeInCollection = typeof(string);
|
||||||
|
var genericEnumerableType = collection.GetType().ExtractGenericInterface(typeof(IEnumerable<>));
|
||||||
|
if (genericEnumerableType != null)
|
||||||
|
{
|
||||||
|
typeInCollection = genericEnumerableType.GetGenericArguments()[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
var typeInCollectionIsNullableValueType = typeInCollection.IsNullableValueType();
|
||||||
|
|
||||||
|
var oldPrefix = html.ViewData.TemplateInfo.HtmlFieldPrefix;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
html.ViewData.TemplateInfo.HtmlFieldPrefix = string.Empty;
|
||||||
|
|
||||||
|
var fieldNameBase = oldPrefix;
|
||||||
|
var result = new StringBuilder();
|
||||||
|
|
||||||
|
var serviceProvider = html.ViewContext.HttpContext.RequestServices;
|
||||||
|
var metadataProvider = serviceProvider.GetService<IModelMetadataProvider>();
|
||||||
|
var viewEngine = serviceProvider.GetService<IViewEngine>();
|
||||||
|
|
||||||
|
var index = 0;
|
||||||
|
foreach (var item in collection)
|
||||||
|
{
|
||||||
|
var itemType = typeInCollection;
|
||||||
|
if (item != null && !typeInCollectionIsNullableValueType)
|
||||||
|
{
|
||||||
|
itemType = item.GetType();
|
||||||
|
}
|
||||||
|
|
||||||
|
var metadata = metadataProvider.GetMetadataForType(() => item, itemType);
|
||||||
|
var fieldName = string.Format(CultureInfo.InvariantCulture, "{0}[{1}]", fieldNameBase, index++);
|
||||||
|
|
||||||
|
var templateBuilder = new TemplateBuilder(
|
||||||
|
viewEngine,
|
||||||
|
html.ViewContext,
|
||||||
|
html.ViewData,
|
||||||
|
metadata,
|
||||||
|
htmlFieldName: fieldName,
|
||||||
|
templateName: null,
|
||||||
|
readOnly: true,
|
||||||
|
additionalViewData: null);
|
||||||
|
|
||||||
|
var output = templateBuilder.Build();
|
||||||
|
result.Append(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.ToString();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
html.ViewData.TemplateInfo.HtmlFieldPrefix = oldPrefix;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string DecimalTemplate(IHtmlHelper<object> html)
|
||||||
|
{
|
||||||
|
if (html.ViewData.TemplateInfo.FormattedModelValue == html.ViewData.ModelMetadata.Model)
|
||||||
|
{
|
||||||
|
html.ViewData.TemplateInfo.FormattedModelValue =
|
||||||
|
string.Format(CultureInfo.CurrentCulture, "{0:0.00}", html.ViewData.ModelMetadata.Model);
|
||||||
|
}
|
||||||
|
|
||||||
|
return StringTemplate(html);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string EmailAddressTemplate(IHtmlHelper<object> html)
|
||||||
|
{
|
||||||
|
var uriString = "mailto:" + ((html.ViewData.Model == null) ? string.Empty : html.ViewData.Model.ToString());
|
||||||
|
var linkedText = (html.ViewData.TemplateInfo.FormattedModelValue == null) ?
|
||||||
|
string.Empty :
|
||||||
|
html.ViewData.TemplateInfo.FormattedModelValue.ToString();
|
||||||
|
|
||||||
|
return HyperlinkTemplate(uriString, linkedText);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string HiddenInputTemplate(IHtmlHelper<object> html)
|
||||||
|
{
|
||||||
|
// TODO: add ModelMetadata.HideSurroundingHtml and use here (return string.Empty)
|
||||||
|
return StringTemplate(html);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string HtmlTemplate(IHtmlHelper<object> html)
|
||||||
|
{
|
||||||
|
return html.ViewData.TemplateInfo.FormattedModelValue.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string ObjectTemplate(IHtmlHelper<object> html)
|
||||||
|
{
|
||||||
|
var viewData = html.ViewData;
|
||||||
|
var templateInfo = viewData.TemplateInfo;
|
||||||
|
var modelMetadata = viewData.ModelMetadata;
|
||||||
|
var builder = new StringBuilder();
|
||||||
|
|
||||||
|
if (modelMetadata.Model == null)
|
||||||
|
{
|
||||||
|
return modelMetadata.NullDisplayText;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (templateInfo.TemplateDepth > 1)
|
||||||
|
{
|
||||||
|
// TODO: add ModelMetadata.SimpleDisplayText and use here (return SimpleDisplayText)
|
||||||
|
return modelMetadata.Model.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
var serviceProvider = html.ViewContext.HttpContext.RequestServices;
|
||||||
|
var viewEngine = serviceProvider.GetService<IViewEngine>();
|
||||||
|
|
||||||
|
foreach (var propertyMetadata in modelMetadata.Properties.Where(pm => ShouldShow(pm, templateInfo)))
|
||||||
|
{
|
||||||
|
var divTag = new TagBuilder("div");
|
||||||
|
|
||||||
|
// TODO: add ModelMetadata.HideSurroundingHtml and use here (skip this block)
|
||||||
|
{
|
||||||
|
var label = propertyMetadata.GetDisplayName();
|
||||||
|
if (!string.IsNullOrEmpty(label))
|
||||||
|
{
|
||||||
|
divTag.SetInnerText(label);
|
||||||
|
divTag.AddCssClass("display-label");
|
||||||
|
builder.AppendLine(divTag.ToString(TagRenderMode.Normal));
|
||||||
|
|
||||||
|
// Reset divTag for reuse.
|
||||||
|
divTag.Attributes.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
divTag.AddCssClass("display-field");
|
||||||
|
builder.Append(divTag.ToString(TagRenderMode.StartTag));
|
||||||
|
}
|
||||||
|
|
||||||
|
var templateBuilder = new TemplateBuilder(
|
||||||
|
viewEngine,
|
||||||
|
html.ViewContext,
|
||||||
|
html.ViewData,
|
||||||
|
propertyMetadata,
|
||||||
|
htmlFieldName: propertyMetadata.PropertyName,
|
||||||
|
templateName: null,
|
||||||
|
readOnly: true,
|
||||||
|
additionalViewData: null);
|
||||||
|
|
||||||
|
builder.Append(templateBuilder.Build());
|
||||||
|
|
||||||
|
// TODO: add ModelMetadata.HideSurroundingHtml and use here (skip this block)
|
||||||
|
{
|
||||||
|
builder.AppendLine(divTag.ToString(TagRenderMode.EndTag));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool ShouldShow(ModelMetadata metadata, TemplateInfo templateInfo)
|
||||||
|
{
|
||||||
|
// TODO: add ModelMetadata.ShowForDisplay and include in this calculation (first)
|
||||||
|
return
|
||||||
|
!metadata.IsComplexType &&
|
||||||
|
!templateInfo.Visited(metadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string StringTemplate(IHtmlHelper<object> html)
|
||||||
|
{
|
||||||
|
return html.Encode(html.ViewData.TemplateInfo.FormattedModelValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string UrlTemplate(IHtmlHelper<object> html)
|
||||||
|
{
|
||||||
|
var uriString = (html.ViewData.Model == null) ? string.Empty : html.ViewData.Model.ToString();
|
||||||
|
var linkedText = (html.ViewData.TemplateInfo.FormattedModelValue == null) ?
|
||||||
|
string.Empty :
|
||||||
|
html.ViewData.TemplateInfo.FormattedModelValue.ToString();
|
||||||
|
|
||||||
|
return HyperlinkTemplate(uriString, linkedText);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Neither uriString nor linkedText need be encoded prior to calling this method.
|
||||||
|
private static string HyperlinkTemplate(string uriString, string linkedText)
|
||||||
|
{
|
||||||
|
var hyperlinkTag = new TagBuilder("a");
|
||||||
|
hyperlinkTag.MergeAttribute("href", uriString);
|
||||||
|
hyperlinkTag.SetInnerText(linkedText);
|
||||||
|
|
||||||
|
return hyperlinkTag.ToString(TagRenderMode.Normal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -301,7 +301,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
||||||
ViewContext,
|
ViewContext,
|
||||||
ViewData,
|
ViewData,
|
||||||
metadata,
|
metadata,
|
||||||
templateName,
|
htmlFieldName,
|
||||||
templateName,
|
templateName,
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
additionalViewData: additionalViewData);
|
additionalViewData: additionalViewData);
|
||||||
|
|
@ -1134,10 +1134,16 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GenerateOption(SelectListItem item)
|
private string GenerateOption(SelectListItem item)
|
||||||
|
{
|
||||||
|
var encodedText = Encode(item.Text);
|
||||||
|
return GenerateOption(item, encodedText);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string GenerateOption(SelectListItem item, string encodedText)
|
||||||
{
|
{
|
||||||
var builder = new TagBuilder("option")
|
var builder = new TagBuilder("option")
|
||||||
{
|
{
|
||||||
InnerHtml = Encode(item.Text)
|
InnerHtml = encodedText,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (item.Value != null)
|
if (item.Value != null)
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
var viewData = new ViewDataDictionary(_viewData)
|
var viewData = new ViewDataDictionary<object>(_viewData)
|
||||||
{
|
{
|
||||||
Model = _metadata.Model,
|
Model = _metadata.Model,
|
||||||
ModelMetadata = _metadata
|
ModelMetadata = _metadata
|
||||||
|
|
@ -86,7 +86,5 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
||||||
|
|
||||||
return templateRenderer.Render();
|
return templateRenderer.Render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNet.DependencyInjection;
|
using Microsoft.AspNet.DependencyInjection;
|
||||||
using Microsoft.AspNet.Mvc.Core;
|
using Microsoft.AspNet.Mvc.Core;
|
||||||
|
|
||||||
|
|
@ -15,15 +14,30 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
||||||
private static readonly string DisplayTemplateViewPath = "DisplayTemplates";
|
private static readonly string DisplayTemplateViewPath = "DisplayTemplates";
|
||||||
private static readonly string EditorTemplateViewPath = "EditorTemplates";
|
private static readonly string EditorTemplateViewPath = "EditorTemplates";
|
||||||
|
|
||||||
|
private static readonly Dictionary<string, Func<IHtmlHelper<object>, string>> _defaultDisplayActions =
|
||||||
|
new Dictionary<string, Func<IHtmlHelper<object>, string>>(StringComparer.OrdinalIgnoreCase)
|
||||||
|
{
|
||||||
|
{ "EmailAddress", DefaultDisplayTemplates.EmailAddressTemplate },
|
||||||
|
{ "HiddenInput", DefaultDisplayTemplates.HiddenInputTemplate },
|
||||||
|
{ "Html", DefaultDisplayTemplates.HtmlTemplate },
|
||||||
|
{ "Text", DefaultDisplayTemplates.StringTemplate },
|
||||||
|
{ "Url", DefaultDisplayTemplates.UrlTemplate },
|
||||||
|
{ "Collection", DefaultDisplayTemplates.CollectionTemplate },
|
||||||
|
{ typeof(bool).Name, DefaultDisplayTemplates.BooleanTemplate },
|
||||||
|
{ typeof(decimal).Name, DefaultDisplayTemplates.DecimalTemplate },
|
||||||
|
{ typeof(string).Name, DefaultDisplayTemplates.StringTemplate },
|
||||||
|
{ typeof(object).Name, DefaultDisplayTemplates.ObjectTemplate },
|
||||||
|
};
|
||||||
|
|
||||||
private ViewContext _viewContext;
|
private ViewContext _viewContext;
|
||||||
private ViewDataDictionary _viewData;
|
private ViewDataDictionary<object> _viewData;
|
||||||
private IViewEngine _viewEngine;
|
private IViewEngine _viewEngine;
|
||||||
private string _templateName;
|
private string _templateName;
|
||||||
private bool _readOnly;
|
private bool _readOnly;
|
||||||
|
|
||||||
public TemplateRenderer([NotNull] IViewEngine viewEngine,
|
public TemplateRenderer([NotNull] IViewEngine viewEngine,
|
||||||
[NotNull] ViewContext viewContext,
|
[NotNull] ViewContext viewContext,
|
||||||
[NotNull] ViewDataDictionary viewData,
|
[NotNull] ViewDataDictionary<object> viewData,
|
||||||
string templateName,
|
string templateName,
|
||||||
bool readOnly)
|
bool readOnly)
|
||||||
{
|
{
|
||||||
|
|
@ -61,22 +75,29 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Func<IHtmlHelper<object>, Task<string>> defaultAction;
|
Func<IHtmlHelper<object>, string> defaultAction;
|
||||||
if (defaultActions.TryGetValue(viewName, out defaultAction))
|
if (defaultActions.TryGetValue(viewName, out defaultAction))
|
||||||
{
|
{
|
||||||
// Right now there's no IhtmlHelper<object> pass in or default templates so this will be
|
return defaultAction(MakeHtmlHelper(_viewContext, _viewData));
|
||||||
// changed once a decision has been reached.
|
|
||||||
return defaultAction(null).Result;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new InvalidOperationException(Resources.FormatTemplateHelpers_NoTemplate(_viewData.ModelMetadata.RealModelType.FullName));
|
throw new InvalidOperationException(
|
||||||
|
Resources.FormatTemplateHelpers_NoTemplate(_viewData.ModelMetadata.RealModelType.FullName));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Dictionary<string, Func<IHtmlHelper<object>, Task<string>>> GetDefaultActions()
|
private Dictionary<string, Func<IHtmlHelper<object>, string>> GetDefaultActions()
|
||||||
{
|
{
|
||||||
// TODO: Implement default templates
|
if (_readOnly)
|
||||||
return new Dictionary<string, Func<IHtmlHelper<object>, Task<string>>>(StringComparer.OrdinalIgnoreCase);
|
{
|
||||||
|
return _defaultDisplayActions;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO: Support Editor() and its default templates.
|
||||||
|
// (No resource for this message because this line _must_ be very short-lived.)
|
||||||
|
throw new NotImplementedException("No default editor templates yet");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<string> GetViewNames()
|
private IEnumerable<string> GetViewNames()
|
||||||
|
|
@ -148,5 +169,19 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static IHtmlHelper<object> MakeHtmlHelper(ViewContext viewContext, ViewDataDictionary<object> viewData)
|
||||||
|
{
|
||||||
|
var newHelper = viewContext.HttpContext.RequestServices.GetService<IHtmlHelper<object>>();
|
||||||
|
|
||||||
|
var contextable = newHelper as ICanHasViewContext;
|
||||||
|
if (contextable != null)
|
||||||
|
{
|
||||||
|
var newViewContext = new ViewContext(viewContext, viewContext.View, viewData, viewContext.Writer);
|
||||||
|
contextable.Contextualize(newViewContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
return newHelper;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -183,6 +183,15 @@
|
||||||
<data name="Common_ValueNotValidForProperty" xml:space="preserve">
|
<data name="Common_ValueNotValidForProperty" xml:space="preserve">
|
||||||
<value>The value '{0}' is invalid.</value>
|
<value>The value '{0}' is invalid.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Common_TriState_False" xml:space="preserve">
|
||||||
|
<value>False</value>
|
||||||
|
</data>
|
||||||
|
<data name="Common_TriState_NotSet" xml:space="preserve">
|
||||||
|
<value>Not Set</value>
|
||||||
|
</data>
|
||||||
|
<data name="Common_TriState_True" xml:space="preserve">
|
||||||
|
<value>True</value>
|
||||||
|
</data>
|
||||||
<data name="DynamicViewData_ViewDataNull" xml:space="preserve">
|
<data name="DynamicViewData_ViewDataNull" xml:space="preserve">
|
||||||
<value>ViewData value must not be null.</value>
|
<value>ViewData value must not be null.</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
@ -204,6 +213,9 @@
|
||||||
<data name="HtmlHelper_WrongSelectDataType" xml:space="preserve">
|
<data name="HtmlHelper_WrongSelectDataType" xml:space="preserve">
|
||||||
<value>The ViewData item that has the key '{0}' is of type '{1}' but must be of type '{2}'.</value>
|
<value>The ViewData item that has the key '{0}' is of type '{1}' but must be of type '{2}'.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Templates_TypeMustImplementIEnumerable" xml:space="preserve">
|
||||||
|
<value>The '{0}' template was used with an object of type '{1}', which does not implement '{2}'.</value>
|
||||||
|
</data>
|
||||||
<data name="TemplateHelpers_TemplateLimitations" xml:space="preserve">
|
<data name="TemplateHelpers_TemplateLimitations" xml:space="preserve">
|
||||||
<value>Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions.</value>
|
<value>Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions.</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
@ -231,4 +243,4 @@
|
||||||
<data name="ViewEngine_ViewNotFound" xml:space="preserve">
|
<data name="ViewEngine_ViewNotFound" xml:space="preserve">
|
||||||
<value>The view '{0}' was not found. The following locations were searched:{1}.</value>
|
<value>The view '{0}' was not found. The following locations were searched:{1}.</value>
|
||||||
</data>
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue