Enable input, image and url resolution `TagHelper`s to be written as void elements.

- Razor rendering now understands `TagMode` which allows void elements to be rendered.
- Added a `TagStructure.WithoutEnd` bit to `InputTagHelper`, `ImageTagHelper` and `UrlResolutionTagHelper`. This will allow users to write the various elements in the void format. Used the HTML5 spec to determine the elements appropriate.
- Added tests to ensure `TagMode.StartTagOnly` is rendered properly.
- Updated a few functional tests to showcase the void element formats.

aspnet/Razor#450
This commit is contained in:
N. Taylor Mullen 2015-08-11 12:40:15 -07:00
parent 89a8d0e36c
commit 1b51f6bca6
18 changed files with 278 additions and 136 deletions

View File

@ -336,7 +336,7 @@ namespace Microsoft.AspNet.Mvc.Razor
}
}
if (tagHelperOutput.SelfClosing)
if (tagHelperOutput.TagMode == TagMode.SelfClosing)
{
writer.Write(" /");
}
@ -344,7 +344,7 @@ namespace Microsoft.AspNet.Mvc.Razor
writer.Write('>');
}
if (isTagNameNullOrWhitespace || !tagHelperOutput.SelfClosing)
if (isTagNameNullOrWhitespace || tagHelperOutput.TagMode == TagMode.StartTagAndEndTag)
{
WriteTo(writer, tagHelperOutput.PreContent);
if (tagHelperOutput.IsContentModified)
@ -364,7 +364,7 @@ namespace Microsoft.AspNet.Mvc.Razor
WriteTo(writer, tagHelperOutput.PostContent);
}
if (!isTagNameNullOrWhitespace && !tagHelperOutput.SelfClosing)
if (!isTagNameNullOrWhitespace && tagHelperOutput.TagMode == TagMode.StartTagAndEndTag)
{
writer.Write(string.Format(CultureInfo.InvariantCulture, "</{0}>", tagHelperOutput.TagName));
}

View File

@ -4,7 +4,6 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
@ -21,28 +20,28 @@ namespace Microsoft.AspNet.Mvc.Razor.TagHelpers
[TargetElement("*", Attributes = "itemid")]
[TargetElement("a", Attributes = "href")]
[TargetElement("applet", Attributes = "archive")]
[TargetElement("area", Attributes = "href")]
[TargetElement("area", Attributes = "href", TagStructure = TagStructure.WithoutEndTag)]
[TargetElement("audio", Attributes = "src")]
[TargetElement("base", Attributes = "href")]
[TargetElement("base", Attributes = "href", TagStructure = TagStructure.WithoutEndTag)]
[TargetElement("blockquote", Attributes = "cite")]
[TargetElement("button", Attributes = "formaction")]
[TargetElement("del", Attributes = "cite")]
[TargetElement("embed", Attributes = "src")]
[TargetElement("embed", Attributes = "src", TagStructure = TagStructure.WithoutEndTag)]
[TargetElement("form", Attributes = "action")]
[TargetElement("html", Attributes = "manifest")]
[TargetElement("iframe", Attributes = "src")]
[TargetElement("img", Attributes = "src")]
[TargetElement("input", Attributes = "src")]
[TargetElement("input", Attributes = "formaction")]
[TargetElement("img", Attributes = "src", TagStructure = TagStructure.WithoutEndTag)]
[TargetElement("input", Attributes = "src", TagStructure = TagStructure.WithoutEndTag)]
[TargetElement("input", Attributes = "formaction", TagStructure = TagStructure.WithoutEndTag)]
[TargetElement("ins", Attributes = "cite")]
[TargetElement("link", Attributes = "href")]
[TargetElement("link", Attributes = "href", TagStructure = TagStructure.WithoutEndTag)]
[TargetElement("menuitem", Attributes = "icon")]
[TargetElement("object", Attributes = "archive")]
[TargetElement("object", Attributes = "data")]
[TargetElement("q", Attributes = "cite")]
[TargetElement("script", Attributes = "src")]
[TargetElement("source", Attributes = "src")]
[TargetElement("track", Attributes = "src")]
[TargetElement("source", Attributes = "src", TagStructure = TagStructure.WithoutEndTag)]
[TargetElement("track", Attributes = "src", TagStructure = TagStructure.WithoutEndTag)]
[TargetElement("video", Attributes = "src")]
[TargetElement("video", Attributes = "poster")]
[EditorBrowsable(EditorBrowsableState.Never)]

View File

@ -16,7 +16,10 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
/// <remarks>
/// The tag helper won't process for cases with just the 'src' attribute.
/// </remarks>
[TargetElement("img", Attributes = AppendVersionAttributeName + "," + SrcAttributeName)]
[TargetElement(
"img",
Attributes = AppendVersionAttributeName + "," + SrcAttributeName,
TagStructure = TagStructure.WithoutEndTag)]
public class ImageTagHelper : UrlResolutionTagHelper
{
private static readonly string Namespace = typeof(ImageTagHelper).Namespace;

View File

@ -15,7 +15,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
/// <summary>
/// <see cref="ITagHelper"/> implementation targeting &lt;input&gt; elements with an <c>asp-for</c> attribute.
/// </summary>
[TargetElement("input", Attributes = ForAttributeName)]
[TargetElement("input", Attributes = ForAttributeName, TagStructure = TagStructure.WithoutEndTag)]
public class InputTagHelper : TagHelper
{
private const string ForAttributeName = "asp-for";

View File

@ -9,27 +9,27 @@
<h2>Image Tag Helper Test</h2>
<!-- Plain image tag -->
<img src="/images/red.png" alt="Red block" title="&lt;the title>" />
<img src="/images/red.png" alt="Red block" title="&lt;the title>">
<!-- Plain image tag with file version -->
<img alt="Red versioned" title="Red versioned" src="/images/red.png?v=W2F5D366_nQ2fQqUk3URdgWy2ZekXjHzHJaY5yaiOOk" />
<!-- Plain image tag with file version set to false -->
<img alt="Red explicitly not versioned" title="Red versioned" src="/images/red.png" />
<img alt="Red explicitly not versioned" title="Red versioned" src="/images/red.png">
<!-- Plain image tag with absolute path and file version -->
<img alt="Absolute path versioned" src="http://contoso.com/hello/world" />
<img alt="Absolute path versioned" src="http://contoso.com/hello/world">
<!-- Plain image tag with file version and path to file that does not exist -->
<img alt="Path to non existing file" src="/images/fake.png" />
<!-- Plain image tag with file version and path containing query string -->
<img alt="Path with query string" src="/images/red.png?abc=def&amp;v=W2F5D366_nQ2fQqUk3URdgWy2ZekXjHzHJaY5yaiOOk" />
<img alt="Path with query string" src="/images/red.png?abc=def&amp;v=W2F5D366_nQ2fQqUk3URdgWy2ZekXjHzHJaY5yaiOOk">
<!-- Plain image tag with file version and path containing fragment -->
<img alt="Path with query string" src="/images/red.png?v=W2F5D366_nQ2fQqUk3URdgWy2ZekXjHzHJaY5yaiOOk#abc" />
<!-- Plain image tag with file version and path linking to some action -->
<img alt="Path linking to some action" src="/controller/action" />
<img alt="Path linking to some action" src="/controller/action">
</body>
</html>

View File

@ -1,22 +1,22 @@
<html manifest="HtmlEncode[[/]]Person">
<head>
<base href="HtmlEncode[[/]]A+Really(Crazy),Url.Is:This/HtmlEncode[[John Doe]]/Detail" target="_blank" />
<base href="HtmlEncode[[/]]A+Really(Crazy),Url.Is:This/HtmlEncode[[John Doe]]/Detail" target="_blank">
</head>
<body>
<dl itemscope itemid="HtmlEncode[[/]]Url"></dl>
<a href="HtmlEncode[[/]]Person">Person</a>
<area href="HtmlEncode[[/]]Person/HtmlEncode[[John Doe]]" alt="Url stuff" />
<link href="HtmlEncode[[/]]Person/HtmlEncode[[John Doe]]/CSS" rel="stylesheet" />
<area href="HtmlEncode[[/]]Person/HtmlEncode[[John Doe]]" alt="Url stuff">
<link href="HtmlEncode[[/]]Person/HtmlEncode[[John Doe]]/CSS" rel="stylesheet">
<video poster="HtmlEncode[[~/SomeUrl]]" src="HtmlEncode[[~/SomeUrl]]/HtmlEncode[[video]]" />
<audio src="HtmlEncode[[~/SomeUrl]]">
<source src="HtmlEncode[[/]]Person" />
<track src="HtmlEncode[[/]]emailHtmlEncode[[~/SomeUrl]]" />
<source src="HtmlEncode[[/]]Person">
<track src="HtmlEncode[[/]]emailHtmlEncode[[~/SomeUrl]]">
</audio>
<embed src="HtmlEncode[[/]]email@dyanmicUrl" />
<embed src="HtmlEncode[[/]]email@dyanmicUrl">
<iframe src="HtmlEncode[[~/SomeUrl]]" />
<img src="HtmlEncode[[/]]HtmlEncode[[~/SomeUrl]]" />
<img src="HtmlEncode[[/]]HtmlEncode[[~/SomeUrl]]">
<script src="HtmlEncode[[/]]Person/HtmlEncode[[John Doe]]/JS"></script>
<input src="HtmlEncode[[/]]/Person" itemscope itemid="HtmlEncode[[/]]Person" formaction="HtmlEncode[[~/SomeUrl]]" />
<input src="HtmlEncode[[/]]/Person" itemscope itemid="HtmlEncode[[/]]Person" formaction="HtmlEncode[[~/SomeUrl]]">
<button formaction="HtmlEncode[[/]]\Person" />
<form action="HtmlEncode[[/]]~Person" />
<blockquote cite="HtmlEncode[[/]]Person" />

View File

@ -1,22 +1,22 @@
<html manifest="/Person">
<head>
<base href="/A+Really(Crazy),Url.Is:This/John Doe/Detail" target="_blank" />
<base href="/A+Really(Crazy),Url.Is:This/John Doe/Detail" target="_blank">
</head>
<body>
<dl itemscope itemid="/Url"></dl>
<a href="/Person">Person</a>
<area href="/Person/John Doe" alt="Url stuff" />
<link href="/Person/John Doe/CSS" rel="stylesheet" />
<area href="/Person/John Doe" alt="Url stuff">
<link href="/Person/John Doe/CSS" rel="stylesheet">
<video poster="/SomeUrl" src="/SomeUrl/video" />
<audio src="/SomeUrl">
<source src="/Person" />
<track src="/email~/SomeUrl" />
<source src="/Person">
<track src="/email~/SomeUrl">
</audio>
<embed src="/email@dyanmicUrl" />
<embed src="/email@dyanmicUrl">
<iframe src="/SomeUrl" />
<img src="/~/SomeUrl" />
<img src="/~/SomeUrl">
<script src="/Person/John Doe/JS"></script>
<input src="//Person" itemscope itemid="/Person" formaction="/SomeUrl" />
<input src="//Person" itemscope itemid="/Person" formaction="/SomeUrl">
<button formaction="/\Person" />
<form action="/~Person" />
<blockquote cite="/Person" />

View File

@ -48,7 +48,7 @@ namespace Asp
BeginContext(117, 1, true);
WriteLiteral("\n");
EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input-test", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input-test", TagMode.SelfClosing, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__Microsoft_AspNet_Mvc_Razor_InputTestTagHelper = CreateTagHelper<Microsoft.AspNet.Mvc.Razor.InputTestTagHelper>();
@ -67,7 +67,7 @@ __Microsoft_AspNet_Mvc_Razor_InputTestTagHelper.For = CreateModelExpression(__mo
BeginContext(142, 1, true);
WriteLiteral("\n");
EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input-test", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input-test", TagMode.SelfClosing, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__Microsoft_AspNet_Mvc_Razor_InputTestTagHelper = CreateTagHelper<Microsoft.AspNet.Mvc.Razor.InputTestTagHelper>();

View File

@ -833,7 +833,7 @@ namespace Microsoft.AspNet.Mvc.Razor
page.HtmlEncoder = new CommonTestEncoder();
var executionContext = new TagHelperExecutionContext(
"p",
selfClosing: false,
tagMode: TagMode.StartTagAndEndTag,
items: null,
uniqueId: string.Empty,
executeChildContentAsync: () => Task.FromResult(result: true),
@ -868,7 +868,7 @@ namespace Microsoft.AspNet.Mvc.Razor
page.HtmlEncoder = new CommonTestEncoder();
var executionContext = new TagHelperExecutionContext(
"p",
selfClosing: false,
tagMode: TagMode.StartTagAndEndTag,
items: null,
uniqueId: string.Empty,
executeChildContentAsync: () => Task.FromResult(result: true),
@ -900,7 +900,7 @@ namespace Microsoft.AspNet.Mvc.Razor
page.HtmlEncoder = new CommonTestEncoder();
var executionContext = new TagHelperExecutionContext(
"p",
selfClosing: false,
tagMode: TagMode.StartTagAndEndTag,
items: null,
uniqueId: string.Empty,
executeChildContentAsync: () => Task.FromResult(result: true),
@ -1053,7 +1053,7 @@ namespace Microsoft.AspNet.Mvc.Razor
GetTagHelperOutput(
tagName: "div",
attributes: new TagHelperAttributeList(),
selfClosing: false,
tagMode: TagMode.StartTagAndEndTag,
preElement: null,
preContent: null,
content: "Hello World!",
@ -1065,7 +1065,7 @@ namespace Microsoft.AspNet.Mvc.Razor
GetTagHelperOutput(
tagName: null,
attributes: new TagHelperAttributeList(),
selfClosing: false,
tagMode: TagMode.StartTagAndEndTag,
preElement: null,
preContent: null,
content: "Hello World!",
@ -1077,7 +1077,7 @@ namespace Microsoft.AspNet.Mvc.Razor
GetTagHelperOutput(
tagName: " ",
attributes: new TagHelperAttributeList(),
selfClosing: false,
tagMode: TagMode.StartTagAndEndTag,
preElement: null,
preContent: null,
content: "Hello World!",
@ -1089,7 +1089,7 @@ namespace Microsoft.AspNet.Mvc.Razor
GetTagHelperOutput(
tagName: "p",
attributes: new TagHelperAttributeList() { { "test", "testVal" } },
selfClosing: false,
tagMode: TagMode.StartTagAndEndTag,
preElement: null,
preContent: null,
content: "Hello World!",
@ -1101,7 +1101,7 @@ namespace Microsoft.AspNet.Mvc.Razor
GetTagHelperOutput(
tagName: "p",
attributes: new TagHelperAttributeList() { { "test", "testVal" }, { "something", " spaced " } },
selfClosing: false,
tagMode: TagMode.StartTagAndEndTag,
preElement: null,
preContent: null,
content: "Hello World!",
@ -1120,7 +1120,7 @@ namespace Microsoft.AspNet.Mvc.Razor
Minimized = true
},
},
selfClosing: false,
tagMode: TagMode.StartTagAndEndTag,
preElement: null,
preContent: null,
content: "Hello World!",
@ -1144,7 +1144,7 @@ namespace Microsoft.AspNet.Mvc.Razor
Minimized = true
},
},
selfClosing: false,
tagMode: TagMode.StartTagAndEndTag,
preElement: null,
preContent: null,
content: "Hello World!",
@ -1164,7 +1164,7 @@ namespace Microsoft.AspNet.Mvc.Razor
Minimized = true
},
},
selfClosing: false,
tagMode: TagMode.StartTagAndEndTag,
preElement: null,
preContent: null,
content: "Hello World!",
@ -1184,7 +1184,7 @@ namespace Microsoft.AspNet.Mvc.Razor
},
["last"] = "unminimized",
},
selfClosing: false,
tagMode: TagMode.StartTagAndEndTag,
preElement: null,
preContent: null,
content: "Hello World!",
@ -1196,7 +1196,7 @@ namespace Microsoft.AspNet.Mvc.Razor
GetTagHelperOutput(
tagName: "p",
attributes: new TagHelperAttributeList() { { "test", "testVal" } },
selfClosing: true,
tagMode: TagMode.SelfClosing,
preElement: null,
preContent: null,
content: "Hello World!",
@ -1208,7 +1208,7 @@ namespace Microsoft.AspNet.Mvc.Razor
GetTagHelperOutput(
tagName: "p",
attributes: new TagHelperAttributeList() { { "test", "testVal" }, { "something", " spaced " } },
selfClosing: true,
tagMode: TagMode.SelfClosing,
preElement: null,
preContent: null,
content: "Hello World!",
@ -1216,11 +1216,35 @@ namespace Microsoft.AspNet.Mvc.Razor
postElement: null),
"<p test=\"HtmlEncode[[testVal]]\" something=\"HtmlEncode[[ spaced ]]\" />"
},
{
GetTagHelperOutput(
tagName: "p",
attributes: new TagHelperAttributeList() { { "test", "testVal" } },
tagMode: TagMode.StartTagOnly,
preElement: null,
preContent: null,
content: "Hello World!",
postContent: null,
postElement: null),
"<p test=\"HtmlEncode[[testVal]]\">"
},
{
GetTagHelperOutput(
tagName: "p",
attributes: new TagHelperAttributeList() { { "test", "testVal" }, { "something", " spaced " } },
tagMode: TagMode.StartTagOnly,
preElement: null,
preContent: null,
content: "Hello World!",
postContent: null,
postElement: null),
"<p test=\"HtmlEncode[[testVal]]\" something=\"HtmlEncode[[ spaced ]]\">"
},
{
GetTagHelperOutput(
tagName: "p",
attributes: new TagHelperAttributeList(),
selfClosing: false,
tagMode: TagMode.StartTagAndEndTag,
preElement: null,
preContent: "Hello World!",
content: null,
@ -1232,7 +1256,7 @@ namespace Microsoft.AspNet.Mvc.Razor
GetTagHelperOutput(
tagName: "p",
attributes: new TagHelperAttributeList(),
selfClosing: false,
tagMode: TagMode.StartTagAndEndTag,
preElement: null,
preContent: null,
content: "Hello World!",
@ -1244,7 +1268,7 @@ namespace Microsoft.AspNet.Mvc.Razor
GetTagHelperOutput(
tagName: "p",
attributes: new TagHelperAttributeList(),
selfClosing: false,
tagMode: TagMode.StartTagAndEndTag,
preElement: null,
preContent: null,
content: null,
@ -1256,7 +1280,7 @@ namespace Microsoft.AspNet.Mvc.Razor
GetTagHelperOutput(
tagName: "p",
attributes: new TagHelperAttributeList(),
selfClosing: false,
tagMode: TagMode.StartTagAndEndTag,
preElement: null,
preContent: "Hello",
content: "Test",
@ -1268,7 +1292,7 @@ namespace Microsoft.AspNet.Mvc.Razor
GetTagHelperOutput(
tagName: "p",
attributes: new TagHelperAttributeList(),
selfClosing: true,
tagMode: TagMode.SelfClosing,
preElement: null,
preContent: "Hello",
content: "Test",
@ -1276,11 +1300,23 @@ namespace Microsoft.AspNet.Mvc.Razor
postElement: null),
"<p />"
},
{
GetTagHelperOutput(
tagName: "p",
attributes: new TagHelperAttributeList(),
tagMode: TagMode.StartTagOnly,
preElement: null,
preContent: "Hello",
content: "Test",
postContent: "World!",
postElement: null),
"<p>"
},
{
GetTagHelperOutput(
tagName: "custom",
attributes: new TagHelperAttributeList(),
selfClosing: false,
tagMode: TagMode.StartTagAndEndTag,
preElement: null,
preContent: "Hello",
content: "Test",
@ -1292,7 +1328,7 @@ namespace Microsoft.AspNet.Mvc.Razor
GetTagHelperOutput(
tagName: "random",
attributes: new TagHelperAttributeList(),
selfClosing: true,
tagMode: TagMode.SelfClosing,
preElement: null,
preContent: "Hello",
content: "Test",
@ -1300,11 +1336,23 @@ namespace Microsoft.AspNet.Mvc.Razor
postElement: null),
"<random />"
},
{
GetTagHelperOutput(
tagName: "random",
attributes: new TagHelperAttributeList(),
tagMode: TagMode.StartTagOnly,
preElement: null,
preContent: "Hello",
content: "Test",
postContent: "World!",
postElement: null),
"<random>"
},
{
GetTagHelperOutput(
tagName: "custom",
attributes: new TagHelperAttributeList(),
selfClosing: false,
tagMode: TagMode.StartTagAndEndTag,
preElement: "Before",
preContent: null,
content: null,
@ -1316,7 +1364,7 @@ namespace Microsoft.AspNet.Mvc.Razor
GetTagHelperOutput(
tagName: null,
attributes: new TagHelperAttributeList(),
selfClosing: false,
tagMode: TagMode.StartTagAndEndTag,
preElement: "Before",
preContent: null,
content: null,
@ -1328,7 +1376,7 @@ namespace Microsoft.AspNet.Mvc.Razor
GetTagHelperOutput(
tagName: null,
attributes: new TagHelperAttributeList { { "test", "testVal" } },
selfClosing: true,
tagMode: TagMode.SelfClosing,
preElement: "Before",
preContent: null,
content: null,
@ -1340,7 +1388,7 @@ namespace Microsoft.AspNet.Mvc.Razor
GetTagHelperOutput(
tagName: "custom",
attributes: new TagHelperAttributeList { { "test", "testVal" } },
selfClosing: true,
tagMode: TagMode.SelfClosing,
preElement: "Before",
preContent: null,
content: null,
@ -1352,7 +1400,7 @@ namespace Microsoft.AspNet.Mvc.Razor
GetTagHelperOutput(
tagName: "custom",
attributes: new TagHelperAttributeList(),
selfClosing: true,
tagMode: TagMode.SelfClosing,
preElement: "Before",
preContent: null,
content: null,
@ -1360,11 +1408,47 @@ namespace Microsoft.AspNet.Mvc.Razor
postElement: null),
"Before<custom />"
},
{
GetTagHelperOutput(
tagName: null,
attributes: new TagHelperAttributeList { { "test", "testVal" } },
tagMode: TagMode.StartTagOnly,
preElement: "Before",
preContent: null,
content: null,
postContent: null,
postElement: null),
"Before"
},
{
GetTagHelperOutput(
tagName: "custom",
attributes: new TagHelperAttributeList { { "test", "testVal" } },
tagMode: TagMode.StartTagOnly,
preElement: "Before",
preContent: null,
content: null,
postContent: null,
postElement: null),
"Before<custom test=\"HtmlEncode[[testVal]]\">"
},
{
GetTagHelperOutput(
tagName: "custom",
attributes: new TagHelperAttributeList(),
selfClosing: false,
tagMode: TagMode.StartTagOnly,
preElement: "Before",
preContent: null,
content: null,
postContent: null,
postElement: null),
"Before<custom>"
},
{
GetTagHelperOutput(
tagName: "custom",
attributes: new TagHelperAttributeList(),
tagMode: TagMode.StartTagAndEndTag,
preElement: null,
preContent: null,
content: null,
@ -1376,7 +1460,7 @@ namespace Microsoft.AspNet.Mvc.Razor
GetTagHelperOutput(
tagName: null,
attributes: new TagHelperAttributeList(),
selfClosing: false,
tagMode: TagMode.StartTagAndEndTag,
preElement: null,
preContent: null,
content: null,
@ -1388,7 +1472,7 @@ namespace Microsoft.AspNet.Mvc.Razor
GetTagHelperOutput(
tagName: null,
attributes: new TagHelperAttributeList { { "test", "testVal" } },
selfClosing: true,
tagMode: TagMode.SelfClosing,
preElement: null,
preContent: null,
content: null,
@ -1400,7 +1484,7 @@ namespace Microsoft.AspNet.Mvc.Razor
GetTagHelperOutput(
tagName: "custom",
attributes: new TagHelperAttributeList { { "test", "testVal" } },
selfClosing: true,
tagMode: TagMode.SelfClosing,
preElement: null,
preContent: null,
content: null,
@ -1412,7 +1496,7 @@ namespace Microsoft.AspNet.Mvc.Razor
GetTagHelperOutput(
tagName: "custom",
attributes: new TagHelperAttributeList(),
selfClosing: true,
tagMode: TagMode.SelfClosing,
preElement: null,
preContent: null,
content: null,
@ -1420,11 +1504,47 @@ namespace Microsoft.AspNet.Mvc.Razor
postElement: "After"),
"<custom />After"
},
{
GetTagHelperOutput(
tagName: null,
attributes: new TagHelperAttributeList { { "test", "testVal" } },
tagMode: TagMode.StartTagOnly,
preElement: null,
preContent: null,
content: null,
postContent: null,
postElement: "After"),
"After"
},
{
GetTagHelperOutput(
tagName: "custom",
attributes: new TagHelperAttributeList { { "test", "testVal" } },
tagMode: TagMode.StartTagOnly,
preElement: null,
preContent: null,
content: null,
postContent: null,
postElement: "After"),
"<custom test=\"HtmlEncode[[testVal]]\">After"
},
{
GetTagHelperOutput(
tagName: "custom",
attributes: new TagHelperAttributeList(),
selfClosing: false,
tagMode: TagMode.StartTagOnly,
preElement: null,
preContent: null,
content: null,
postContent: null,
postElement: "After"),
"<custom>After"
},
{
GetTagHelperOutput(
tagName: "custom",
attributes: new TagHelperAttributeList(),
tagMode: TagMode.StartTagAndEndTag,
preElement: "Before",
preContent: "Hello",
content: "Test",
@ -1436,7 +1556,7 @@ namespace Microsoft.AspNet.Mvc.Razor
GetTagHelperOutput(
tagName: "custom",
attributes: new TagHelperAttributeList { { "test", "testVal" } },
selfClosing: false,
tagMode: TagMode.StartTagAndEndTag,
preElement: "Before",
preContent: "Hello",
content: "Test",
@ -1448,7 +1568,7 @@ namespace Microsoft.AspNet.Mvc.Razor
GetTagHelperOutput(
tagName: "custom",
attributes: new TagHelperAttributeList(),
selfClosing: true,
tagMode: TagMode.SelfClosing,
preElement: "Before",
preContent: "Hello",
content: "Test",
@ -1460,7 +1580,31 @@ namespace Microsoft.AspNet.Mvc.Razor
GetTagHelperOutput(
tagName: null,
attributes: new TagHelperAttributeList(),
selfClosing: true,
tagMode: TagMode.SelfClosing,
preElement: "Before",
preContent: "Hello",
content: "Test",
postContent: "World!",
postElement: "After"),
"BeforeHelloTestWorld!After"
},
{
GetTagHelperOutput(
tagName: "custom",
attributes: new TagHelperAttributeList(),
tagMode: TagMode.StartTagOnly,
preElement: "Before",
preContent: "Hello",
content: "Test",
postContent: "World!",
postElement: "After"),
"Before<custom>After"
},
{
GetTagHelperOutput(
tagName: null,
attributes: new TagHelperAttributeList(),
tagMode: TagMode.StartTagOnly,
preElement: "Before",
preContent: "Hello",
content: "Test",
@ -1472,7 +1616,7 @@ namespace Microsoft.AspNet.Mvc.Razor
GetTagHelperOutput(
tagName: null,
attributes: new TagHelperAttributeList(),
selfClosing: false,
tagMode: TagMode.StartTagAndEndTag,
preElement: "Before",
preContent: "Hello",
content: "Test",
@ -1484,7 +1628,7 @@ namespace Microsoft.AspNet.Mvc.Razor
GetTagHelperOutput(
tagName: null,
attributes: new TagHelperAttributeList { { "test", "testVal" } },
selfClosing: false,
tagMode: TagMode.StartTagAndEndTag,
preElement: "Before",
preContent: "Hello",
content: "Test",
@ -1505,7 +1649,7 @@ namespace Microsoft.AspNet.Mvc.Razor
var context = CreateViewContext(writer);
var tagHelperExecutionContext = new TagHelperExecutionContext(
tagName: output.TagName,
selfClosing: output.SelfClosing,
tagMode: output.TagMode,
items: new Dictionary<object, object>(),
uniqueId: string.Empty,
executeChildContentAsync: () => Task.FromResult(result: true),
@ -1539,7 +1683,7 @@ namespace Microsoft.AspNet.Mvc.Razor
var context = CreateViewContext(writer);
var tagHelperExecutionContext = new TagHelperExecutionContext(
tagName: "p",
selfClosing: false,
tagMode: TagMode.StartTagAndEndTag,
items: new Dictionary<object, object>(),
uniqueId: string.Empty,
executeChildContentAsync: () =>
@ -1575,7 +1719,7 @@ namespace Microsoft.AspNet.Mvc.Razor
var context = CreateViewContext(new StringWriter());
var tagHelperExecutionContext = new TagHelperExecutionContext(
tagName: "p",
selfClosing: false,
tagMode: TagMode.StartTagAndEndTag,
items: new Dictionary<object, object>(),
uniqueId: string.Empty,
executeChildContentAsync: () => { return Task.FromResult(result: true); },
@ -1604,7 +1748,7 @@ namespace Microsoft.AspNet.Mvc.Razor
var context = CreateViewContext(new StringWriter());
var tagHelperExecutionContext = new TagHelperExecutionContext(
tagName: output.TagName,
selfClosing: output.SelfClosing,
tagMode: output.TagMode,
items: new Dictionary<object, object>(),
uniqueId: string.Empty,
executeChildContentAsync: () => Task.FromResult(result: true),
@ -1627,7 +1771,7 @@ namespace Microsoft.AspNet.Mvc.Razor
private static TagHelperOutput GetTagHelperOutput(
string tagName,
TagHelperAttributeList attributes,
bool selfClosing,
TagMode tagMode,
string preElement,
string preContent,
string content,
@ -1636,7 +1780,7 @@ namespace Microsoft.AspNet.Mvc.Razor
{
var output = new TagHelperOutput(tagName, attributes)
{
SelfClosing = selfClosing
TagMode = tagMode
};
output.PreElement.SetContent(preElement);

View File

@ -11,7 +11,6 @@ using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using Microsoft.AspNet.Routing;
using Microsoft.Framework.WebEncoders.Testing;
using Moq;
using Xunit;
@ -137,7 +136,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
// Assert
Assert.Equal("form", output.TagName);
Assert.False(output.SelfClosing);
Assert.Equal(TagMode.StartTagAndEndTag, output.TagMode);
Assert.Empty(output.Attributes);
Assert.Empty(output.PreContent.GetContent());
Assert.True(output.Content.IsEmpty);
@ -207,7 +206,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
await formTagHelper.ProcessAsync(context, output);
Assert.Equal("form", output.TagName);
Assert.False(output.SelfClosing);
Assert.Equal(TagMode.StartTagAndEndTag ,output.TagMode);
var attribute = Assert.Single(output.Attributes);
Assert.Equal(expectedAttribute, attribute);
Assert.Empty(output.PreContent.GetContent());
@ -259,7 +258,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
generator.Verify();
Assert.Equal("form", output.TagName);
Assert.False(output.SelfClosing);
Assert.Equal(TagMode.StartTagAndEndTag, output.TagMode);
Assert.Empty(output.Attributes);
Assert.Empty(output.PreElement.GetContent());
Assert.Empty(output.PreContent.GetContent());
@ -312,7 +311,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
generator.Verify();
Assert.Equal("form", output.TagName);
Assert.False(output.SelfClosing);
Assert.Equal(TagMode.StartTagAndEndTag, output.TagMode);
Assert.Empty(output.Attributes);
Assert.Empty(output.PreElement.GetContent());
Assert.Empty(output.PreContent.GetContent());
@ -364,7 +363,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
// Assert
Assert.Equal("form", output.TagName);
Assert.False(output.SelfClosing);
Assert.Equal(TagMode.StartTagAndEndTag, output.TagMode);
var attribute = Assert.Single(output.Attributes);
Assert.Equal(new TagHelperAttribute("aCTiON", "my-action"), attribute);
Assert.Empty(output.PreContent.GetContent());

View File

@ -4,17 +4,14 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNet.Html.Abstractions;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Mvc.Rendering.Internal;
using Microsoft.AspNet.Mvc.TestCommon;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using Microsoft.Framework.WebEncoders.Testing;
using Moq;
using Xunit;
@ -96,7 +93,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
getChildContentAsync: useCachedResult => Task.FromResult<TagHelperContent>(result: null));
var output = new TagHelperOutput(originalTagName, outputAttributes)
{
SelfClosing = true,
TagMode = TagMode.SelfClosing,
};
output.Content.SetContent(originalContent);
var htmlGenerator = new TestableHtmlGenerator(new EmptyModelMetadataProvider());
@ -108,7 +105,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
// Assert
Assert.Empty(output.Attributes); // Moved to Content and cleared
Assert.Equal(expectedContent, HtmlContentUtilities.HtmlContentToString(output.Content));
Assert.True(output.SelfClosing);
Assert.Equal(TagMode.SelfClosing, output.TagMode);
Assert.Null(output.TagName); // Cleared
}
@ -209,7 +206,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
};
var output = new TagHelperOutput(expectedTagName, originalAttributes)
{
SelfClosing = false,
TagMode = TagMode.StartTagOnly,
};
output.PreContent.SetContent(expectedPreContent);
output.Content.SetContent(expectedContent);
@ -240,7 +237,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
Assert.Equal(expectedPreContent, output.PreContent.GetContent());
Assert.Equal(expectedContent, output.Content.GetContent());
Assert.Equal(expectedPostContent, output.PostContent.GetContent());
Assert.False(output.SelfClosing);
Assert.Equal(TagMode.StartTagOnly, output.TagMode);
Assert.Equal(expectedTagName, output.TagName);
}
@ -271,7 +268,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
};
var output = new TagHelperOutput(originalTagName, originalAttributes)
{
SelfClosing = true,
TagMode = TagMode.SelfClosing,
};
output.PreContent.SetContent(expectedPreContent);
output.Content.SetContent(originalContent);
@ -313,7 +310,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
Assert.Equal(expectedPreContent, output.PreContent.GetContent());
Assert.Equal(expectedContent, HtmlContentUtilities.HtmlContentToString(output.Content));
Assert.Equal(expectedPostContent, output.PostContent.GetContent());
Assert.True(output.SelfClosing);
Assert.Equal(TagMode.SelfClosing, output.TagMode);
Assert.Null(output.TagName); // Cleared
}
@ -367,7 +364,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
};
var output = new TagHelperOutput(expectedTagName, originalAttributes)
{
SelfClosing = false,
TagMode = TagMode.StartTagOnly,
};
output.PreContent.SetContent(expectedPreContent);
output.Content.SetContent(expectedContent);
@ -408,7 +405,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
// Assert
htmlGenerator.Verify();
Assert.False(output.SelfClosing);
Assert.Equal(TagMode.StartTagOnly, output.TagMode);
Assert.Equal(expectedAttributes, output.Attributes);
Assert.Equal(expectedPreContent, output.PreContent.GetContent());
Assert.Equal(expectedContent, output.Content.GetContent());
@ -466,7 +463,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
};
var output = new TagHelperOutput(expectedTagName, originalAttributes)
{
SelfClosing = false,
TagMode = TagMode.StartTagOnly,
};
output.PreContent.SetContent(expectedPreContent);
output.Content.SetContent(expectedContent);
@ -506,7 +503,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
// Assert
htmlGenerator.Verify();
Assert.False(output.SelfClosing);
Assert.Equal(TagMode.StartTagOnly, output.TagMode);
Assert.Equal(expectedAttributes, output.Attributes);
Assert.Equal(expectedPreContent, output.PreContent.GetContent());
Assert.Equal(expectedContent, output.Content.GetContent());
@ -562,7 +559,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
};
var output = new TagHelperOutput(expectedTagName, originalAttributes)
{
SelfClosing = false,
TagMode = TagMode.StartTagOnly,
};
output.PreContent.SetContent(expectedPreContent);
output.Content.SetContent(expectedContent);
@ -597,7 +594,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
// Assert
htmlGenerator.Verify();
Assert.False(output.SelfClosing);
Assert.Equal(TagMode.StartTagOnly, output.TagMode);
Assert.Equal(expectedAttributes, output.Attributes);
Assert.Equal(expectedPreContent, output.PreContent.GetContent());
Assert.Equal(expectedContent, output.Content.GetContent());
@ -669,7 +666,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
};
var output = new TagHelperOutput(expectedTagName, originalAttributes)
{
SelfClosing = false,
TagMode = TagMode.StartTagOnly,
};
output.PreContent.SetContent(expectedPreContent);
output.Content.SetContent(expectedContent);
@ -710,7 +707,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
// Assert
htmlGenerator.Verify();
Assert.False(output.SelfClosing);
Assert.Equal(TagMode.StartTagOnly, output.TagMode);
Assert.Equal(expectedAttributes, output.Attributes);
Assert.Equal(expectedPreContent, output.PreContent.GetContent());
Assert.Equal(expectedContent, output.Content.GetContent());
@ -781,7 +778,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
var output = new TagHelperOutput(expectedTagName, attributes: new TagHelperAttributeList())
{
SelfClosing = true,
TagMode = TagMode.SelfClosing,
};
var metadataProvider = new TestModelMetadataProvider();
@ -821,7 +818,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
// Assert
htmlGenerator.Verify();
Assert.True(output.SelfClosing);
Assert.Equal(TagMode.SelfClosing, output.TagMode);
Assert.Equal(expectedAttributes, output.Attributes);
Assert.Empty(output.PreContent.GetContent());
Assert.Equal(string.Empty, output.Content.GetContent());
@ -862,7 +859,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
var output = new TagHelperOutput(expectedTagName, attributes: new TagHelperAttributeList())
{
SelfClosing = true,
TagMode = TagMode.SelfClosing,
};
var htmlAttributes = new Dictionary<string, object>
@ -896,7 +893,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
// Assert
htmlGenerator.Verify();
Assert.True(output.SelfClosing);
Assert.Equal(TagMode.SelfClosing, output.TagMode);
Assert.Equal(expectedAttributes, output.Attributes);
Assert.Empty(output.PreContent.GetContent());
Assert.Equal(string.Empty, output.Content.GetContent());

View File

@ -207,13 +207,13 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
output.PreContent.SetContent(expectedPreContent);
output.PostContent.SetContent(expectedPostContent);
// LabelTagHelper checks IsContentModified so we don't want to forcibly set it if
// LabelTagHelper checks IsContentModified so we don't want to forcibly set it if
// tagHelperOutputContent.OriginalContent is going to be null or empty.
if (!string.IsNullOrEmpty(tagHelperOutputContent.OriginalContent))
{
output.Content.SetContent(tagHelperOutputContent.OriginalContent);
}
var viewContext = TestableHtmlGenerator.GetViewContext(model, htmlGenerator, metadataProvider);
tagHelper.ViewContext = viewContext;
@ -227,7 +227,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
tagHelperOutputContent.ExpectedContent,
HtmlContentUtilities.HtmlContentToString(output.Content));
Assert.Equal(expectedPostContent, output.PostContent.GetContent());
Assert.False(output.SelfClosing);
Assert.Equal(TagMode.StartTagAndEndTag, output.TagMode);
Assert.Equal(expectedTagName, output.TagName);
}

View File

@ -407,7 +407,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
var output = new TagHelperOutput(expectedTagHelperOutput.TagName, originalAttributes)
{
SelfClosing = false,
TagMode = TagMode.StartTagAndEndTag
};
output.Content.SetContent(originalContent);
@ -475,7 +475,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
});
var output = new TagHelperOutput(originalTagName, originalAttributes)
{
SelfClosing = false,
TagMode = TagMode.StartTagAndEndTag,
};
output.PreContent.SetContent(originalPreContent);
output.Content.SetContent(originalContent);
@ -537,7 +537,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
var output = new TagHelperOutput(originalTagName, originalAttributes)
{
SelfClosing = false,
TagMode = TagMode.StartTagAndEndTag,
};
output.PreContent.SetContent(originalPreContent);
output.Content.SetContent(originalContent);

View File

@ -211,7 +211,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
});
var output = new TagHelperOutput(expectedTagName, originalAttributes)
{
SelfClosing = true,
TagMode = TagMode.SelfClosing,
};
output.PreContent.SetContent(expectedPreContent);
output.Content.SetContent(expectedContent);
@ -235,7 +235,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
await tagHelper.ProcessAsync(tagHelperContext, output);
// Assert
Assert.True(output.SelfClosing);
Assert.Equal(TagMode.SelfClosing, output.TagMode);
Assert.Equal(expectedAttributes, output.Attributes);
Assert.Equal(expectedPreContent, output.PreContent.GetContent());
Assert.Equal(expectedContent, output.Content.GetContent());
@ -298,7 +298,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
});
var output = new TagHelperOutput(expectedTagName, originalAttributes)
{
SelfClosing = true,
TagMode = TagMode.SelfClosing,
};
output.PreContent.SetContent(expectedPreContent);
output.Content.SetContent(expectedContent);
@ -331,7 +331,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
await tagHelper.ProcessAsync(tagHelperContext, output);
// Assert
Assert.True(output.SelfClosing);
Assert.Equal(TagMode.SelfClosing, output.TagMode);
Assert.Equal(expectedAttributes, output.Attributes);
Assert.Equal(expectedPreContent, output.PreContent.GetContent());
Assert.Equal(expectedContent, output.Content.GetContent());
@ -400,7 +400,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
});
var output = new TagHelperOutput(expectedTagName, originalAttributes)
{
SelfClosing = true
TagMode = TagMode.SelfClosing,
};
output.PreContent.SetContent(expectedPreContent);
output.Content.SetContent(expectedContent);
@ -434,7 +434,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
await tagHelper.ProcessAsync(tagHelperContext, output);
// Assert
Assert.True(output.SelfClosing);
Assert.Equal(TagMode.SelfClosing, output.TagMode);
Assert.Equal(expectedAttributes, output.Attributes);
Assert.Equal(expectedPreContent, output.PreContent.GetContent());
Assert.Equal(expectedContent, output.Content.GetContent());

View File

@ -139,7 +139,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
};
var output = new TagHelperOutput(expectedTagName, htmlAttributes)
{
SelfClosing = true,
TagMode = TagMode.SelfClosing,
};
output.Content.SetContent("original content");
@ -150,7 +150,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
await tagHelper.ProcessAsync(tagHelperContext, output);
// Assert
Assert.True(output.SelfClosing);
Assert.Equal(TagMode.SelfClosing, output.TagMode);
Assert.Equal(expectedAttributes, output.Attributes);
Assert.Equal(expectedContent, HtmlContentUtilities.HtmlContentToString(output.Content));
Assert.Equal(expectedTagName, output.TagName);

View File

@ -11,27 +11,27 @@
<h2>Image Tag Helper Test</h2>
<!-- Plain image tag -->
<img src="~/images/red.png" alt="Red block" title="&lt;the title>" />
<img src="~/images/red.png" alt="Red block" title="&lt;the title>">
<!-- Plain image tag with file version -->
<img src="~/images/red.png" alt="Red versioned" title="Red versioned" asp-append-version="true" />
<!-- Plain image tag with file version set to false -->
<img src="~/images/red.png" alt="Red explicitly not versioned" title="Red versioned" asp-append-version="false" />
<img src="~/images/red.png" alt="Red explicitly not versioned" title="Red versioned" asp-append-version="false">
<!-- Plain image tag with absolute path and file version -->
<img src="http://contoso.com/hello/world" alt="Absolute path versioned" asp-append-version="true" />
<img src="http://contoso.com/hello/world" alt="Absolute path versioned" asp-append-version="true">
<!-- Plain image tag with file version and path to file that does not exist -->
<img src="~/images/fake.png" alt="Path to non existing file" asp-append-version="true" />
<!-- Plain image tag with file version and path containing query string -->
<img src="~/images/red.png?abc=def" alt="Path with query string" asp-append-version="true" />
<img src="~/images/red.png?abc=def" alt="Path with query string" asp-append-version="true">
<!-- Plain image tag with file version and path containing fragment -->
<img src="~/images/red.png#abc" alt="Path with query string" asp-append-version="true" />
<!-- Plain image tag with file version and path linking to some action -->
<img src="/controller/action" alt="Path linking to some action" asp-append-version="true" />
<img src="/controller/action" alt="Path linking to some action" asp-append-version="true">
</body>
</html>

View File

@ -6,23 +6,23 @@
<html manifest="~/Person">
<head>
<base href="~/A+Really(Crazy),Url.Is:This/@Model.Name/Detail" target="_blank"/>
<base href="~/A+Really(Crazy),Url.Is:This/@Model.Name/Detail" target="_blank">
</head>
<body>
<dl itemscope itemid="~/Url"></dl>
<a href="~/Person">Person</a>
<area href="~/Person/@Model.Name" alt="Url stuff" />
<link href="~/Person/@Model.Name/CSS" rel="stylesheet" />
<area href="~/Person/@Model.Name" alt="Url stuff" >
<link href="~/Person/@Model.Name/CSS" rel="stylesheet">
<video poster=@dynamicUrl src='@dynamicUrl/@("video")' />
<audio src="@(dynamicUrl)">
<source src="~/Person" />
<track src="~/email@(dynamicUrl)" />
<source src="~/Person">
<track src="~/email@(dynamicUrl)">
</audio>
<embed src="~/email@dyanmicUrl" />
<embed src="~/email@dyanmicUrl">
<iframe src=@(dynamicUrl) />
<img src="~/@dynamicUrl" />
<img src="~/@dynamicUrl">
<script src="~/Person/@Model.Name/JS"></script>
<input src="~//Person" itemscope itemid="~/Person" formaction=@dynamicUrl />
<input src="~//Person" itemscope itemid="~/Person" formaction=@dynamicUrl>
<button formaction="~/\Person" />
<form action="~/~Person" />
<blockquote cite="~/Person" />

View File

@ -23,7 +23,7 @@ namespace TagHelpersWebSite.TagHelpers
Info.CopyrightYear.ToString(),
Info.Approved.ToString(),
Info.TagsToShow.ToString()));
output.SelfClosing = false;
output.TagMode = TagMode.StartTagAndEndTag;
}
}
}