Allow _ViewImports to remove default inherited tag helpers.

Additionally simplifying the contract for
ChunkInheritaceUtility\IChunkMerger so we don't have to understand the
order in which CodeTrees appear.
This commit is contained in:
Pranav K 2015-09-17 22:37:31 -07:00
parent b95dcd5f1c
commit f045c6792b
30 changed files with 300 additions and 313 deletions

View File

@ -3,7 +3,6 @@
using System; using System;
using System.Linq; using System.Linq;
using Microsoft.AspNet.Mvc.Razor.Host;
using Microsoft.AspNet.Razor.Chunks; using Microsoft.AspNet.Razor.Chunks;
namespace Microsoft.AspNet.Mvc.Razor.Directives namespace Microsoft.AspNet.Mvc.Razor.Directives
@ -15,33 +14,6 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
{ {
private const string TModelToken = "<TModel>"; private const string TModelToken = "<TModel>";
/// <summary>
/// Attempts to cast the passed in <see cref="Chunk"/> to type <typeparamref name="TChunk"/> and throws if the
/// cast fails.
/// </summary>
/// <typeparam name="TChunk">The type to cast to.</typeparam>
/// <param name="chunk">The chunk to cast.</param>
/// <returns>The <paramref name="chunk"/> cast to <typeparamref name="TChunk"/>.</returns>
/// <exception cref="ArgumentException"><paramref name="chunk"/> is not an instance of
/// <typeparamref name="TChunk"/>.</exception>
public static TChunk EnsureChunk<TChunk>(Chunk chunk)
where TChunk : Chunk
{
if (chunk == null)
{
throw new ArgumentNullException(nameof(chunk));
}
var chunkOfT = chunk as TChunk;
if (chunkOfT == null)
{
var message = Resources.FormatArgumentMustBeOfType(typeof(TChunk).FullName);
throw new ArgumentException(message, nameof(chunk));
}
return chunkOfT;
}
/// <summary> /// <summary>
/// Returns the <see cref="ModelChunk"/> used to determine the model name for the page generated /// Returns the <see cref="ModelChunk"/> used to determine the model name for the page generated
/// using the specified <paramref name="chunkTree"/> /// using the specified <paramref name="chunkTree"/>

View File

@ -63,6 +63,12 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
/// <param name="pagePath">The path of the page to locate inherited chunks for.</param> /// <param name="pagePath">The path of the page to locate inherited chunks for.</param>
/// <returns>A <see cref="IReadOnlyList{ChunkTreeResult}"/> of parsed <c>_ViewImports</c> /// <returns>A <see cref="IReadOnlyList{ChunkTreeResult}"/> of parsed <c>_ViewImports</c>
/// <see cref="ChunkTree"/>s and their file paths.</returns> /// <see cref="ChunkTree"/>s and their file paths.</returns>
/// <remarks>
/// The resulting <see cref="IReadOnlyList{ChunkTreeResult}"/> is ordered so that the result
/// for a _ViewImport closest to the application root appears first and the _ViewImport
/// closest to the page appears last i.e.
/// [ /_ViewImport, /Views/_ViewImport, /Views/Home/_ViewImport ]
/// </remarks>
public virtual IReadOnlyList<ChunkTreeResult> GetInheritedChunkTreeResults(string pagePath) public virtual IReadOnlyList<ChunkTreeResult> GetInheritedChunkTreeResults(string pagePath)
{ {
if (pagePath == null) if (pagePath == null)
@ -88,7 +94,7 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
if (chunkTree != null) if (chunkTree != null)
{ {
var result = new ChunkTreeResult(chunkTree, viewImportsPath); var result = new ChunkTreeResult(chunkTree, viewImportsPath);
inheritedChunkTreeResults.Add(result); inheritedChunkTreeResults.Insert(0, result);
} }
} }
@ -102,7 +108,7 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
/// <param name="chunkTree">The <see cref="ChunkTree"/> to merge in to.</param> /// <param name="chunkTree">The <see cref="ChunkTree"/> to merge in to.</param>
/// <param name="inheritedChunkTrees"><see cref="IReadOnlyList{ChunkTree}"/> inherited from <c>_ViewImports</c> /// <param name="inheritedChunkTrees"><see cref="IReadOnlyList{ChunkTree}"/> inherited from <c>_ViewImports</c>
/// files.</param> /// files.</param>
/// <param name="defaultModel">The list of chunks to merge.</param> /// <param name="defaultModel">The default model <see cref="Type"/> name.</param>
public void MergeInheritedChunkTrees( public void MergeInheritedChunkTrees(
ChunkTree chunkTree, ChunkTree chunkTree,
IReadOnlyList<ChunkTree> inheritedChunkTrees, IReadOnlyList<ChunkTree> inheritedChunkTrees,
@ -118,44 +124,34 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
throw new ArgumentNullException(nameof(inheritedChunkTrees)); throw new ArgumentNullException(nameof(inheritedChunkTrees));
} }
var mergerMappings = GetMergerMappings(chunkTree, defaultModel); var chunkMergers = GetChunkMergers(chunkTree, defaultModel);
IChunkMerger merger;
// We merge chunks into the ChunkTree in two passes. In the first pass, we traverse the ChunkTree visiting // We merge chunks into the ChunkTree in two passes. In the first pass, we traverse the ChunkTree visiting
// a mapped IChunkMerger for types that are registered. // a mapped IChunkMerger for types that are registered.
foreach (var chunk in chunkTree.Chunks) foreach (var chunk in chunkTree.Chunks)
{ {
if (mergerMappings.TryGetValue(chunk.GetType(), out merger)) foreach (var merger in chunkMergers)
{ {
merger.VisitChunk(chunk); merger.VisitChunk(chunk);
} }
} }
// In the second phase we invoke IChunkMerger.Merge for each chunk that has a mapped merger. var inheritedChunks = _defaultInheritedChunks.Concat(
// During this phase, the merger can either add to the ChunkTree or ignore the chunk based on the merging inheritedChunkTrees.SelectMany(tree => tree.Chunks)).ToArray();
// rules.
// Read the chunks outside in - that is chunks from the _ViewImports closest to the page get merged in first foreach (var merger in chunkMergers)
// and the furthest one last. This allows the merger to ignore a directive like @model that was previously
// seen.
var chunksToMerge = inheritedChunkTrees.SelectMany(tree => tree.Chunks)
.Concat(_defaultInheritedChunks);
foreach (var chunk in chunksToMerge)
{ {
if (mergerMappings.TryGetValue(chunk.GetType(), out merger)) merger.MergeInheritedChunks(chunkTree, inheritedChunks);
{
merger.Merge(chunkTree, chunk);
}
} }
} }
private static Dictionary<Type, IChunkMerger> GetMergerMappings(ChunkTree chunkTree, string defaultModel) private static IChunkMerger[] GetChunkMergers(ChunkTree chunkTree, string defaultModel)
{ {
var modelType = ChunkHelper.GetModelTypeName(chunkTree, defaultModel); var modelType = ChunkHelper.GetModelTypeName(chunkTree, defaultModel);
return new Dictionary<Type, IChunkMerger> return new IChunkMerger[]
{ {
{ typeof(UsingChunk), new UsingChunkMerger() }, new UsingChunkMerger(),
{ typeof(InjectChunk), new InjectChunkMerger(modelType) }, new InjectChunkMerger(modelType),
{ typeof(SetBaseTypeChunk), new SetBaseTypeChunkMerger(modelType) } new SetBaseTypeChunkMerger(modelType)
}; };
} }

View File

@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved. // Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using Microsoft.AspNet.Razor.Chunks; using Microsoft.AspNet.Razor.Chunks;
namespace Microsoft.AspNet.Mvc.Razor.Directives namespace Microsoft.AspNet.Mvc.Razor.Directives
@ -20,7 +21,7 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
/// Merges an inherited <see cref="Chunk"/> into the <see cref="ChunkTree"/>. /// Merges an inherited <see cref="Chunk"/> into the <see cref="ChunkTree"/>.
/// </summary> /// </summary>
/// <param name="ChunkTree">The <see cref="ChunkTree"/> to merge into.</param> /// <param name="ChunkTree">The <see cref="ChunkTree"/> to merge into.</param>
/// <param name="chunk">The <see cref="Chunk"/> to merge.</param> /// <param name="inheritedChunks">The <see cref="IReadOnlyList{Chunk}"/>s to merge.</param>
void Merge(ChunkTree chunkTree, Chunk chunk); void MergeInheritedChunks(ChunkTree chunkTree, IReadOnlyList<Chunk> inheritedChunks);
} }
} }

View File

@ -3,6 +3,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNet.Razor.Chunks; using Microsoft.AspNet.Razor.Chunks;
namespace Microsoft.AspNet.Mvc.Razor.Directives namespace Microsoft.AspNet.Mvc.Razor.Directives
@ -37,29 +38,35 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
throw new ArgumentNullException(nameof(chunk)); throw new ArgumentNullException(nameof(chunk));
} }
var injectChunk = ChunkHelper.EnsureChunk<InjectChunk>(chunk); var injectChunk = chunk as InjectChunk;
injectChunk.TypeName = ChunkHelper.ReplaceTModel(injectChunk.TypeName, _modelType); if (injectChunk != null)
_addedMemberNames.Add(injectChunk.MemberName); {
injectChunk.TypeName = ChunkHelper.ReplaceTModel(injectChunk.TypeName, _modelType);
_addedMemberNames.Add(injectChunk.MemberName);
}
} }
/// <inheritdoc /> /// <inheritdoc />
public void Merge(ChunkTree chunkTree, Chunk chunk) public void MergeInheritedChunks(ChunkTree chunkTree, IReadOnlyList<Chunk> inheritedChunks)
{ {
if (chunkTree == null) if (chunkTree == null)
{ {
throw new ArgumentNullException(nameof(chunkTree)); throw new ArgumentNullException(nameof(chunkTree));
} }
if (chunk == null) if (inheritedChunks == null)
{ {
throw new ArgumentNullException(nameof(chunk)); throw new ArgumentNullException(nameof(inheritedChunks));
} }
var injectChunk = ChunkHelper.EnsureChunk<InjectChunk>(chunk); for (var i = inheritedChunks.Count - 1; i >= 0; i--)
if (!_addedMemberNames.Contains(injectChunk.MemberName))
{ {
_addedMemberNames.Add(injectChunk.MemberName); var injectChunk = inheritedChunks[i] as InjectChunk;
chunkTree.Chunks.Add(TransformChunk(injectChunk)); if (injectChunk != null &&
_addedMemberNames.Add(injectChunk.MemberName))
{
chunkTree.Chunks.Add(TransformChunk(injectChunk));
}
} }
} }

View File

@ -2,6 +2,8 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNet.Razor.Chunks; using Microsoft.AspNet.Razor.Chunks;
namespace Microsoft.AspNet.Mvc.Razor.Directives namespace Microsoft.AspNet.Mvc.Razor.Directives
@ -31,32 +33,38 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
throw new ArgumentNullException(nameof(chunk)); throw new ArgumentNullException(nameof(chunk));
} }
var setBaseTypeChunk = ChunkHelper.EnsureChunk<SetBaseTypeChunk>(chunk); var setBaseTypeChunk = chunk as SetBaseTypeChunk;
setBaseTypeChunk.TypeName = ChunkHelper.ReplaceTModel(setBaseTypeChunk.TypeName, _modelType); if (setBaseTypeChunk != null)
_isBaseTypeSet = true; {
setBaseTypeChunk.TypeName = ChunkHelper.ReplaceTModel(setBaseTypeChunk.TypeName, _modelType);
_isBaseTypeSet = true;
}
} }
/// <inheritdoc /> /// <inheritdoc />
public void Merge(ChunkTree chunkTree, Chunk chunk) public void MergeInheritedChunks(ChunkTree chunkTree, IReadOnlyList<Chunk> inheritedChunks)
{ {
if (chunkTree == null) if (chunkTree == null)
{ {
throw new ArgumentNullException(nameof(chunkTree)); throw new ArgumentNullException(nameof(chunkTree));
} }
if (chunk == null) if (inheritedChunks == null)
{ {
throw new ArgumentNullException(nameof(chunk)); throw new ArgumentNullException(nameof(inheritedChunks));
} }
if (!_isBaseTypeSet) if (!_isBaseTypeSet)
{ {
var baseTypeChunk = ChunkHelper.EnsureChunk<SetBaseTypeChunk>(chunk); for (var i = inheritedChunks.Count - 1; i >= 0; i--)
{
// The base type can set exactly once and the first one we encounter wins. var baseTypeChunk = inheritedChunks[i] as SetBaseTypeChunk;
_isBaseTypeSet = true; if (baseTypeChunk != null)
{
chunkTree.Chunks.Add(TransformChunk(baseTypeChunk)); chunkTree.Chunks.Add(TransformChunk(baseTypeChunk));
break;
}
}
} }
} }

View File

@ -3,6 +3,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNet.Razor.Chunks; using Microsoft.AspNet.Razor.Chunks;
namespace Microsoft.AspNet.Mvc.Razor.Directives namespace Microsoft.AspNet.Mvc.Razor.Directives
@ -22,29 +23,33 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
throw new ArgumentNullException(nameof(chunk)); throw new ArgumentNullException(nameof(chunk));
} }
var namespaceChunk = ChunkHelper.EnsureChunk<UsingChunk>(chunk); var namespaceChunk = chunk as UsingChunk;
_currentUsings.Add(namespaceChunk.Namespace); if (namespaceChunk != null)
{
_currentUsings.Add(namespaceChunk.Namespace);
}
} }
/// <inheritdoc /> /// <inheritdoc />
public void Merge(ChunkTree chunkTree, Chunk chunk) public void MergeInheritedChunks(ChunkTree chunkTree, IReadOnlyList<Chunk> inheritedChunks)
{ {
if (chunkTree == null) if (chunkTree == null)
{ {
throw new ArgumentNullException(nameof(chunkTree)); throw new ArgumentNullException(nameof(chunkTree));
} }
if (chunk == null) if (inheritedChunks == null)
{ {
throw new ArgumentNullException(nameof(chunk)); throw new ArgumentNullException(nameof(inheritedChunks));
} }
var namespaceChunk = ChunkHelper.EnsureChunk<UsingChunk>(chunk); var namespaceChunks = inheritedChunks.OfType<UsingChunk>();
foreach (var namespaceChunk in namespaceChunks)
if (!_currentUsings.Contains(namespaceChunk.Namespace))
{ {
_currentUsings.Add(namespaceChunk.Namespace); if (_currentUsings.Add(namespaceChunk.Namespace))
chunkTree.Chunks.Add(namespaceChunk); {
chunkTree.Chunks.Add(namespaceChunk);
}
} }
} }
} }

View File

@ -117,15 +117,8 @@ namespace Microsoft.AspNet.Mvc.Razor
{ {
var descriptors = new List<TagHelperDirectiveDescriptor>(); var descriptors = new List<TagHelperDirectiveDescriptor>();
// For tag helpers, the @removeTagHelper only applies tag helpers that were added prior to it. var inheritedChunks = defaultInheritedChunks.Concat(inheritedChunkTrees.SelectMany(tree => tree.Chunks));
// Consequently we must visit tag helpers outside-in - furthest _ViewImports first and nearest one last. foreach (var chunk in inheritedChunks)
// This is different from the behavior of chunk merging where we visit the nearest one first and ignore
// chunks that were previously visited.
var chunksFromViewImports = inheritedChunkTrees
.Reverse()
.SelectMany(tree => tree.Chunks);
var chunksInOrder = defaultInheritedChunks.Concat(chunksFromViewImports);
foreach (var chunk in chunksInOrder)
{ {
// All TagHelperDirectiveDescriptors created here have undefined source locations because the source // All TagHelperDirectiveDescriptors created here have undefined source locations because the source
// that created them is not in the same file. // that created them is not in the same file.

View File

@ -26,22 +26,6 @@ namespace Microsoft.AspNet.Mvc.Razor.Host
return GetString("ArgumentCannotBeNullOrEmpy"); return GetString("ArgumentCannotBeNullOrEmpy");
} }
/// <summary>
/// Argument must be an instance of '{0}'.
/// </summary>
internal static string ArgumentMustBeOfType
{
get { return GetString("ArgumentMustBeOfType"); }
}
/// <summary>
/// Argument must be an instance of '{0}'.
/// </summary>
internal static string FormatArgumentMustBeOfType(object p0)
{
return string.Format(CultureInfo.CurrentCulture, GetString("ArgumentMustBeOfType"), p0);
}
/// <summary> /// <summary>
/// The 'inherits' keyword is not allowed when a '{0}' keyword is used. /// The 'inherits' keyword is not allowed when a '{0}' keyword is used.
/// </summary> /// </summary>

View File

@ -120,9 +120,6 @@
<data name="ArgumentCannotBeNullOrEmpy" xml:space="preserve"> <data name="ArgumentCannotBeNullOrEmpy" xml:space="preserve">
<value>Value cannot be null or empty.</value> <value>Value cannot be null or empty.</value>
</data> </data>
<data name="ArgumentMustBeOfType" xml:space="preserve">
<value>Argument must be an instance of '{0}'.</value>
</data>
<data name="MvcRazorCodeParser_CannotHaveModelAndInheritsKeyword" xml:space="preserve"> <data name="MvcRazorCodeParser_CannotHaveModelAndInheritsKeyword" xml:space="preserve">
<value>The 'inherits' keyword is not allowed when a '{0}' keyword is used.</value> <value>The 'inherits' keyword is not allowed when a '{0}' keyword is used.</value>
</data> </data>

View File

@ -152,6 +152,19 @@ page:<root>root-content</root>"
Assert.Equal(expected, result.Trim(), ignoreLineEndingDifferences: true); Assert.Equal(expected, result.Trim(), ignoreLineEndingDifferences: true);
} }
[Fact]
public async Task DefaultInheritedTagsCanBeRemoved()
{
// Arrange
var expected =
@"<a href=""~/VirtualPath"">Virtual path</a>";
var result = await Client.GetStringAsync("RemoveDefaultInheritedTagHelpers");
// Assert
Assert.Equal(expected, result.Trim(), ignoreLineEndingDifferences: true);
}
[Fact] [Fact]
public async Task ViewsWithModelMetadataAttributes_CanRenderForm() public async Task ViewsWithModelMetadataAttributes_CanRenderForm()
{ {

View File

@ -40,28 +40,6 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
// Assert // Assert
Assert.Collection(chunkTreeResults, Assert.Collection(chunkTreeResults,
chunkTreeResult =>
{
var viewImportsPath = PlatformNormalizer.NormalizePath(@"Views\home\_ViewImports.cshtml");
Assert.Collection(chunkTreeResult.ChunkTree.Chunks,
chunk =>
{
Assert.IsType<LiteralChunk>(chunk);
Assert.Equal(viewImportsPath, chunk.Start.FilePath);
},
chunk =>
{
var usingChunk = Assert.IsType<UsingChunk>(chunk);
Assert.Equal("MyNamespace", usingChunk.Namespace);
Assert.Equal(viewImportsPath, chunk.Start.FilePath);
},
chunk =>
{
Assert.IsType<LiteralChunk>(chunk);
Assert.Equal(viewImportsPath, chunk.Start.FilePath);
});
Assert.Equal(viewImportsPath, chunkTreeResult.FilePath);
},
chunkTreeResult => chunkTreeResult =>
{ {
var viewImportsPath = PlatformNormalizer.NormalizePath(@"Views\_ViewImports.cshtml"); var viewImportsPath = PlatformNormalizer.NormalizePath(@"Views\_ViewImports.cshtml");
@ -88,7 +66,6 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
var setBaseTypeChunk = Assert.IsType<SetBaseTypeChunk>(chunk); var setBaseTypeChunk = Assert.IsType<SetBaseTypeChunk>(chunk);
Assert.Equal("MyBaseType", setBaseTypeChunk.TypeName); Assert.Equal("MyBaseType", setBaseTypeChunk.TypeName);
Assert.Equal(viewImportsPath, chunk.Start.FilePath); Assert.Equal(viewImportsPath, chunk.Start.FilePath);
}, },
chunk => chunk =>
{ {
@ -106,6 +83,28 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
Assert.Equal(viewImportsPath, chunk.Start.FilePath); Assert.Equal(viewImportsPath, chunk.Start.FilePath);
}); });
Assert.Equal(viewImportsPath, chunkTreeResult.FilePath); Assert.Equal(viewImportsPath, chunkTreeResult.FilePath);
},
chunkTreeResult =>
{
var viewImportsPath = PlatformNormalizer.NormalizePath(@"Views\home\_ViewImports.cshtml");
Assert.Collection(chunkTreeResult.ChunkTree.Chunks,
chunk =>
{
Assert.IsType<LiteralChunk>(chunk);
Assert.Equal(viewImportsPath, chunk.Start.FilePath);
},
chunk =>
{
var usingChunk = Assert.IsType<UsingChunk>(chunk);
Assert.Equal("MyNamespace", usingChunk.Namespace);
Assert.Equal(viewImportsPath, chunk.Start.FilePath);
},
chunk =>
{
Assert.IsType<LiteralChunk>(chunk);
Assert.Equal(viewImportsPath, chunk.Start.FilePath);
});
Assert.Equal(viewImportsPath, chunkTreeResult.FilePath);
}); });
} }
@ -173,10 +172,10 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
utility.MergeInheritedChunkTrees(chunkTree, inheritedChunkTrees, "dynamic"); utility.MergeInheritedChunkTrees(chunkTree, inheritedChunkTrees, "dynamic");
// Assert // Assert
Assert.Equal(3, chunkTree.Chunks.Count); Assert.Collection(chunkTree.Chunks,
Assert.Same(inheritedChunkTrees[0].Chunks[0], chunkTree.Chunks[0]); chunk => Assert.Same(defaultChunks[1], chunk),
Assert.Same(inheritedChunkTrees[1].Chunks[0], chunkTree.Chunks[1]); chunk => Assert.Same(inheritedChunkTrees[0].Chunks[0], chunk),
Assert.Same(defaultChunks[0], chunkTree.Chunks[2]); chunk => Assert.Same(defaultChunks[0], chunk));
} }
} }
} }

View File

@ -2,24 +2,12 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Razor.Chunks; using Microsoft.AspNet.Razor.Chunks;
using Microsoft.AspNet.Testing;
using Xunit; using Xunit;
namespace Microsoft.AspNet.Mvc.Razor.Directives namespace Microsoft.AspNet.Mvc.Razor.Directives
{ {
public class InjectChunkMergerTest public class InjectChunkMergerTest
{ {
[Fact]
public void Visit_ThrowsIfThePassedInChunkIsNotAInjectChunk()
{
// Arrange
var expected = "Argument must be an instance of 'Microsoft.AspNet.Mvc.Razor.InjectChunk'.";
var merger = new InjectChunkMerger("dynamic");
// Act and Assert
ExceptionAssert.ThrowsArgument(() => merger.VisitChunk(new LiteralChunk()), "chunk", expected);
}
[Theory] [Theory]
[InlineData("MyApp.TestHelper<TModel>", "MyApp.TestHelper<Person>")] [InlineData("MyApp.TestHelper<TModel>", "MyApp.TestHelper<Person>")]
[InlineData("TestBaseType", "TestBaseType")] [InlineData("TestBaseType", "TestBaseType")]
@ -37,17 +25,6 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
Assert.Equal("TestHelper", chunk.MemberName); Assert.Equal("TestHelper", chunk.MemberName);
} }
[Fact]
public void Merge_ThrowsIfThePassedInChunkIsNotAInjectChunk()
{
// Arrange
var expected = "Argument must be an instance of 'Microsoft.AspNet.Mvc.Razor.InjectChunk'.";
var merger = new InjectChunkMerger("dynamic");
// Act and Assert
ExceptionAssert.ThrowsArgument(() => merger.Merge(new ChunkTree(), new LiteralChunk()), "chunk", expected);
}
[Fact] [Fact]
public void Merge_AddsChunkIfChunkWithMatchingPropertyNameWasNotVisitedInChunkTree() public void Merge_AddsChunkIfChunkWithMatchingPropertyNameWasNotVisitedInChunkTree()
{ {
@ -56,9 +33,13 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
var expectedProperty = "MyHelper"; var expectedProperty = "MyHelper";
var merger = new InjectChunkMerger("dynamic"); var merger = new InjectChunkMerger("dynamic");
var chunkTree = new ChunkTree(); var chunkTree = new ChunkTree();
var inheritedChunks = new[]
{
new InjectChunk(expectedType, expectedProperty)
};
// Act // Act
merger.Merge(chunkTree, new InjectChunk(expectedType, expectedProperty)); merger.MergeInheritedChunks(chunkTree, inheritedChunks);
// Assert // Assert
var chunk = Assert.Single(chunkTree.Chunks); var chunk = Assert.Single(chunkTree.Chunks);
@ -73,10 +54,14 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
// Arrange // Arrange
var merger = new InjectChunkMerger("dynamic"); var merger = new InjectChunkMerger("dynamic");
var chunkTree = new ChunkTree(); var chunkTree = new ChunkTree();
var inheritedChunks = new[]
{
new InjectChunk("MyTypeB", "MyProperty")
};
// Act // Act
merger.VisitChunk(new InjectChunk("MyTypeA", "MyProperty")); merger.VisitChunk(new InjectChunk("MyTypeA", "MyProperty"));
merger.Merge(chunkTree, new InjectChunk("MyTypeB", "MyProperty")); merger.MergeInheritedChunks(chunkTree, inheritedChunks);
// Assert // Assert
Assert.Empty(chunkTree.Chunks); Assert.Empty(chunkTree.Chunks);
@ -88,11 +73,15 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
// Arrange // Arrange
var merger = new InjectChunkMerger("dynamic"); var merger = new InjectChunkMerger("dynamic");
var chunkTree = new ChunkTree(); var chunkTree = new ChunkTree();
var inheritedChunks = new[]
{
new InjectChunk("MyTypeB", "different-property"),
new InjectChunk("MyType", "myproperty"),
};
// Act // Act
merger.VisitChunk(new InjectChunk("MyType", "MyProperty")); merger.VisitChunk(new InjectChunk("MyType", "MyProperty"));
merger.Merge(chunkTree, new InjectChunk("MyType", "myproperty")); merger.MergeInheritedChunks(chunkTree, inheritedChunks);
merger.Merge(chunkTree, new InjectChunk("MyTypeB", "different-property"));
// Assert // Assert
Assert.Equal(2, chunkTree.Chunks.Count); Assert.Equal(2, chunkTree.Chunks.Count);
@ -111,9 +100,13 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
// Arrange // Arrange
var merger = new InjectChunkMerger("dynamic"); var merger = new InjectChunkMerger("dynamic");
var chunkTree = new ChunkTree(); var chunkTree = new ChunkTree();
var inheritedChunks = new[]
{
new InjectChunk("MyHelper<TModel>", "MyProperty")
};
// Act // Act
merger.Merge(chunkTree, new InjectChunk("MyHelper<TModel>", "MyProperty")); merger.MergeInheritedChunks(chunkTree, inheritedChunks);
// Assert // Assert
var chunk = Assert.Single(chunkTree.Chunks); var chunk = Assert.Single(chunkTree.Chunks);
@ -128,9 +121,13 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
// Arrange // Arrange
var merger = new InjectChunkMerger("MyTestModel2"); var merger = new InjectChunkMerger("MyTestModel2");
var chunkTree = new ChunkTree(); var chunkTree = new ChunkTree();
var inheritedChunks = new[]
{
new InjectChunk("MyHelper<TModel>", "MyProperty")
};
// Act // Act
merger.Merge(chunkTree, new InjectChunk("MyHelper<TModel>", "MyProperty")); merger.MergeInheritedChunks(chunkTree, inheritedChunks);
// Assert // Assert
var chunk = Assert.Single(chunkTree.Chunks); var chunk = Assert.Single(chunkTree.Chunks);
@ -140,21 +137,36 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
} }
[Fact] [Fact]
public void Merge_IgnoresChunkIfChunkWithMatchingPropertyNameWasPreviouslyMerged() public void Merge_UsesTheLastInjectChunkOfAPropertyName()
{ {
// Arrange // Arrange
var merger = new InjectChunkMerger("dynamic"); var merger = new InjectChunkMerger("dynamic");
var chunkTree = new ChunkTree(); var chunkTree = new ChunkTree();
var inheritedChunks = new Chunk[]
{
new LiteralChunk(),
new InjectChunk("SomeOtherType", "Property"),
new InjectChunk("DifferentPropertyType", "DifferentProperty"),
new InjectChunk("SomeType", "Property"),
};
// Act // Act
merger.Merge(chunkTree, new InjectChunk("SomeType", "Property")); merger.MergeInheritedChunks(chunkTree, inheritedChunks);
merger.Merge(chunkTree, new InjectChunk("SomeOtherType", "Property"));
// Assert // Assert
var chunk = Assert.Single(chunkTree.Chunks); Assert.Collection(chunkTree.Chunks,
var injectChunk = Assert.IsType<InjectChunk>(chunk); chunk =>
Assert.Equal("SomeType", injectChunk.TypeName); {
Assert.Equal("Property", injectChunk.MemberName); var injectChunk = Assert.IsType<InjectChunk>(chunk);
Assert.Equal("SomeType", injectChunk.TypeName);
Assert.Equal("Property", injectChunk.MemberName);
},
chunk =>
{
var injectChunk = Assert.IsType<InjectChunk>(chunk);
Assert.Equal("DifferentPropertyType", injectChunk.TypeName);
Assert.Equal("DifferentProperty", injectChunk.MemberName);
});
} }
} }
} }

View File

@ -2,25 +2,12 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Razor.Chunks; using Microsoft.AspNet.Razor.Chunks;
using Microsoft.AspNet.Testing;
using Xunit; using Xunit;
namespace Microsoft.AspNet.Mvc.Razor.Directives namespace Microsoft.AspNet.Mvc.Razor.Directives
{ {
public class SetBaseTypeChunkMergerTest public class SetBaseTypeChunkMergerTest
{ {
[Fact]
public void Visit_ThrowsIfThePassedInChunkIsNotASetBaseTypeChunk()
{
// Arrange
var expected = "Argument must be an instance of " +
"'Microsoft.AspNet.Razor.Chunks.SetBaseTypeChunk'.";
var merger = new SetBaseTypeChunkMerger("dynamic");
// Act and Assert
ExceptionAssert.ThrowsArgument(() => merger.VisitChunk(new LiteralChunk()), "chunk", expected);
}
[Theory] [Theory]
[InlineData("MyApp.BaseType<TModel>", "MyApp.BaseType<Person>")] [InlineData("MyApp.BaseType<TModel>", "MyApp.BaseType<Person>")]
[InlineData("TestBaseType", "TestBaseType")] [InlineData("TestBaseType", "TestBaseType")]
@ -40,18 +27,6 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
Assert.Equal(expectedValue, chunk.TypeName); Assert.Equal(expectedValue, chunk.TypeName);
} }
[Fact]
public void Merge_ThrowsIfThePassedInChunkIsNotASetBaseTypeChunk()
{
// Arrange
var expected = "Argument must be an instance of " +
"'Microsoft.AspNet.Razor.Chunks.SetBaseTypeChunk'.";
var merger = new SetBaseTypeChunkMerger("dynamic");
// Act and Assert
ExceptionAssert.ThrowsArgument(() => merger.Merge(new ChunkTree(), new LiteralChunk()), "chunk", expected);
}
[Fact] [Fact]
public void Merge_SetsBaseTypeIfItHasNotBeenSetInChunkTree() public void Merge_SetsBaseTypeIfItHasNotBeenSetInChunkTree()
{ {
@ -59,9 +34,13 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
var expected = "MyApp.Razor.MyBaseType"; var expected = "MyApp.Razor.MyBaseType";
var merger = new SetBaseTypeChunkMerger("dynamic"); var merger = new SetBaseTypeChunkMerger("dynamic");
var chunkTree = new ChunkTree(); var chunkTree = new ChunkTree();
var inheritedChunks = new[]
{
new SetBaseTypeChunk { TypeName = expected }
};
// Act // Act
merger.Merge(chunkTree, new SetBaseTypeChunk { TypeName = expected }); merger.MergeInheritedChunks(chunkTree, inheritedChunks);
// Assert // Assert
var chunk = Assert.Single(chunkTree.Chunks); var chunk = Assert.Single(chunkTree.Chunks);
@ -75,25 +54,34 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
// Arrange // Arrange
var merger = new SetBaseTypeChunkMerger("dynamic"); var merger = new SetBaseTypeChunkMerger("dynamic");
var chunkTree = new ChunkTree(); var chunkTree = new ChunkTree();
var inheritedChunks = new[]
{
new SetBaseTypeChunk { TypeName = "MyBaseType2" }
};
// Act // Act
merger.VisitChunk(new SetBaseTypeChunk { TypeName = "MyBaseType1" }); merger.VisitChunk(new SetBaseTypeChunk { TypeName = "MyBaseType1" });
merger.Merge(chunkTree, new SetBaseTypeChunk { TypeName = "MyBaseType2" }); merger.MergeInheritedChunks(chunkTree, inheritedChunks);
// Assert // Assert
Assert.Empty(chunkTree.Chunks); Assert.Empty(chunkTree.Chunks);
} }
[Fact] [Fact]
public void Merge_IgnoresSetBaseTypeChunksIfSetBaseTypeWasPreviouslyMerged() public void Merge_PicksLastBaseTypeChunkFromChunkTree()
{ {
// Arrange // Arrange
var merger = new SetBaseTypeChunkMerger("dynamic"); var merger = new SetBaseTypeChunkMerger("dynamic");
var chunkTree = new ChunkTree(); var chunkTree = new ChunkTree();
var inheritedChunks = new Chunk[]
{
new SetBaseTypeChunk { TypeName = "MyBase2" },
new LiteralChunk(),
new SetBaseTypeChunk { TypeName = "MyBase1" },
};
// Act // Act
merger.Merge(chunkTree, new SetBaseTypeChunk { TypeName = "MyBase1" }); merger.MergeInheritedChunks(chunkTree, inheritedChunks);
merger.Merge(chunkTree, new SetBaseTypeChunk { TypeName = "MyBase2" });
// Assert // Assert
var chunk = Assert.Single(chunkTree.Chunks); var chunk = Assert.Single(chunkTree.Chunks);

View File

@ -9,28 +9,6 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
{ {
public class UsingChunkMergerTest public class UsingChunkMergerTest
{ {
[Fact]
public void Visit_ThrowsIfThePassedInChunkIsNotAUsingChunk()
{
// Arrange
var expected = "Argument must be an instance of 'Microsoft.AspNet.Razor.Chunks.UsingChunk'.";
var merger = new UsingChunkMerger();
// Act and Assert
ExceptionAssert.ThrowsArgument(() => merger.VisitChunk(new LiteralChunk()), "chunk", expected);
}
[Fact]
public void Merge_ThrowsIfThePassedInChunkIsNotAUsingChunk()
{
// Arrange
var expected = "Argument must be an instance of 'Microsoft.AspNet.Razor.Chunks.UsingChunk'.";
var merger = new UsingChunkMerger();
// Act and Assert
ExceptionAssert.ThrowsArgument(() => merger.Merge(new ChunkTree(), new LiteralChunk()), "chunk", expected);
}
[Fact] [Fact]
public void Merge_AddsNamespacesThatHaveNotBeenVisitedInChunkTree() public void Merge_AddsNamespacesThatHaveNotBeenVisitedInChunkTree()
{ {
@ -38,10 +16,14 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
var expected = "MyApp.Models"; var expected = "MyApp.Models";
var merger = new UsingChunkMerger(); var merger = new UsingChunkMerger();
var chunkTree = new ChunkTree(); var chunkTree = new ChunkTree();
var inheritedChunks = new Chunk[]
{
new UsingChunk { Namespace = expected },
};
// Act // Act
merger.VisitChunk(new UsingChunk { Namespace = "Microsoft.AspNet.Mvc" }); merger.VisitChunk(new UsingChunk { Namespace = "Microsoft.AspNet.Mvc" });
merger.Merge(chunkTree, new UsingChunk { Namespace = expected }); merger.MergeInheritedChunks(chunkTree, inheritedChunks);
// Assert // Assert
var chunk = Assert.Single(chunkTree.Chunks); var chunk = Assert.Single(chunkTree.Chunks);
@ -55,26 +37,36 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
// Arrange // Arrange
var merger = new UsingChunkMerger(); var merger = new UsingChunkMerger();
var chunkTree = new ChunkTree(); var chunkTree = new ChunkTree();
var inheritedChunks = new Chunk[]
{
new UsingChunk { Namespace = "Microsoft.AspNet.Mvc" },
new InjectChunk("Foo", "Bar")
};
// Act // Act
merger.VisitChunk(new UsingChunk { Namespace = "Microsoft.AspNet.Mvc" }); merger.VisitChunk(new UsingChunk { Namespace = "Microsoft.AspNet.Mvc" });
merger.Merge(chunkTree, new UsingChunk { Namespace = "Microsoft.AspNet.Mvc" }); merger.MergeInheritedChunks(chunkTree, inheritedChunks);
// Assert // Assert
Assert.Empty(chunkTree.Chunks); Assert.Empty(chunkTree.Chunks);
} }
[Fact] [Fact]
public void Merge_IgnoresNamespacesThatHaveBeenVisitedDuringMerge() public void Merge_DoesNotAddMoreThanOneInstanceOfTheSameInheritedNamespace()
{ {
// Arrange // Arrange
var merger = new UsingChunkMerger(); var merger = new UsingChunkMerger();
var chunkTree = new ChunkTree(); var chunkTree = new ChunkTree();
var inheritedChunks = new Chunk[]
{
new LiteralChunk(),
new UsingChunk { Namespace = "Microsoft.AspNet.Mvc" },
new UsingChunk { Namespace = "Microsoft.AspNet.Mvc" },
new UsingChunk { Namespace = "Microsoft.AspNet.Mvc.Razor" }
};
// Act // Act
merger.Merge(chunkTree, new UsingChunk { Namespace = "Microsoft.AspNet.Mvc" }); merger.MergeInheritedChunks(chunkTree, inheritedChunks);
merger.Merge(chunkTree, new UsingChunk { Namespace = "Microsoft.AspNet.Mvc" });
merger.Merge(chunkTree, new UsingChunk { Namespace = "Microsoft.AspNet.Mvc.Razor" });
// Assert // Assert
Assert.Equal(2, chunkTree.Chunks.Count); Assert.Equal(2, chunkTree.Chunks.Count);
@ -85,15 +77,19 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
} }
[Fact] [Fact]
public void Merge_MacthesNamespacesInCaseSensitiveManner() public void Merge_MatchesNamespacesInCaseSensitiveManner()
{ {
// Arrange // Arrange
var merger = new UsingChunkMerger(); var merger = new UsingChunkMerger();
var chunkTree = new ChunkTree(); var chunkTree = new ChunkTree();
var inheritedChunks = new[]
{
new UsingChunk { Namespace = "Microsoft.AspNet.Mvc" },
new UsingChunk { Namespace = "Microsoft.AspNet.mvc" }
};
// Act // Act
merger.Merge(chunkTree, new UsingChunk { Namespace = "Microsoft.AspNet.Mvc" }); merger.MergeInheritedChunks(chunkTree, inheritedChunks);
merger.Merge(chunkTree, new UsingChunk { Namespace = "Microsoft.AspNet.mvc" });
// Assert // Assert
Assert.Equal(2, chunkTree.Chunks.Count); Assert.Equal(2, chunkTree.Chunks.Count);

View File

@ -5,7 +5,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Microsoft.AspNet.Mvc.Rendering; using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Mvc.ViewFeatures;
using Microsoft.AspNet.Razor; using Microsoft.AspNet.Razor;
using Microsoft.AspNet.Razor.Chunks; using Microsoft.AspNet.Razor.Chunks;
using Microsoft.AspNet.Razor.Parser; using Microsoft.AspNet.Razor.Parser;
@ -66,8 +65,8 @@ namespace Microsoft.AspNet.Mvc.Razor
{ {
new[] new[]
{ {
CreateChunkTree(new TagHelperPrefixDirectiveChunk { Prefix = "THP1" }),
CreateChunkTree(new TagHelperPrefixDirectiveChunk { Prefix = "THP2" }), CreateChunkTree(new TagHelperPrefixDirectiveChunk { Prefix = "THP2" }),
CreateChunkTree(new TagHelperPrefixDirectiveChunk { Prefix = "THP1" }),
}, },
new[] { CreateDirectiveDescriptor("THP1", TagHelperDirectiveType.TagHelperPrefix) } new[] { CreateDirectiveDescriptor("THP1", TagHelperDirectiveType.TagHelperPrefix) }
}, },
@ -89,10 +88,10 @@ namespace Microsoft.AspNet.Mvc.Razor
{ {
new[] new[]
{ {
CreateChunkTree(new RemoveTagHelperChunk { LookupText = "RTH" }),
CreateChunkTree( CreateChunkTree(
new LiteralChunk { Text = "Hello world" }, new LiteralChunk { Text = "Hello world" },
new AddTagHelperChunk { LookupText = "ATH" }), new AddTagHelperChunk { LookupText = "ATH" }),
CreateChunkTree(new RemoveTagHelperChunk { LookupText = "RTH" })
}, },
new[] new[]
{ {
@ -103,11 +102,11 @@ namespace Microsoft.AspNet.Mvc.Razor
{ {
new[] new[]
{ {
CreateChunkTree(new TagHelperPrefixDirectiveChunk { Prefix = "THP" }), CreateChunkTree(new RemoveTagHelperChunk { LookupText = "RTH" }),
CreateChunkTree( CreateChunkTree(
new LiteralChunk { Text = "Hello world" }, new LiteralChunk { Text = "Hello world" },
new AddTagHelperChunk { LookupText = "ATH" }), new AddTagHelperChunk { LookupText = "ATH" }),
CreateChunkTree(new RemoveTagHelperChunk { LookupText = "RTH" }) CreateChunkTree(new TagHelperPrefixDirectiveChunk { Prefix = "THP" }),
}, },
new[] new[]
{ {
@ -119,10 +118,10 @@ namespace Microsoft.AspNet.Mvc.Razor
{ {
new[] new[]
{ {
CreateChunkTree(new TagHelperPrefixDirectiveChunk { Prefix = "THP1" }),
CreateChunkTree(new AddTagHelperChunk { LookupText = "ATH" }),
CreateChunkTree(new RemoveTagHelperChunk { LookupText = "RTH" }),
CreateChunkTree(new TagHelperPrefixDirectiveChunk { Prefix = "THP2" }), CreateChunkTree(new TagHelperPrefixDirectiveChunk { Prefix = "THP2" }),
CreateChunkTree(new RemoveTagHelperChunk { LookupText = "RTH" }),
CreateChunkTree(new AddTagHelperChunk { LookupText = "ATH" }),
CreateChunkTree(new TagHelperPrefixDirectiveChunk { Prefix = "THP1" }),
}, },
new[] new[]
{ {

View File

@ -16,13 +16,13 @@ namespace Asp
} }
#line hidden #line hidden
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.Rendering.IHtmlHelper<dynamic> Html { get; private set; } public Microsoft.AspNet.Mvc.IUrlHelper Url { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.Rendering.IJsonHelper Json { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.IViewComponentHelper Component { get; private set; } public Microsoft.AspNet.Mvc.IViewComponentHelper Component { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.IUrlHelper Url { get; private set; } public Microsoft.AspNet.Mvc.Rendering.IJsonHelper Json { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.Rendering.IHtmlHelper<dynamic> Html { get; private set; }
#line hidden #line hidden

View File

@ -30,13 +30,13 @@ using MyNamespace
#line hidden #line hidden
{ get; private set; } { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.Rendering.IHtmlHelper<dynamic> Html { get; private set; } public Microsoft.AspNet.Mvc.IUrlHelper Url { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.Rendering.IJsonHelper Json { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.IViewComponentHelper Component { get; private set; } public Microsoft.AspNet.Mvc.IViewComponentHelper Component { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.IUrlHelper Url { get; private set; } public Microsoft.AspNet.Mvc.Rendering.IJsonHelper Json { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.Rendering.IHtmlHelper<dynamic> Html { get; private set; }
#line hidden #line hidden

View File

@ -38,11 +38,11 @@ namespace Asp
#line hidden #line hidden
{ get; private set; } { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.Rendering.IJsonHelper Json { get; private set; } public Microsoft.AspNet.Mvc.IUrlHelper Url { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.IViewComponentHelper Component { get; private set; } public Microsoft.AspNet.Mvc.IViewComponentHelper Component { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.IUrlHelper Url { get; private set; } public Microsoft.AspNet.Mvc.Rendering.IJsonHelper Json { get; private set; }
#line hidden #line hidden

View File

@ -54,11 +54,11 @@ namespace Asp
#line hidden #line hidden
{ get; private set; } { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.Rendering.IJsonHelper Json { get; private set; } public Microsoft.AspNet.Mvc.IUrlHelper Url { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.IViewComponentHelper Component { get; private set; } public Microsoft.AspNet.Mvc.IViewComponentHelper Component { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.IUrlHelper Url { get; private set; } public Microsoft.AspNet.Mvc.Rendering.IJsonHelper Json { get; private set; }
#line hidden #line hidden

View File

@ -22,13 +22,13 @@ namespace Asp
} }
#line hidden #line hidden
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.Rendering.IHtmlHelper<System.Collections.IEnumerable> Html { get; private set; } public Microsoft.AspNet.Mvc.IUrlHelper Url { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.Rendering.IJsonHelper Json { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.IViewComponentHelper Component { get; private set; } public Microsoft.AspNet.Mvc.IViewComponentHelper Component { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.IUrlHelper Url { get; private set; } public Microsoft.AspNet.Mvc.Rendering.IJsonHelper Json { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.Rendering.IHtmlHelper<System.Collections.IEnumerable> Html { get; private set; }
#line hidden #line hidden

View File

@ -38,13 +38,13 @@ namespace Asp
} }
#line hidden #line hidden
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.Rendering.IHtmlHelper<DateTime> Html { get; private set; } public Microsoft.AspNet.Mvc.IUrlHelper Url { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.Rendering.IJsonHelper Json { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.IViewComponentHelper Component { get; private set; } public Microsoft.AspNet.Mvc.IViewComponentHelper Component { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.IUrlHelper Url { get; private set; } public Microsoft.AspNet.Mvc.Rendering.IJsonHelper Json { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.Rendering.IHtmlHelper<DateTime> Html { get; private set; }
#line hidden #line hidden

View File

@ -16,13 +16,13 @@ namespace Asp
} }
#line hidden #line hidden
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.Rendering.IHtmlHelper<dynamic> Html { get; private set; } public Microsoft.AspNet.Mvc.IUrlHelper Url { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.Rendering.IJsonHelper Json { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.IViewComponentHelper Component { get; private set; } public Microsoft.AspNet.Mvc.IViewComponentHelper Component { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.IUrlHelper Url { get; private set; } public Microsoft.AspNet.Mvc.Rendering.IJsonHelper Json { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.Rendering.IHtmlHelper<dynamic> Html { get; private set; }
#line hidden #line hidden

View File

@ -24,13 +24,13 @@ using MyNamespace
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public MyApp MyPropertyName { get; private set; } public MyApp MyPropertyName { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.Rendering.IHtmlHelper<dynamic> Html { get; private set; } public Microsoft.AspNet.Mvc.IUrlHelper Url { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.Rendering.IJsonHelper Json { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.IViewComponentHelper Component { get; private set; } public Microsoft.AspNet.Mvc.IViewComponentHelper Component { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.IUrlHelper Url { get; private set; } public Microsoft.AspNet.Mvc.Rendering.IJsonHelper Json { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.Rendering.IHtmlHelper<dynamic> Html { get; private set; }
#line hidden #line hidden

View File

@ -26,11 +26,11 @@ namespace Asp
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public MyService<MyModel> Html { get; private set; } public MyService<MyModel> Html { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.Rendering.IJsonHelper Json { get; private set; } public Microsoft.AspNet.Mvc.IUrlHelper Url { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.IViewComponentHelper Component { get; private set; } public Microsoft.AspNet.Mvc.IViewComponentHelper Component { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.IUrlHelper Url { get; private set; } public Microsoft.AspNet.Mvc.Rendering.IJsonHelper Json { get; private set; }
#line hidden #line hidden

View File

@ -30,11 +30,11 @@ namespace Asp
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public MyService<MyModel> Html2 { get; private set; } public MyService<MyModel> Html2 { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.Rendering.IJsonHelper Json { get; private set; } public Microsoft.AspNet.Mvc.IUrlHelper Url { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.IViewComponentHelper Component { get; private set; } public Microsoft.AspNet.Mvc.IViewComponentHelper Component { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.IUrlHelper Url { get; private set; } public Microsoft.AspNet.Mvc.Rendering.IJsonHelper Json { get; private set; }
#line hidden #line hidden

View File

@ -22,13 +22,13 @@ namespace Asp
} }
#line hidden #line hidden
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.Rendering.IHtmlHelper<System.Collections.IEnumerable> Html { get; private set; } public Microsoft.AspNet.Mvc.IUrlHelper Url { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.Rendering.IJsonHelper Json { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.IViewComponentHelper Component { get; private set; } public Microsoft.AspNet.Mvc.IViewComponentHelper Component { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.IUrlHelper Url { get; private set; } public Microsoft.AspNet.Mvc.Rendering.IJsonHelper Json { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.Rendering.IHtmlHelper<System.Collections.IEnumerable> Html { get; private set; }
#line hidden #line hidden

View File

@ -31,13 +31,13 @@ namespace Asp
} }
#line hidden #line hidden
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.Rendering.IHtmlHelper<DateTime> Html { get; private set; } public Microsoft.AspNet.Mvc.IUrlHelper Url { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.Rendering.IJsonHelper Json { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.IViewComponentHelper Component { get; private set; } public Microsoft.AspNet.Mvc.IViewComponentHelper Component { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute] [Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.IUrlHelper Url { get; private set; } public Microsoft.AspNet.Mvc.Rendering.IJsonHelper Json { get; private set; }
[Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNet.Mvc.Rendering.IHtmlHelper<DateTime> Html { get; private set; }
#line hidden #line hidden

View File

@ -0,0 +1,12 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Mvc;
namespace TagHelpersWebSite.Controllers
{
public class RemoveDefaultInheritedTagHelpersController : Controller
{
public IActionResult Index() => View();
}
}

View File

@ -0,0 +1,4 @@
@{
Layout = null;
}
<a href="~/VirtualPath">Virtual path</a>

View File

@ -0,0 +1 @@
@removeTagHelper "*, Microsoft.AspNet.Mvc.Razor"