parent
d2cfbd2671
commit
dee479fda7
|
|
@ -1214,6 +1214,33 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
|
||||||
public virtual UnauthorizedResult Unauthorized()
|
public virtual UnauthorizedResult Unauthorized()
|
||||||
=> new UnauthorizedResult();
|
=> new UnauthorizedResult();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a <see cref="PartialViewResult"/> by specifying the name of a partial to render.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="viewName">The partial name.</param>
|
||||||
|
/// <returns>The created <see cref="PartialViewResult"/> object for the response.</returns>
|
||||||
|
public virtual PartialViewResult Partial(string viewName)
|
||||||
|
{
|
||||||
|
return Partial(viewName, model: null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a <see cref="PartialViewResult"/> by specifying the name of a partial to render and the model object.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="viewName">The partial name.</param>
|
||||||
|
/// <param name="model">The model to be passed into the partial.</param>
|
||||||
|
/// <returns>The created <see cref="PartialViewResult"/> object for the response.</returns>
|
||||||
|
public virtual PartialViewResult Partial(string viewName, object model)
|
||||||
|
{
|
||||||
|
ViewContext.ViewData.Model = model;
|
||||||
|
|
||||||
|
return new PartialViewResult
|
||||||
|
{
|
||||||
|
ViewName = viewName,
|
||||||
|
ViewData = ViewContext.ViewData
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#region ViewComponentResult
|
#region ViewComponentResult
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a <see cref="ViewComponentResult"/> by specifying the name of a view component to render.
|
/// Creates a <see cref="ViewComponentResult"/> by specifying the name of a view component to render.
|
||||||
|
|
|
||||||
|
|
@ -1614,6 +1614,33 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
|
||||||
public virtual UnauthorizedResult Unauthorized()
|
public virtual UnauthorizedResult Unauthorized()
|
||||||
=> new UnauthorizedResult();
|
=> new UnauthorizedResult();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a <see cref="PartialViewResult"/> by specifying the name of a partial to render.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="viewName">The partial name.</param>
|
||||||
|
/// <returns>The created <see cref="PartialViewResult"/> object for the response.</returns>
|
||||||
|
public virtual PartialViewResult Partial(string viewName)
|
||||||
|
{
|
||||||
|
return Partial(viewName, model: null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a <see cref="PartialViewResult"/> by specifying the name of a partial to render and the model object.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="viewName">The partial name.</param>
|
||||||
|
/// <param name="model">The model to be passed into the partial.</param>
|
||||||
|
/// <returns>The created <see cref="PartialViewResult"/> object for the response.</returns>
|
||||||
|
public virtual PartialViewResult Partial(string viewName, object model)
|
||||||
|
{
|
||||||
|
ViewData.Model = model;
|
||||||
|
|
||||||
|
return new PartialViewResult
|
||||||
|
{
|
||||||
|
ViewName = viewName,
|
||||||
|
ViewData = ViewData
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#region ViewComponentResult
|
#region ViewComponentResult
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a <see cref="ViewComponentResult"/> by specifying the name of a view component to render.
|
/// Creates a <see cref="ViewComponentResult"/> by specifying the name of a view component to render.
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,8 @@
|
||||||
// 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;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using AngleSharp.Dom.Html;
|
|
||||||
using AngleSharp.Parser.Html;
|
using AngleSharp.Parser.Html;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
||||||
|
|
@ -19,27 +17,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
||||||
var parser = new HtmlParser();
|
var parser = new HtmlParser();
|
||||||
var htmlDocument = parser.Parse(htmlContent);
|
var htmlDocument = parser.Parse(htmlContent);
|
||||||
|
|
||||||
return RetrieveAntiforgeryToken(htmlDocument);
|
return htmlDocument.RetrieveAntiforgeryToken();
|
||||||
}
|
|
||||||
|
|
||||||
public static string RetrieveAntiforgeryToken(IHtmlDocument htmlDocument)
|
|
||||||
{
|
|
||||||
var hiddenInputs = htmlDocument.QuerySelectorAll("form input[type=hidden]");
|
|
||||||
foreach (var input in hiddenInputs)
|
|
||||||
{
|
|
||||||
if (!input.HasAttribute("name"))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var name = input.GetAttribute("name");
|
|
||||||
if (name == "__RequestVerificationToken" || name == "HtmlEncode[[__RequestVerificationToken]]")
|
|
||||||
{
|
|
||||||
return input.GetAttribute("value");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Exception($"Antiforgery token could not be located in {htmlDocument.Source.Text}.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CookieMetadata RetrieveAntiforgeryCookie(HttpResponseMessage response)
|
public static CookieMetadata RetrieveAntiforgeryCookie(HttpResponseMessage response)
|
||||||
|
|
|
||||||
|
|
@ -566,7 +566,7 @@ Products: Music Systems, Televisions (3)";
|
||||||
var document = await Client.GetHtmlDocumentAsync(url);
|
var document = await Client.GetHtmlDocumentAsync(url);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
var banner = QuerySelector(document, ".banner");
|
var banner = document.RequiredQuerySelector(".banner");
|
||||||
Assert.Equal("Some status message", banner.TextContent);
|
Assert.Equal("Some status message", banner.TextContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -581,21 +581,10 @@ Products: Music Systems, Televisions (3)";
|
||||||
var document = await Client.GetHtmlDocumentAsync(url);
|
var document = await Client.GetHtmlDocumentAsync(url);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
var banner = QuerySelector(document, ".banner");
|
var banner = document.RequiredQuerySelector(".banner");
|
||||||
Assert.Empty(banner.TextContent);
|
Assert.Empty(banner.TextContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IElement QuerySelector(IHtmlDocument document, string selector)
|
|
||||||
{
|
|
||||||
var element = document.QuerySelector(selector);
|
|
||||||
if (element == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentException($"Document does not contain element that matches the selector {selector}: " + Environment.NewLine + document.DocumentElement.OuterHtml);
|
|
||||||
}
|
|
||||||
|
|
||||||
return element;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static HttpRequestMessage RequestWithLocale(string url, string locale)
|
private static HttpRequestMessage RequestWithLocale(string url, string locale)
|
||||||
{
|
{
|
||||||
var request = new HttpRequestMessage(HttpMethod.Get, url);
|
var request = new HttpRequestMessage(HttpMethod.Get, url);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
// 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 AngleSharp.Dom;
|
||||||
|
using AngleSharp.Dom.Html;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
||||||
|
{
|
||||||
|
public static class IHtmlDocumentExtensions
|
||||||
|
{
|
||||||
|
public static IElement RequiredQuerySelector(this IHtmlDocument document, string selector)
|
||||||
|
{
|
||||||
|
var element = document.QuerySelector(selector);
|
||||||
|
if (element == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentException($"Document does not contain element that matches the selector {selector}: " + Environment.NewLine + document.DocumentElement.OuterHtml);
|
||||||
|
}
|
||||||
|
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string RetrieveAntiforgeryToken(this IHtmlDocument htmlDocument)
|
||||||
|
{
|
||||||
|
var hiddenInputs = htmlDocument.QuerySelectorAll("form input[type=hidden]");
|
||||||
|
foreach (var input in hiddenInputs)
|
||||||
|
{
|
||||||
|
if (!input.HasAttribute("name"))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var name = input.GetAttribute("name");
|
||||||
|
if (name == "__RequestVerificationToken" || name == "HtmlEncode[[__RequestVerificationToken]]")
|
||||||
|
{
|
||||||
|
return input.GetAttribute("value");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Exception($"Antiforgery token could not be located in {htmlDocument.Source.Text}.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -11,7 +11,6 @@ using System.Net.Http.Headers;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Mvc.Authorization;
|
|
||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
using Microsoft.AspNetCore.Testing;
|
using Microsoft.AspNetCore.Testing;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
@ -144,6 +143,26 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
||||||
Assert.Equal("CustomActionResult", content);
|
Assert.Equal("CustomActionResult", content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Page_Handler_ReturnPartialWithoutModel()
|
||||||
|
{
|
||||||
|
// Act
|
||||||
|
var document = await Client.GetHtmlDocumentAsync("RenderPartialWithoutModel");
|
||||||
|
|
||||||
|
var element = document.RequiredQuerySelector("#content");
|
||||||
|
Assert.Equal("Welcome, Guest", element.TextContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Page_Handler_ReturnPartialWithModel()
|
||||||
|
{
|
||||||
|
// Act
|
||||||
|
var document = await Client.GetHtmlDocumentAsync("RenderPartialWithModel");
|
||||||
|
|
||||||
|
var element = document.RequiredQuerySelector("#content");
|
||||||
|
Assert.Equal("Welcome, Admin", element.TextContent);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task Page_Handler_AsyncReturnTypeImplementsIActionResult()
|
public async Task Page_Handler_AsyncReturnTypeImplementsIActionResult()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1894,6 +1894,52 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
|
||||||
testPageModel.Verify();
|
testPageModel.Verify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void PartialView_WithName()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary());
|
||||||
|
var pageModel = new TestPageModel
|
||||||
|
{
|
||||||
|
PageContext = new PageContext
|
||||||
|
{
|
||||||
|
ViewData = viewData
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = pageModel.Partial("LoginStatus");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.NotNull(result);
|
||||||
|
Assert.Equal("LoginStatus", result.ViewName);
|
||||||
|
Assert.Same(viewData, result.ViewData);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void PartialView_WithNameAndModel()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary());
|
||||||
|
var pageModel = new TestPageModel
|
||||||
|
{
|
||||||
|
PageContext = new PageContext
|
||||||
|
{
|
||||||
|
ViewData = viewData
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var model = new { Username = "Admin" };
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = pageModel.Partial("LoginStatus", model);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.NotNull(result);
|
||||||
|
Assert.Equal("LoginStatus", result.ViewName);
|
||||||
|
Assert.Equal(model, result.Model);
|
||||||
|
Assert.Same(viewData, result.ViewData);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ViewComponent_WithName()
|
public void ViewComponent_WithName()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1697,6 +1697,52 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
|
||||||
Assert.Equal(statusCode, result.StatusCode);
|
Assert.Equal(statusCode, result.StatusCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void PartialView_WithName()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary());
|
||||||
|
var pageModel = new TestPage
|
||||||
|
{
|
||||||
|
ViewContext = new ViewContext
|
||||||
|
{
|
||||||
|
ViewData = viewData
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = pageModel.Partial("LoginStatus");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.NotNull(result);
|
||||||
|
Assert.Equal("LoginStatus", result.ViewName);
|
||||||
|
Assert.Same(viewData, result.ViewData);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void PartialView_WithNameAndModel()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary());
|
||||||
|
var pageModel = new TestPage
|
||||||
|
{
|
||||||
|
ViewContext = new ViewContext
|
||||||
|
{
|
||||||
|
ViewData = viewData
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var model = new { Username = "Admin" };
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = pageModel.Partial("LoginStatus", model);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.NotNull(result);
|
||||||
|
Assert.Equal("LoginStatus", result.ViewName);
|
||||||
|
Assert.Equal(model, result.Model);
|
||||||
|
Assert.Same(viewData, result.ViewData);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ViewComponent_WithName()
|
public void ViewComponent_WithName()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
// 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.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
|
||||||
|
namespace RazorPagesWebSite
|
||||||
|
{
|
||||||
|
public class RenderPartialWithModel : PageModel
|
||||||
|
{
|
||||||
|
public IActionResult OnGet() => Partial("_PartialWithModel", this);
|
||||||
|
|
||||||
|
public string Username => "Admin";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
@page
|
||||||
|
@model RazorPagesWebSite.RenderPartialWithModel
|
||||||
|
|
||||||
|
<p>The partial will be loaded here ...</p>
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
@page
|
||||||
|
|
||||||
|
@functions {
|
||||||
|
public IActionResult OnGet() => Partial("_PartialWithoutModel");
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
@model RazorPagesWebSite.RenderPartialWithModel
|
||||||
|
|
||||||
|
<span id="content">Welcome, @Model.Username</span>
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
<span id="content">Welcome, Guest</span>
|
||||||
Loading…
Reference in New Issue