Modify ViewStartUtility to generate always view paths with forward slashes
Fixes #3294
This commit is contained in:
parent
e943cdb57a
commit
f4a6d634b5
|
|
@ -5,6 +5,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.Razor
|
namespace Microsoft.AspNet.Mvc.Razor
|
||||||
{
|
{
|
||||||
|
|
@ -77,18 +78,31 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
// If the specified path is for the file hierarchy being constructed, then the first file that applies
|
// If the specified path is for the file hierarchy being constructed, then the first file that applies
|
||||||
// to it is in a parent directory.
|
// to it is in a parent directory.
|
||||||
relativePath = Path.GetDirectoryName(relativePath);
|
relativePath = Path.GetDirectoryName(relativePath);
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(relativePath))
|
if (string.IsNullOrEmpty(relativePath))
|
||||||
{
|
{
|
||||||
return Enumerable.Empty<string>();
|
return Enumerable.Empty<string>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var locations = new List<string>();
|
var builder = new StringBuilder(relativePath);
|
||||||
while (!string.IsNullOrEmpty(relativePath))
|
builder.Replace('\\', '/');
|
||||||
|
|
||||||
|
if (builder.Length > 0 && builder[0] != '/')
|
||||||
{
|
{
|
||||||
relativePath = Path.GetDirectoryName(relativePath);
|
builder.Insert(0, '/');
|
||||||
var path = Path.Combine(relativePath, fileName);
|
}
|
||||||
locations.Add(path);
|
|
||||||
|
var locations = new List<string>();
|
||||||
|
for (var index = builder.Length - 1; index >= 0; index--)
|
||||||
|
{
|
||||||
|
if (builder[index] == '/')
|
||||||
|
{
|
||||||
|
builder.Length = index + 1;
|
||||||
|
builder.Append(fileName);
|
||||||
|
|
||||||
|
locations.Add(builder.ToString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return locations;
|
return locations;
|
||||||
|
|
|
||||||
|
|
@ -58,10 +58,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
||||||
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
||||||
Assert.Equal(expectedMediaType, response.Content.Headers.ContentType);
|
Assert.Equal(expectedMediaType, response.Content.Headers.ContentType);
|
||||||
var content = await response.Content.ReadAsStringAsync();
|
var content = await response.Content.ReadAsStringAsync();
|
||||||
Assert.Contains(
|
Assert.Contains("/Views/ErrorFromViewImports/_ViewImports.cshtml", content);
|
||||||
PlatformNormalizer.NormalizePath(@"Views\ErrorFromViewImports\_ViewImports.cshtml"),
|
|
||||||
content);
|
|
||||||
|
|
||||||
Assert.Contains(expectedMessage, content);
|
Assert.Contains(expectedMessage, content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -400,7 +400,7 @@ Partial that does not specify Layout
|
||||||
ResourceFile.UpdateFile(_assembly, outputFile, expectedContent, responseContent);
|
ResourceFile.UpdateFile(_assembly, outputFile, expectedContent, responseContent);
|
||||||
#else
|
#else
|
||||||
Assert.Equal(
|
Assert.Equal(
|
||||||
PlatformNormalizer.NormalizePath(expectedContent),
|
expectedContent,
|
||||||
responseContent,
|
responseContent,
|
||||||
ignoreLineEndingDifferences: true);
|
ignoreLineEndingDifferences: true);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
/Views/ViewWithPaths/Index.cshtml
|
/Views/ViewWithPaths/Index.cshtml
|
||||||
</Layout>
|
</Layout>
|
||||||
<ViewStart>
|
<ViewStart>
|
||||||
Views\ViewWithPaths\_ViewStart.cshtml
|
/Views/ViewWithPaths/_ViewStart.cshtml
|
||||||
/Views/ViewWithPaths/Index.cshtml
|
/Views/ViewWithPaths/Index.cshtml
|
||||||
</ViewStart>
|
</ViewStart>
|
||||||
<Index>
|
<Index>
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,10 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var fileProvider = new TestFileProvider();
|
var fileProvider = new TestFileProvider();
|
||||||
fileProvider.AddFile(PlatformNormalizer.NormalizePath(@"Views\accounts\_ViewImports.cshtml"), "@using AccountModels");
|
fileProvider.AddFile(@"/Views/accounts/_ViewImports.cshtml", "@using AccountModels");
|
||||||
fileProvider.AddFile(PlatformNormalizer.NormalizePath(@"Views\Shared\_ViewImports.cshtml"), "@inject SharedHelper Shared");
|
fileProvider.AddFile(@"/Views/Shared/_ViewImports.cshtml", "@inject SharedHelper Shared");
|
||||||
fileProvider.AddFile(PlatformNormalizer.NormalizePath(@"Views\home\_ViewImports.cshtml"), "@using MyNamespace");
|
fileProvider.AddFile(@"/Views/home/_ViewImports.cshtml", "@using MyNamespace");
|
||||||
fileProvider.AddFile(PlatformNormalizer.NormalizePath(@"Views\_ViewImports.cshtml"),
|
fileProvider.AddFile(@"/Views/_ViewImports.cshtml",
|
||||||
@"@inject MyHelper<TModel> Helper
|
@"@inject MyHelper<TModel> Helper
|
||||||
@inherits MyBaseType
|
@inherits MyBaseType
|
||||||
|
|
||||||
|
|
@ -42,7 +42,7 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
|
||||||
Assert.Collection(chunkTreeResults,
|
Assert.Collection(chunkTreeResults,
|
||||||
chunkTreeResult =>
|
chunkTreeResult =>
|
||||||
{
|
{
|
||||||
var viewImportsPath = PlatformNormalizer.NormalizePath(@"Views\_ViewImports.cshtml");
|
var viewImportsPath = @"/Views/_ViewImports.cshtml";
|
||||||
Assert.Collection(chunkTreeResult.ChunkTree.Chunks,
|
Assert.Collection(chunkTreeResult.ChunkTree.Chunks,
|
||||||
chunk =>
|
chunk =>
|
||||||
{
|
{
|
||||||
|
|
@ -86,7 +86,7 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
|
||||||
},
|
},
|
||||||
chunkTreeResult =>
|
chunkTreeResult =>
|
||||||
{
|
{
|
||||||
var viewImportsPath = PlatformNormalizer.NormalizePath(@"Views\home\_ViewImports.cshtml");
|
var viewImportsPath = "/Views/home/_ViewImports.cshtml";
|
||||||
Assert.Collection(chunkTreeResult.ChunkTree.Chunks,
|
Assert.Collection(chunkTreeResult.ChunkTree.Chunks,
|
||||||
chunk =>
|
chunk =>
|
||||||
{
|
{
|
||||||
|
|
@ -113,9 +113,9 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var fileProvider = new TestFileProvider();
|
var fileProvider = new TestFileProvider();
|
||||||
fileProvider.AddFile(@"_ViewImports.cs", string.Empty);
|
fileProvider.AddFile(@"/_ViewImports.cs", string.Empty);
|
||||||
fileProvider.AddFile(PlatformNormalizer.NormalizePath(@"Views\_Layout.cshtml"), string.Empty);
|
fileProvider.AddFile(@"/Views/_Layout.cshtml", string.Empty);
|
||||||
fileProvider.AddFile(PlatformNormalizer.NormalizePath(@"Views\home\_not-viewimports.cshtml"), string.Empty);
|
fileProvider.AddFile(@"/Views/home/_not-viewimports.cshtml", string.Empty);
|
||||||
var cache = new DefaultChunkTreeCache(fileProvider);
|
var cache = new DefaultChunkTreeCache(fileProvider);
|
||||||
var host = new MvcRazorHost(cache);
|
var host = new MvcRazorHost(cache);
|
||||||
var defaultChunks = new Chunk[]
|
var defaultChunks = new Chunk[]
|
||||||
|
|
@ -137,7 +137,7 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var fileProvider = new TestFileProvider();
|
var fileProvider = new TestFileProvider();
|
||||||
fileProvider.AddFile(PlatformNormalizer.NormalizePath(@"Views\_ViewImports.cshtml"),
|
fileProvider.AddFile(@"/Views/_ViewImports.cshtml",
|
||||||
"@inject DifferentHelper<TModel> Html");
|
"@inject DifferentHelper<TModel> Html");
|
||||||
var cache = new DefaultChunkTreeCache(fileProvider);
|
var cache = new DefaultChunkTreeCache(fileProvider);
|
||||||
var host = new MvcRazorHost(cache);
|
var host = new MvcRazorHost(cache);
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
// 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.IO;
|
using System.IO;
|
||||||
using Microsoft.AspNet.Testing;
|
|
||||||
using Microsoft.AspNet.Testing.xunit;
|
using Microsoft.AspNet.Testing.xunit;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -43,9 +42,34 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
// Arrange
|
// Arrange
|
||||||
var expected = new[]
|
var expected = new[]
|
||||||
{
|
{
|
||||||
PlatformNormalizer.NormalizePath(@"Views\Home\_ViewStart.cshtml"),
|
"/Views/Home/_ViewStart.cshtml",
|
||||||
PlatformNormalizer.NormalizePath(@"Views\_ViewStart.cshtml"),
|
"/Views/_ViewStart.cshtml",
|
||||||
@"_ViewStart.cshtml"
|
"/_ViewStart.cshtml"
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = ViewHierarchyUtility.GetViewStartLocations(inputPath);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(expected, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[ConditionalTheory]
|
||||||
|
[OSSkipCondition(OperatingSystems.Linux,
|
||||||
|
SkipReason = "Back slashes only work as path separators on Windows")]
|
||||||
|
[OSSkipCondition(OperatingSystems.MacOSX,
|
||||||
|
SkipReason = "Back slashes only work as path separators on Windows")]
|
||||||
|
[InlineData(@"~/Views\Home\MyView.cshtml")]
|
||||||
|
[InlineData(@"Views\Home\MyView.cshtml")]
|
||||||
|
public void GetViewStartLocations_ReturnsPotentialViewStartLocations_PathsContainBackSlash(
|
||||||
|
string inputPath)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var expected = new[]
|
||||||
|
{
|
||||||
|
"/Views/Home/_ViewStart.cshtml",
|
||||||
|
"/Views/_ViewStart.cshtml",
|
||||||
|
"/_ViewStart.cshtml"
|
||||||
};
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -64,9 +88,9 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
// Arrange
|
// Arrange
|
||||||
var expected = new[]
|
var expected = new[]
|
||||||
{
|
{
|
||||||
PlatformNormalizer.NormalizePath(@"Views\Home\_ViewImports.cshtml"),
|
"/Views/Home/_ViewImports.cshtml",
|
||||||
PlatformNormalizer.NormalizePath(@"Views\_ViewImports.cshtml"),
|
"/Views/_ViewImports.cshtml",
|
||||||
@"_ViewImports.cshtml"
|
"/_ViewImports.cshtml"
|
||||||
};
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -85,8 +109,8 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
// Arrange
|
// Arrange
|
||||||
var expected = new[]
|
var expected = new[]
|
||||||
{
|
{
|
||||||
PlatformNormalizer.NormalizePath(@"Views\_ViewStart.cshtml"),
|
"/Views/_ViewStart.cshtml",
|
||||||
@"_ViewStart.cshtml"
|
"/_ViewStart.cshtml"
|
||||||
};
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -105,9 +129,9 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
// Arrange
|
// Arrange
|
||||||
var expected = new[]
|
var expected = new[]
|
||||||
{
|
{
|
||||||
PlatformNormalizer.NormalizePath(@"Views\Home\_ViewImports.cshtml"),
|
"/Views/Home/_ViewImports.cshtml",
|
||||||
PlatformNormalizer.NormalizePath(@"Views\_ViewImports.cshtml"),
|
"/Views/_ViewImports.cshtml",
|
||||||
@"_ViewImports.cshtml"
|
"/_ViewImports.cshtml"
|
||||||
};
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -126,8 +150,8 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
// Arrange
|
// Arrange
|
||||||
var expected = new[]
|
var expected = new[]
|
||||||
{
|
{
|
||||||
PlatformNormalizer.NormalizePath(@"Views\_ViewImports.cshtml"),
|
"/Views/_ViewImports.cshtml",
|
||||||
@"_ViewImports.cshtml"
|
"/_ViewImports.cshtml"
|
||||||
};
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -145,14 +169,42 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
// Arrange
|
// Arrange
|
||||||
var expected = new[]
|
var expected = new[]
|
||||||
{
|
{
|
||||||
PlatformNormalizer.NormalizePath(@"Areas\MyArea\Sub\Views\Admin\_ViewStart.cshtml"),
|
"/Areas/MyArea/Sub/Views/Admin/_ViewStart.cshtml",
|
||||||
PlatformNormalizer.NormalizePath(@"Areas\MyArea\Sub\Views\_ViewStart.cshtml"),
|
"/Areas/MyArea/Sub/Views/_ViewStart.cshtml",
|
||||||
PlatformNormalizer.NormalizePath(@"Areas\MyArea\Sub\_ViewStart.cshtml"),
|
"/Areas/MyArea/Sub/_ViewStart.cshtml",
|
||||||
PlatformNormalizer.NormalizePath(@"Areas\MyArea\_ViewStart.cshtml"),
|
"/Areas/MyArea/_ViewStart.cshtml",
|
||||||
PlatformNormalizer.NormalizePath(@"Areas\_ViewStart.cshtml"),
|
"/Areas/_ViewStart.cshtml",
|
||||||
@"_ViewStart.cshtml",
|
"/_ViewStart.cshtml",
|
||||||
};
|
};
|
||||||
var viewPath = Path.Combine("Areas", "MyArea", "Sub", "Views", "Admin", fileName);
|
var viewPath = $"Areas/MyArea/Sub/Views/Admin/{fileName}";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = ViewHierarchyUtility.GetViewStartLocations(viewPath);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(expected, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[ConditionalTheory]
|
||||||
|
[OSSkipCondition(OperatingSystems.Linux,
|
||||||
|
SkipReason = "Back slashes only work as path separators on Windows")]
|
||||||
|
[OSSkipCondition(OperatingSystems.MacOSX,
|
||||||
|
SkipReason = "Back slashes only work as path separators on Windows")]
|
||||||
|
[InlineData("Test.cshtml")]
|
||||||
|
[InlineData("ViewStart.cshtml")]
|
||||||
|
public void GetViewStartLocations_ReturnsPotentialViewStartLocations_ForPathsWithBackSlashes(string fileName)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var expected = new[]
|
||||||
|
{
|
||||||
|
"/Areas/MyArea/Sub/Views/Admin/_ViewStart.cshtml",
|
||||||
|
"/Areas/MyArea/Sub/Views/_ViewStart.cshtml",
|
||||||
|
"/Areas/MyArea/Sub/_ViewStart.cshtml",
|
||||||
|
"/Areas/MyArea/_ViewStart.cshtml",
|
||||||
|
"/Areas/_ViewStart.cshtml",
|
||||||
|
"/_ViewStart.cshtml",
|
||||||
|
};
|
||||||
|
var viewPath = $"Areas\\MyArea\\Sub\\Views\\Admin/{fileName}";
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = ViewHierarchyUtility.GetViewStartLocations(viewPath);
|
var result = ViewHierarchyUtility.GetViewStartLocations(viewPath);
|
||||||
|
|
@ -170,14 +222,14 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
// Arrange
|
// Arrange
|
||||||
var expected = new[]
|
var expected = new[]
|
||||||
{
|
{
|
||||||
PlatformNormalizer.NormalizePath(@"Areas\MyArea\Sub\Views\Admin\_ViewImports.cshtml"),
|
"/Areas/MyArea/Sub/Views/Admin/_ViewImports.cshtml",
|
||||||
PlatformNormalizer.NormalizePath(@"Areas\MyArea\Sub\Views\_ViewImports.cshtml"),
|
"/Areas/MyArea/Sub/Views/_ViewImports.cshtml",
|
||||||
PlatformNormalizer.NormalizePath(@"Areas\MyArea\Sub\_ViewImports.cshtml"),
|
"/Areas/MyArea/Sub/_ViewImports.cshtml",
|
||||||
PlatformNormalizer.NormalizePath(@"Areas\MyArea\_ViewImports.cshtml"),
|
"/Areas/MyArea/_ViewImports.cshtml",
|
||||||
PlatformNormalizer.NormalizePath(@"Areas\_ViewImports.cshtml"),
|
"/Areas/_ViewImports.cshtml",
|
||||||
@"_ViewImports.cshtml",
|
"/_ViewImports.cshtml",
|
||||||
};
|
};
|
||||||
var viewPath = Path.Combine("Areas", "MyArea", "Sub", "Views", "Admin", fileName);
|
var viewPath = $"Areas/MyArea/Sub/Views/Admin/{fileName}";
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = ViewHierarchyUtility.GetViewImportsLocations(viewPath);
|
var result = ViewHierarchyUtility.GetViewImportsLocations(viewPath);
|
||||||
|
|
@ -194,13 +246,13 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
// Arrange
|
// Arrange
|
||||||
var expected = new[]
|
var expected = new[]
|
||||||
{
|
{
|
||||||
PlatformNormalizer.NormalizePath(@"Areas\MyArea\Sub\Views\_ViewStart.cshtml"),
|
"/Areas/MyArea/Sub/Views/_ViewStart.cshtml",
|
||||||
PlatformNormalizer.NormalizePath(@"Areas\MyArea\Sub\_ViewStart.cshtml"),
|
"/Areas/MyArea/Sub/_ViewStart.cshtml",
|
||||||
PlatformNormalizer.NormalizePath(@"Areas\MyArea\_ViewStart.cshtml"),
|
"/Areas/MyArea/_ViewStart.cshtml",
|
||||||
PlatformNormalizer.NormalizePath(@"Areas\_ViewStart.cshtml"),
|
"/Areas/_ViewStart.cshtml",
|
||||||
@"_ViewStart.cshtml",
|
"/_ViewStart.cshtml",
|
||||||
};
|
};
|
||||||
var viewPath = Path.Combine("Areas", "MyArea", "Sub", "Views", "Admin", fileName);
|
var viewPath = $"Areas/MyArea/Sub/Views/Admin/{fileName}";
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = ViewHierarchyUtility.GetViewStartLocations(viewPath);
|
var result = ViewHierarchyUtility.GetViewStartLocations(viewPath);
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -21,9 +20,9 @@ namespace Microsoft.AspNet.Mvc.Razor.Compilation
|
||||||
public static TheoryData ViewImportsPaths =>
|
public static TheoryData ViewImportsPaths =>
|
||||||
new TheoryData<string>
|
new TheoryData<string>
|
||||||
{
|
{
|
||||||
Path.Combine("Views", "Home", "_ViewImports.cshtml"),
|
"/Views/Home/_ViewImports.cshtml",
|
||||||
Path.Combine("Views", "_ViewImports.cshtml"),
|
"/Views/_ViewImports.cshtml",
|
||||||
"_ViewImports.cshtml",
|
"/_ViewImports.cshtml",
|
||||||
};
|
};
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue