Trim quotes from template (#5838)
This commit is contained in:
parent
7cadb58e12
commit
85e28ae478
|
|
@ -42,7 +42,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
|||
}
|
||||
|
||||
string template;
|
||||
if (!PageDirectiveFeature.TryGetRouteTemplate(item, out template))
|
||||
if (!PageDirectiveFeature.TryGetPageDirective(item, out template))
|
||||
{
|
||||
// .cshtml pages without @page are not RazorPages.
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -9,25 +9,46 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
|||
{
|
||||
public static class PageDirectiveFeature
|
||||
{
|
||||
public static bool TryGetRouteTemplate(RazorProjectItem projectItem, out string template)
|
||||
public static bool TryGetPageDirective(RazorProjectItem projectItem, out string template)
|
||||
{
|
||||
if (projectItem == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(projectItem));
|
||||
}
|
||||
|
||||
const string PageDirective = "@page";
|
||||
|
||||
string content;
|
||||
using (var streamReader = new StreamReader(projectItem.Read()))
|
||||
var stream = projectItem.Read();
|
||||
|
||||
string content = null;
|
||||
using (var streamReader = new StreamReader(stream))
|
||||
{
|
||||
content = streamReader.ReadToEnd();
|
||||
do
|
||||
{
|
||||
content = streamReader.ReadLine();
|
||||
} while (content != null && string.IsNullOrWhiteSpace(content));
|
||||
content = content?.Trim();
|
||||
}
|
||||
|
||||
if (content.StartsWith(PageDirective, StringComparison.Ordinal))
|
||||
if (content == null || !content.StartsWith(PageDirective, StringComparison.Ordinal))
|
||||
{
|
||||
var newLineIndex = content.IndexOf(Environment.NewLine, PageDirective.Length);
|
||||
template = content.Substring(PageDirective.Length, newLineIndex - PageDirective.Length).Trim();
|
||||
return true;
|
||||
template = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
template = null;
|
||||
return false;
|
||||
template = content.Substring(PageDirective.Length, content.Length - PageDirective.Length).TrimStart();
|
||||
|
||||
if (template.StartsWith("\"") && template.EndsWith("\""))
|
||||
{
|
||||
template = template.Substring(1, template.Length - 2);
|
||||
}
|
||||
// If it's not in quotes it's not our template
|
||||
else
|
||||
{
|
||||
template = string.Empty;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// 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 System;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
|
|
@ -19,6 +18,19 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
|
||||
public HttpClient Client { get; }
|
||||
|
||||
[Fact]
|
||||
public async Task NoPage_NotFound()
|
||||
{
|
||||
// Arrange
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/NoPage");
|
||||
|
||||
// Act
|
||||
var response = await Client.SendAsync(request);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task HelloWorld_CanGetContent()
|
||||
{
|
||||
|
|
@ -83,16 +95,32 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
Assert.Equal("Hello, pagemodel!", content.Trim());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task PageWithoutContent()
|
||||
{
|
||||
// Arrange
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/PageWithoutContent/No/Content/Path");
|
||||
|
||||
// Act
|
||||
var response = await Client.SendAsync(request);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
var content = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal("", content);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TempData_SetTempDataInPage_CanReadValue()
|
||||
{
|
||||
// Arrange 1
|
||||
var url = "http://localhost/TempData/SetTempDataOnPageAndRedirect?message=Hi1";
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, url);
|
||||
|
||||
|
||||
// Act 1
|
||||
var response = await Client.SendAsync(request);
|
||||
|
||||
|
||||
// Assert 1
|
||||
Assert.Equal(HttpStatusCode.Redirect, response.StatusCode);
|
||||
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
|||
razorProject.Setup(p => p.EnumerateItems("/"))
|
||||
.Returns(new[]
|
||||
{
|
||||
GetProjectItem("/", "/Test.cshtml", $"@page Home {Environment.NewLine}<h1>Hello world</h1>"),
|
||||
GetProjectItem("/", "/Test.cshtml", $"@page \"Home\" {Environment.NewLine}<h1>Hello world</h1>"),
|
||||
});
|
||||
var provider = new PageActionDescriptorProvider(
|
||||
razorProject.Object,
|
||||
|
|
@ -105,7 +105,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
|||
razorProject.Setup(p => p.EnumerateItems("/"))
|
||||
.Returns(new[]
|
||||
{
|
||||
GetProjectItem("/", "/Test.cshtml", $"@page {template} {Environment.NewLine}<h1>Hello world</h1>"),
|
||||
GetProjectItem("/", "/Test.cshtml", $"@page \"{template}\" {Environment.NewLine}<h1>Hello world</h1>"),
|
||||
});
|
||||
var provider = new PageActionDescriptorProvider(
|
||||
razorProject.Object,
|
||||
|
|
@ -166,7 +166,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
|||
razorProject.Setup(p => p.EnumerateItems("/"))
|
||||
.Returns(new[]
|
||||
{
|
||||
GetProjectItem("", "/Catalog/Details/Index.cshtml", $"@page {{id:int?}} {Environment.NewLine}"),
|
||||
GetProjectItem("", "/Catalog/Details/Index.cshtml", $"@page \"{{id:int?}}\" {Environment.NewLine}"),
|
||||
});
|
||||
var provider = new PageActionDescriptorProvider(
|
||||
razorProject.Object,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,267 @@
|
|||
// 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 System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Microsoft.AspNetCore.Razor.Evolution;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
||||
{
|
||||
public class PageDirectiveFeatureTest
|
||||
{
|
||||
[Fact]
|
||||
public void TryGetPageDirective_FindsTemplate()
|
||||
{
|
||||
// Arrange
|
||||
string template;
|
||||
var projectItem = new TestRazorProjectItem(@"@page ""Some/Path/{value}""
|
||||
The rest of the thing");
|
||||
|
||||
// Act & Assert
|
||||
Assert.True(PageDirectiveFeature.TryGetPageDirective(projectItem, out template));
|
||||
Assert.Equal("Some/Path/{value}", template);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TryGetPageDirective_NoNewLine()
|
||||
{
|
||||
// Arrange
|
||||
string template;
|
||||
var projectItem = new TestRazorProjectItem(@"@page ""Some/Path/{value}""");
|
||||
|
||||
// Act & Assert
|
||||
Assert.True(PageDirectiveFeature.TryGetPageDirective(projectItem, out template));
|
||||
Assert.Equal("Some/Path/{value}", template);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TryGetPageDirective_JunkBeforeDirective()
|
||||
{
|
||||
// Arrange
|
||||
string template;
|
||||
var projectItem = new TestRazorProjectItem(@"Not a directive @page ""Some/Path/{value}""");
|
||||
|
||||
// Act & Assert
|
||||
Assert.False(PageDirectiveFeature.TryGetPageDirective(projectItem, out template));
|
||||
Assert.Null(template);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TryGetPageDirective_MultipleQuotes()
|
||||
{
|
||||
// Arrange
|
||||
string template;
|
||||
var projectItem = new TestRazorProjectItem(@"@page """"template""""");
|
||||
|
||||
// Act & Assert
|
||||
Assert.True(PageDirectiveFeature.TryGetPageDirective(projectItem, out template));
|
||||
Assert.Equal(@"""template""", template);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(@"""Some/Path/{value}")]
|
||||
[InlineData(@"Some/Path/{value}""")]
|
||||
public void TryGetPageDirective_RequiresBothQuotes(string inTemplate)
|
||||
{
|
||||
// Arrange
|
||||
string template;
|
||||
var projectItem = new TestRazorProjectItem($@"@page {inTemplate}");
|
||||
|
||||
// Act & Assert
|
||||
Assert.True(PageDirectiveFeature.TryGetPageDirective(projectItem, out template));
|
||||
Assert.Equal(string.Empty, template);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void TryGetPageDirective_NoQuotesAroundPath_IsNotTemplate()
|
||||
{
|
||||
// Arrange
|
||||
string template;
|
||||
var projectItem = new TestRazorProjectItem(@"@page Some/Path/{value}");
|
||||
|
||||
// Act & Assert
|
||||
Assert.True(PageDirectiveFeature.TryGetPageDirective(projectItem, out template));
|
||||
Assert.Equal(string.Empty, template);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TryGetPageDirective_WrongNewLine()
|
||||
{
|
||||
// Arrange
|
||||
var wrongNewLine = Environment.NewLine == "\r\n" ? "\n" : "\r\n";
|
||||
|
||||
string template;
|
||||
var projectItem = new TestRazorProjectItem($"@page \"Some/Path/{{value}}\" {wrongNewLine}");
|
||||
|
||||
// Act & Assert
|
||||
Assert.True(PageDirectiveFeature.TryGetPageDirective(projectItem, out template));
|
||||
Assert.Equal("Some/Path/{value}", template);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TryGetPageDirective_NewLineBeforeDirective()
|
||||
{
|
||||
// Arrange
|
||||
string template;
|
||||
var projectItem = new TestRazorProjectItem("\n @page \"Some/Path/{value}\"");
|
||||
|
||||
// Act
|
||||
Assert.True(PageDirectiveFeature.TryGetPageDirective(projectItem, out template));
|
||||
Assert.Equal("Some/Path/{value}", template);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TryGetPageDirective_WhitespaceBeforeDirective()
|
||||
{
|
||||
// Arrange
|
||||
string template;
|
||||
var projectItem = new TestRazorProjectItem(@" @page ""Some/Path/{value}""
|
||||
");
|
||||
|
||||
// Act & Assert
|
||||
Assert.True(PageDirectiveFeature.TryGetPageDirective(projectItem, out template));
|
||||
Assert.Equal("Some/Path/{value}", template);
|
||||
}
|
||||
|
||||
[Fact(Skip = "Re-evaluate this scenario after we use Razor to parse this stuff")]
|
||||
public void TryGetPageDirective_JunkBeforeNewline()
|
||||
{
|
||||
// Arrange
|
||||
string template;
|
||||
var projectItem = new TestRazorProjectItem(@"@page ""Some/Path/{value}"" things that are not the path
|
||||
a new line");
|
||||
|
||||
// Act & Assert
|
||||
Assert.True(PageDirectiveFeature.TryGetPageDirective(projectItem, out template));
|
||||
Assert.Empty(template);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TryGetPageDirective_Directive_WithoutPathOrContent()
|
||||
{
|
||||
// Arrange
|
||||
string template;
|
||||
var projectItem = new TestRazorProjectItem(@"@page");
|
||||
|
||||
// Act & Assert
|
||||
Assert.True(PageDirectiveFeature.TryGetPageDirective(projectItem, out template));
|
||||
Assert.Empty(template);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TryGetPageDirective_DirectiveWithContent_WithoutPath()
|
||||
{
|
||||
// Arrange
|
||||
string template;
|
||||
var projectItem = new TestRazorProjectItem(@"@page
|
||||
Non-path things");
|
||||
|
||||
// Act & Assert
|
||||
Assert.True(PageDirectiveFeature.TryGetPageDirective(projectItem, out template));
|
||||
Assert.Empty(template);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TryGetPageDirective_NoDirective()
|
||||
{
|
||||
// Arrange
|
||||
string template;
|
||||
var projectItem = new TestRazorProjectItem(@"This is junk
|
||||
Nobody will use it");
|
||||
|
||||
// Act & Assert
|
||||
Assert.False(PageDirectiveFeature.TryGetPageDirective(projectItem, out template));
|
||||
Assert.Null(template);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TryGetPageDirective_EmptyStream()
|
||||
{
|
||||
// Arrange
|
||||
string template;
|
||||
var projectItem = new TestRazorProjectItem(string.Empty);
|
||||
|
||||
// Act
|
||||
Assert.False(PageDirectiveFeature.TryGetPageDirective(projectItem, out template));
|
||||
Assert.Null(template);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TryGetPageDirective_NullProject()
|
||||
{
|
||||
// Arrange
|
||||
string template;
|
||||
|
||||
// Act & Assert
|
||||
Assert.Throws<ArgumentNullException>(() => PageDirectiveFeature.TryGetPageDirective(projectItem: null, template: out template));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TryGetPageDirective_NullStream()
|
||||
{
|
||||
// Arrange
|
||||
string template;
|
||||
var projectItem = new TestRazorProjectItem(content: null);
|
||||
|
||||
// Act & Assert
|
||||
Assert.Throws<ArgumentNullException>(() => PageDirectiveFeature.TryGetPageDirective(projectItem, out template));
|
||||
}
|
||||
}
|
||||
|
||||
public class TestRazorProjectItem : RazorProjectItem
|
||||
{
|
||||
private string _content;
|
||||
|
||||
public TestRazorProjectItem(string content)
|
||||
{
|
||||
_content = content;
|
||||
}
|
||||
|
||||
public override string BasePath
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Exists
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public override string Path
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public override string PhysicalPath
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public override Stream Read()
|
||||
{
|
||||
if (_content == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes(_content));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
@page Some/Path/{text}
|
||||
@page "Some/Path/{text}"
|
||||
|
||||
Hello, @(ViewContext.RouteData.Values["text"])!
|
||||
|
|
@ -0,0 +1 @@
|
|||
This isn't a razor page
|
||||
|
|
@ -0,0 +1 @@
|
|||
@page "No/Content/Path"
|
||||
Loading…
Reference in New Issue