Define semantics for pagemodels
Fixes #6210 Now a pagemodel requires a [PageModel] somewhere in it's hierarchy. We don't do a guess at whether or not your model class is a PageModel.
This commit is contained in:
parent
b95ea8bcd2
commit
579aca0121
|
|
@ -6,11 +6,11 @@ using System;
|
|||
namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
||||
{
|
||||
/// <summary>
|
||||
/// An attribute for base classes for Pages and PageModels. Applying this attribute to a type
|
||||
/// suppresses discovery of handler methods for that type.
|
||||
/// An attribute for base classes for page models. Applying this attribute to a type
|
||||
/// marks all subclasses of that type as page model types.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
|
||||
public class PagesBaseClassAttribute : Attribute
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
|
||||
public class PageModelAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -2,11 +2,11 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNetCore.Mvc.ApplicationModels;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
using Microsoft.AspNetCore.Mvc.Razor;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure;
|
||||
using Microsoft.Extensions.Internal;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
|
@ -66,23 +66,34 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
throw new ArgumentNullException(nameof(pageTypeInfo));
|
||||
}
|
||||
|
||||
if (!typeof(PageBase).GetTypeInfo().IsAssignableFrom(pageTypeInfo))
|
||||
{
|
||||
throw new InvalidOperationException(Resources.FormatInvalidPageType_WrongBase(
|
||||
pageTypeInfo.FullName,
|
||||
typeof(PageBase).FullName));
|
||||
}
|
||||
|
||||
// Pages always have a model type. If it's not set explicitly by the developer using
|
||||
// @model, it will be the same as the page type.
|
||||
var modelTypeInfo = pageTypeInfo.GetProperty(ModelPropertyName)?.PropertyType?.GetTypeInfo();
|
||||
var modelProperty = pageTypeInfo.GetProperty(ModelPropertyName, BindingFlags.Public | BindingFlags.Instance);
|
||||
if (modelProperty == null)
|
||||
{
|
||||
throw new InvalidOperationException(Resources.FormatInvalidPageType_NoModelProperty(
|
||||
pageTypeInfo.FullName,
|
||||
ModelPropertyName));
|
||||
}
|
||||
|
||||
// Now we want to find the handler methods. If the model defines any handlers, then we'll use those,
|
||||
// otherwise look at the page itself (unless the page IS the model, in which case we already looked).
|
||||
var modelTypeInfo = modelProperty.PropertyType.GetTypeInfo();
|
||||
|
||||
// Now we want figure out which type is the handler type.
|
||||
TypeInfo handlerType;
|
||||
|
||||
var handlerModels = modelTypeInfo == null ? null : CreateHandlerModels(modelTypeInfo);
|
||||
if (handlerModels?.Count > 0)
|
||||
if (modelProperty.PropertyType.IsDefined(typeof(PageModelAttribute), inherit: true))
|
||||
{
|
||||
handlerType = modelTypeInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
handlerType = pageTypeInfo.GetTypeInfo();
|
||||
handlerModels = CreateHandlerModels(pageTypeInfo);
|
||||
handlerType = pageTypeInfo;
|
||||
}
|
||||
|
||||
var handlerTypeAttributes = handlerType.GetCustomAttributes(inherit: true);
|
||||
|
|
@ -95,27 +106,9 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
ModelType = modelTypeInfo,
|
||||
};
|
||||
|
||||
for (var i = 0; i < handlerModels.Count; i++)
|
||||
{
|
||||
var handlerModel = handlerModels[i];
|
||||
handlerModel.Page = pageModel;
|
||||
pageModel.HandlerMethods.Add(handlerModel);
|
||||
}
|
||||
|
||||
PopulateHandlerMethods(pageModel);
|
||||
PopulateHandlerProperties(pageModel);
|
||||
|
||||
for (var i = 0; i < _globalFilters.Count; i++)
|
||||
{
|
||||
pageModel.Filters.Add(_globalFilters[i]);
|
||||
}
|
||||
|
||||
for (var i = 0; i < handlerTypeAttributes.Length; i++)
|
||||
{
|
||||
if (handlerTypeAttributes[i] is IFilterMetadata filter)
|
||||
{
|
||||
pageModel.Filters.Add(filter);
|
||||
}
|
||||
}
|
||||
PopulateFilters(pageModel);
|
||||
|
||||
return pageModel;
|
||||
}
|
||||
|
|
@ -124,6 +117,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
internal void PopulateHandlerProperties(PageApplicationModel pageModel)
|
||||
{
|
||||
var properties = PropertyHelper.GetVisibleProperties(pageModel.HandlerType.AsType());
|
||||
|
||||
for (var i = 0; i < properties.Length; i++)
|
||||
{
|
||||
var propertyModel = CreatePropertyModel(properties[i].Property);
|
||||
|
|
@ -136,21 +130,34 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
}
|
||||
|
||||
// Internal for unit testing
|
||||
internal IList<PageHandlerModel> CreateHandlerModels(TypeInfo handlerTypeInfo)
|
||||
internal void PopulateHandlerMethods(PageApplicationModel pageModel)
|
||||
{
|
||||
var methods = handlerTypeInfo.GetMethods();
|
||||
var results = new List<PageHandlerModel>();
|
||||
var methods = pageModel.HandlerType.GetMethods();
|
||||
|
||||
for (var i = 0; i < methods.Length; i++)
|
||||
{
|
||||
var handler = CreateHandlerModel(methods[i]);
|
||||
if (handler != null)
|
||||
{
|
||||
results.Add(handler);
|
||||
pageModel.HandlerMethods.Add(handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
internal void PopulateFilters(PageApplicationModel pageModel)
|
||||
{
|
||||
for (var i = 0; i < _globalFilters.Count; i++)
|
||||
{
|
||||
pageModel.Filters.Add(_globalFilters[i]);
|
||||
}
|
||||
|
||||
for (var i = 0; i < pageModel.HandlerTypeAttributes.Count; i++)
|
||||
{
|
||||
if (pageModel.HandlerTypeAttributes[i] is IFilterMetadata filter)
|
||||
{
|
||||
pageModel.Filters.Add(filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -170,16 +177,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
return null;
|
||||
}
|
||||
|
||||
if (method.IsDefined(typeof(NonHandlerAttribute)))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (method.DeclaringType.GetTypeInfo().IsDefined(typeof(PagesBaseClassAttribute)))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!TryParseHandlerMethod(method.Name, out var httpMethod, out var handlerName))
|
||||
{
|
||||
return null;
|
||||
|
|
@ -294,7 +291,32 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
return false;
|
||||
}
|
||||
|
||||
return methodInfo.IsPublic;
|
||||
if (!methodInfo.IsPublic)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (methodInfo.IsDefined(typeof(NonHandlerAttribute)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Exclude the whole hierarchy of Page.
|
||||
var declaringType = methodInfo.DeclaringType;
|
||||
if (declaringType == typeof(Page) ||
|
||||
declaringType == typeof(PageBase) ||
|
||||
declaringType == typeof(RazorPageBase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Exclude methods declared on PageModel
|
||||
if (declaringType == typeof(PageModel))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static bool TryParseHandlerMethod(string methodName, out string httpMethod, out string handler)
|
||||
|
|
|
|||
|
|
@ -1,14 +1,11 @@
|
|||
// 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.RazorPages.Infrastructure;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.RazorPages
|
||||
{
|
||||
/// <summary>
|
||||
/// A base class for a Razor page.
|
||||
/// </summary>
|
||||
[PagesBaseClass]
|
||||
public abstract class Page : PageBase
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ using Microsoft.AspNetCore.Mvc.ModelBinding;
|
|||
using Microsoft.AspNetCore.Mvc.ModelBinding.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
using Microsoft.AspNetCore.Mvc.Razor;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
|
@ -24,7 +23,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
|
|||
/// <summary>
|
||||
/// A base class for a Razor page.
|
||||
/// </summary>
|
||||
[PagesBaseClass]
|
||||
public abstract class PageBase : RazorPageBase
|
||||
{
|
||||
private IObjectModelValidator _objectValidator;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ using Microsoft.Net.Http.Headers;
|
|||
|
||||
namespace Microsoft.AspNetCore.Mvc.RazorPages
|
||||
{
|
||||
[PagesBaseClass]
|
||||
[PageModelAttribute]
|
||||
public abstract class PageModel
|
||||
{
|
||||
private IModelMetadataProvider _metadataProvider;
|
||||
|
|
|
|||
|
|
@ -136,6 +136,34 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
|
|||
internal static string FormatAsyncPageFilter_InvalidShortCircuit(object p0, object p1, object p2, object p3)
|
||||
=> string.Format(CultureInfo.CurrentCulture, GetString("AsyncPageFilter_InvalidShortCircuit"), p0, p1, p2, p3);
|
||||
|
||||
/// <summary>
|
||||
/// The type '{0}' is not a valid page. A page must inherit from '{1}'.
|
||||
/// </summary>
|
||||
internal static string InvalidPageType_WrongBase
|
||||
{
|
||||
get => GetString("InvalidPageType_WrongBase");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The type '{0}' is not a valid page. A page must inherit from '{1}'.
|
||||
/// </summary>
|
||||
internal static string FormatInvalidPageType_WrongBase(object p0, object p1)
|
||||
=> string.Format(CultureInfo.CurrentCulture, GetString("InvalidPageType_WrongBase"), p0, p1);
|
||||
|
||||
/// <summary>
|
||||
/// The type '{0}' is not a valid page. A page must define a public, non-static '{1}' property.
|
||||
/// </summary>
|
||||
internal static string InvalidPageType_NoModelProperty
|
||||
{
|
||||
get => GetString("InvalidPageType_NoModelProperty");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The type '{0}' is not a valid page. A page must define a public, non-static '{1}' property.
|
||||
/// </summary>
|
||||
internal static string FormatInvalidPageType_NoModelProperty(object p0, object p1)
|
||||
=> string.Format(CultureInfo.CurrentCulture, GetString("InvalidPageType_NoModelProperty"), p0, p1);
|
||||
|
||||
private static string GetString(string name, params string[] formatterNames)
|
||||
{
|
||||
var value = _resourceManager.GetString(name);
|
||||
|
|
|
|||
|
|
@ -144,4 +144,10 @@
|
|||
<data name="AsyncPageFilter_InvalidShortCircuit" xml:space="preserve">
|
||||
<value>If an {0} provides a result value by setting the {1} property of {2} to a non-null value, then it cannot call the next filter by invoking {3}.</value>
|
||||
</data>
|
||||
<data name="InvalidPageType_WrongBase" xml:space="preserve">
|
||||
<value>The type '{0}' is not a valid page. A page must inherit from '{1}'.</value>
|
||||
</data>
|
||||
<data name="InvalidPageType_NoModelProperty" xml:space="preserve">
|
||||
<value>The type '{0}' is not a valid page. A page must define a public, non-static '{1}' property.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
@ -384,6 +384,19 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
Assert.StartsWith("Hello, pagemodel!", content.Trim());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task HelloWorldWithPageModelAttributeHandler()
|
||||
{
|
||||
// Arrange
|
||||
var url = "HelloWorldWithPageModelAttributeModel?message=DecoratedModel";
|
||||
|
||||
// Act
|
||||
var content = await Client.GetStringAsync(url);
|
||||
|
||||
// Assert
|
||||
Assert.Equal("Hello, DecoratedModel!", content.Trim());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task PageWithoutContent()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
// 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.Collections.Generic;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc.ApplicationModels;
|
||||
using Microsoft.AspNetCore.Mvc.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc.Razor;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||
|
|
@ -18,7 +20,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
// Arrange
|
||||
var policyProvider = new DefaultAuthorizationPolicyProvider(new TestOptionsManager<AuthorizationOptions>());
|
||||
var autorizationProvider = new AuthorizationPageApplicationModelProvider(policyProvider);
|
||||
var typeInfo = typeof(PageWiithAuthorizeHandlers).GetTypeInfo();
|
||||
var typeInfo = typeof(PageWithAuthorizeHandlers).GetTypeInfo();
|
||||
var context = GetApplicationProviderContext(typeInfo);
|
||||
|
||||
// Act
|
||||
|
|
@ -28,12 +30,14 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
Assert.Empty(context.PageApplicationModel.Filters);
|
||||
}
|
||||
|
||||
private class PageWiithAuthorizeHandlers
|
||||
private class PageWithAuthorizeHandlers : Page
|
||||
{
|
||||
public ModelWuthAuthorizeHandlers Model => null;
|
||||
public ModelWithAuthorizeHandlers Model => null;
|
||||
|
||||
public override Task ExecuteAsync() => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public class ModelWuthAuthorizeHandlers
|
||||
public class ModelWithAuthorizeHandlers : PageModel
|
||||
{
|
||||
[Authorize]
|
||||
public void OnGet()
|
||||
|
|
@ -58,13 +62,15 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
f => Assert.IsType<AuthorizeFilter>(f));
|
||||
}
|
||||
|
||||
private class TestPage
|
||||
private class TestPage : Page
|
||||
{
|
||||
public TestModel Model => null;
|
||||
|
||||
public override Task ExecuteAsync() => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
[Authorize]
|
||||
private class TestModel
|
||||
private class TestModel : PageModel
|
||||
{
|
||||
public virtual void OnGet()
|
||||
{
|
||||
|
|
@ -93,13 +99,15 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
Assert.Equal(3, authorizeFilter.Policy.Requirements.Count);
|
||||
}
|
||||
|
||||
private class TestPageWithDerivedModel
|
||||
private class TestPageWithDerivedModel : Page
|
||||
{
|
||||
public DeriviedModel Model => null;
|
||||
|
||||
public override Task ExecuteAsync() =>throw new NotImplementedException();
|
||||
}
|
||||
|
||||
[Authorize(Policy = "Base")]
|
||||
public class BaseModel
|
||||
public class BaseModel : PageModel
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -128,13 +136,15 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
f => Assert.IsType<AllowAnonymousFilter>(f));
|
||||
}
|
||||
|
||||
private class PageWithAnonymousModel
|
||||
private class PageWithAnonymousModel : Page
|
||||
{
|
||||
public AnonymousModel Model => null;
|
||||
|
||||
public override Task ExecuteAsync() => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
[AllowAnonymous]
|
||||
public class AnonymousModel
|
||||
public class AnonymousModel : PageModel
|
||||
{
|
||||
public void OnGet() { }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,19 +8,135 @@ using System.Threading.Tasks;
|
|||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.ApplicationModels;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
using Microsoft.AspNetCore.Mvc.Razor;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||
{
|
||||
public partial class DefaultPageApplicationModelProviderTest
|
||||
public class DefaultPageApplicationModelProviderTest
|
||||
{
|
||||
[Fact]
|
||||
public void OnProvidersExecuting_SetsPageAsHandlerType_IfModelPropertyDoesNotExist()
|
||||
public void OnProvidersExecuting_ThrowsIfPageDoesNotDeriveFromValidBaseType()
|
||||
{
|
||||
// Arrange
|
||||
var provider = new TestPageApplicationModelProvider();
|
||||
var typeInfo = typeof(TestPage).GetTypeInfo();
|
||||
var typeInfo = typeof(InvalidPageWithWrongBaseClass).GetTypeInfo();
|
||||
var descriptor = new PageActionDescriptor();
|
||||
var context = new PageApplicationModelProviderContext(descriptor, typeInfo);
|
||||
|
||||
// Act & Assert
|
||||
var ex = Assert.Throws<InvalidOperationException>(() => provider.OnProvidersExecuting(context));
|
||||
|
||||
// Assert
|
||||
Assert.Equal(
|
||||
$"The type '{typeInfo.FullName}' is not a valid page. A page must inherit from '{typeof(PageBase).FullName}'.",
|
||||
ex.Message);
|
||||
}
|
||||
|
||||
private class InvalidPageWithWrongBaseClass : RazorPageBase
|
||||
{
|
||||
public override void BeginContext(int position, int length, bool isLiteral)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void EndContext()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void EnsureRenderedBodyOrSections()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override Task ExecuteAsync()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void OnProvidersExecuting_ThrowsIfModelPropertyDoesNotExistOnPage()
|
||||
{
|
||||
// Arrange
|
||||
var provider = new TestPageApplicationModelProvider();
|
||||
var typeInfo = typeof(PageWithoutModelProperty).GetTypeInfo();
|
||||
var descriptor = new PageActionDescriptor();
|
||||
var context = new PageApplicationModelProviderContext(descriptor, typeInfo);
|
||||
|
||||
// Act & Assert
|
||||
var ex = Assert.Throws<InvalidOperationException>(() => provider.OnProvidersExecuting(context));
|
||||
|
||||
// Assert
|
||||
Assert.Equal(
|
||||
$"The type '{typeInfo.FullName}' is not a valid page. A page must define a public, non-static 'Model' property.",
|
||||
ex.Message);
|
||||
}
|
||||
|
||||
private class PageWithoutModelProperty : PageBase
|
||||
{
|
||||
public override Task ExecuteAsync() => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void OnProvidersExecuting_ThrowsIfModelPropertyIsNotPublic()
|
||||
{
|
||||
// Arrange
|
||||
var provider = new TestPageApplicationModelProvider();
|
||||
var typeInfo = typeof(PageWithNonVisibleModel).GetTypeInfo();
|
||||
var descriptor = new PageActionDescriptor();
|
||||
var context = new PageApplicationModelProviderContext(descriptor, typeInfo);
|
||||
|
||||
// Act & Assert
|
||||
var ex = Assert.Throws<InvalidOperationException>(() => provider.OnProvidersExecuting(context));
|
||||
|
||||
// Assert
|
||||
Assert.Equal(
|
||||
$"The type '{typeInfo.FullName}' is not a valid page. A page must define a public, non-static 'Model' property.",
|
||||
ex.Message);
|
||||
}
|
||||
|
||||
private class PageWithNonVisibleModel : PageBase
|
||||
{
|
||||
private object Model => null;
|
||||
|
||||
public override Task ExecuteAsync() => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void OnProvidersExecuting_ThrowsIfModelPropertyIsStatic()
|
||||
{
|
||||
// Arrange
|
||||
var provider = new TestPageApplicationModelProvider();
|
||||
var typeInfo = typeof(PageWithStaticModel).GetTypeInfo();
|
||||
var descriptor = new PageActionDescriptor();
|
||||
var context = new PageApplicationModelProviderContext(descriptor, typeInfo);
|
||||
|
||||
// Act & Assert
|
||||
var ex = Assert.Throws<InvalidOperationException>(() => provider.OnProvidersExecuting(context));
|
||||
|
||||
// Assert
|
||||
Assert.Equal(
|
||||
$"The type '{typeInfo.FullName}' is not a valid page. A page must define a public, non-static 'Model' property.",
|
||||
ex.Message);
|
||||
}
|
||||
|
||||
private class PageWithStaticModel : PageBase
|
||||
{
|
||||
public static object Model => null;
|
||||
|
||||
public override Task ExecuteAsync() => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void OnProvidersExecuting_DiscoversPropertiesFromPage_IfModelTypeDoesNotHaveAttribute()
|
||||
{
|
||||
// Arrange
|
||||
var provider = new TestPageApplicationModelProvider();
|
||||
var typeInfo = typeof(PageWithModelWithoutPageModelAttribute).GetTypeInfo();
|
||||
var descriptor = new PageActionDescriptor();
|
||||
var context = new PageApplicationModelProviderContext(descriptor, typeInfo);
|
||||
|
||||
|
|
@ -29,49 +145,53 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
|
||||
// Assert
|
||||
Assert.NotNull(context.PageApplicationModel);
|
||||
Assert.Same(context.PageApplicationModel.PageType, context.PageApplicationModel.HandlerType);
|
||||
var propertiesOnPage = context.PageApplicationModel.HandlerProperties
|
||||
.Where(p => p.PropertyInfo.DeclaringType.GetTypeInfo() == typeInfo);
|
||||
Assert.Collection(
|
||||
propertiesOnPage.OrderBy(p => p.PropertyName),
|
||||
property =>
|
||||
{
|
||||
Assert.Equal(typeInfo.GetProperty(nameof(PageWithModelWithoutPageModelAttribute.Model)), property.PropertyInfo);
|
||||
Assert.Equal(nameof(PageWithModelWithoutPageModelAttribute.Model), property.PropertyName);
|
||||
},
|
||||
property =>
|
||||
{
|
||||
Assert.Equal(typeInfo.GetProperty(nameof(PageWithModelWithoutPageModelAttribute.Property1)), property.PropertyInfo);
|
||||
Assert.Null(property.BindingInfo);
|
||||
Assert.Equal(nameof(PageWithModelWithoutPageModelAttribute.Property1), property.PropertyName);
|
||||
},
|
||||
property =>
|
||||
{
|
||||
Assert.Equal(typeInfo.GetProperty(nameof(PageWithModelWithoutPageModelAttribute.Property2)), property.PropertyInfo);
|
||||
Assert.Equal(nameof(PageWithModelWithoutPageModelAttribute.Property2), property.PropertyName);
|
||||
Assert.NotNull(property.BindingInfo);
|
||||
Assert.Equal(BindingSource.Path, property.BindingInfo.BindingSource);
|
||||
});
|
||||
}
|
||||
|
||||
private class PageWithModelWithoutPageModelAttribute : Page
|
||||
{
|
||||
public string Property1 { get; set; }
|
||||
|
||||
[FromRoute]
|
||||
public object Property2 { get; set; }
|
||||
|
||||
public ModelWithoutPageModelAttribute Model => null;
|
||||
|
||||
public override Task ExecuteAsync() => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private class ModelWithoutPageModelAttribute
|
||||
{
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void OnProvidersExecuting_SetsPageAsHandlerType_IfModelTypeDoesNotHaveAnyHandlers()
|
||||
public void OnProvidersExecuting_DiscoversPropertiesFromPageModel_IfModelHasAttribute()
|
||||
{
|
||||
// Arrange
|
||||
var provider = new TestPageApplicationModelProvider();
|
||||
var typeInfo = typeof(PageWithModelWithoutHandlers).GetTypeInfo();
|
||||
var descriptor = new PageActionDescriptor();
|
||||
var context = new PageApplicationModelProviderContext(descriptor, typeInfo);
|
||||
|
||||
// Act
|
||||
provider.OnProvidersExecuting(context);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(context.PageApplicationModel);
|
||||
Assert.Same(context.PageApplicationModel.PageType, context.PageApplicationModel.HandlerType);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void OnProvidersExecuting_SetsModelAsHandlerType()
|
||||
{
|
||||
// Arrange
|
||||
var provider = new TestPageApplicationModelProvider();
|
||||
var typeInfo = typeof(PageWithModel).GetTypeInfo();
|
||||
var descriptor = new PageActionDescriptor();
|
||||
var context = new PageApplicationModelProviderContext(descriptor, typeInfo);
|
||||
|
||||
// Act
|
||||
provider.OnProvidersExecuting(context);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(context.PageApplicationModel);
|
||||
Assert.Same(typeof(TestPageModel).GetTypeInfo(), context.PageApplicationModel.HandlerType);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void OnProvidersExecuting_DiscoversPropertiesFromPage()
|
||||
{
|
||||
// Arrange
|
||||
var provider = new TestPageApplicationModelProvider();
|
||||
var typeInfo = typeof(TestPage).GetTypeInfo();
|
||||
var typeInfo = typeof(PageWithModelWithPageModelAttribute).GetTypeInfo();
|
||||
var modelType = typeof(ModelWithPageModelAttribute);
|
||||
var descriptor = new PageActionDescriptor();
|
||||
var context = new PageApplicationModelProviderContext(descriptor, typeInfo);
|
||||
|
||||
|
|
@ -84,19 +204,31 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
context.PageApplicationModel.HandlerProperties.OrderBy(p => p.PropertyName),
|
||||
property =>
|
||||
{
|
||||
Assert.Equal(typeInfo.GetProperty(nameof(TestPage.Property1)), property.PropertyInfo);
|
||||
Assert.Null(property.BindingInfo);
|
||||
Assert.Equal(nameof(TestPage.Property1), property.PropertyName);
|
||||
},
|
||||
property =>
|
||||
{
|
||||
Assert.Equal(typeInfo.GetProperty(nameof(TestPage.Property2)), property.PropertyInfo);
|
||||
Assert.Equal(nameof(TestPage.Property2), property.PropertyName);
|
||||
Assert.Equal(modelType.GetProperty(nameof(ModelWithPageModelAttribute.Property)), property.PropertyInfo);
|
||||
Assert.Equal(nameof(ModelWithPageModelAttribute.Property), property.PropertyName);
|
||||
Assert.NotNull(property.BindingInfo);
|
||||
Assert.Equal(BindingSource.Path, property.BindingInfo.BindingSource);
|
||||
});
|
||||
}
|
||||
|
||||
private class PageWithModelWithPageModelAttribute : Page
|
||||
{
|
||||
public string Property1 { get; set; }
|
||||
|
||||
[FromRoute]
|
||||
public object Property2 { get; set; }
|
||||
|
||||
public ModelWithPageModelAttribute Model => null;
|
||||
public override Task ExecuteAsync() => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
[PageModel]
|
||||
private class ModelWithPageModelAttribute
|
||||
{
|
||||
[FromRoute]
|
||||
public string Property { get; set; }
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void OnProvidersExecuting_DiscoversHandlersFromPage()
|
||||
{
|
||||
|
|
@ -237,7 +369,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
var pageModel = context.PageApplicationModel;
|
||||
Assert.Empty(pageModel.HandlerProperties.Where(p => p.BindingInfo != null));
|
||||
Assert.Empty(pageModel.HandlerMethods);
|
||||
Assert.Same(typeof(EmptyPageWithPageModel).GetTypeInfo(), pageModel.HandlerType);
|
||||
Assert.Same(typeof(EmptyPageModel).GetTypeInfo(), pageModel.HandlerType);
|
||||
Assert.Same(typeof(EmptyPageModel).GetTypeInfo(), pageModel.ModelType);
|
||||
Assert.Same(typeof(EmptyPageWithPageModel).GetTypeInfo(), pageModel.PageType);
|
||||
}
|
||||
|
|
@ -304,9 +436,9 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
|
||||
// Assert
|
||||
var pageModel = context.PageApplicationModel;
|
||||
Assert.Collection(
|
||||
Assert.Contains(
|
||||
pageModel.HandlerProperties,
|
||||
p => Assert.Equal(modelType.GetProperty(nameof(ModelWithHandler.BindMe)), p.PropertyInfo));
|
||||
p => p.PropertyInfo == modelType.GetProperty(nameof(ModelWithHandler.BindMe)));
|
||||
|
||||
Assert.Collection(
|
||||
pageModel.HandlerMethods,
|
||||
|
|
@ -317,7 +449,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
Assert.Same(typeof(PageWithHandlerThatGetsIgnored).GetTypeInfo(), pageModel.PageType);
|
||||
}
|
||||
|
||||
private class ModelWithHandler
|
||||
private class ModelWithHandler : PageModel
|
||||
{
|
||||
[ModelBinder]
|
||||
public int BindMe { get; set; }
|
||||
|
|
@ -325,7 +457,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
public void OnGet() { }
|
||||
}
|
||||
|
||||
private class PageWithHandlerThatGetsIgnored
|
||||
private class PageWithHandlerThatGetsIgnored : Page
|
||||
{
|
||||
public ModelWithHandler Model => null;
|
||||
|
||||
|
|
@ -333,11 +465,12 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
public int IgnoreMe { get; set; }
|
||||
|
||||
public void OnPost() { }
|
||||
|
||||
public override Task ExecuteAsync() => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
[Fact] // If the model has no handler methods, we look at the page instead.
|
||||
public void OnProvidersExecuting_FindsHandlerMethodOnPage_WhenModelHasNoHandlers()
|
||||
[Fact] // If the model does not have the PageModelAttribute, we look at the page instead.
|
||||
public void OnProvidersExecuting_FindsHandlerMethodOnPage_WhenModelIsNotAnnotatedWithPageModelAttribute()
|
||||
{
|
||||
// Arrange
|
||||
var provider = new TestPageApplicationModelProvider();
|
||||
|
|
@ -349,8 +482,10 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
|
||||
// Assert
|
||||
var pageModel = context.PageApplicationModel;
|
||||
var propertiesOnPage = pageModel.HandlerProperties
|
||||
.Where(p => p.PropertyInfo.DeclaringType.GetTypeInfo() == typeInfo);
|
||||
Assert.Collection(
|
||||
pageModel.HandlerProperties.OrderBy(p => p.PropertyName),
|
||||
propertiesOnPage.OrderBy(p => p.PropertyName),
|
||||
p => Assert.Equal(typeInfo.GetProperty(nameof(PageWithHandler.BindMe)), p.PropertyInfo),
|
||||
p => Assert.Equal(typeInfo.GetProperty(nameof(PageWithHandler.Model)), p.PropertyInfo));
|
||||
|
||||
|
|
@ -363,7 +498,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
Assert.Same(typeof(PageWithHandler).GetTypeInfo(), pageModel.PageType);
|
||||
}
|
||||
|
||||
private class PageWithHandler
|
||||
private class PageWithHandler : Page
|
||||
{
|
||||
public PocoModel Model => null;
|
||||
|
||||
|
|
@ -371,22 +506,36 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
public int BindMe { get; set; }
|
||||
|
||||
public void OnGet() { }
|
||||
|
||||
public override Task ExecuteAsync() => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private class PocoModel
|
||||
{
|
||||
// Just a plain ol' model, nothing to see here.
|
||||
|
||||
[ModelBinder]
|
||||
public int IgnoreMe { get; set; }
|
||||
|
||||
public void OnGet() { }
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateHandlerModels_DiscoversHandlersFromBaseType()
|
||||
public void PopulateHandlerMethods_DiscoversHandlersFromBaseType()
|
||||
{
|
||||
// Arrange
|
||||
var provider = new TestPageApplicationModelProvider();
|
||||
var typeInfo = typeof(InheritsMethods).GetTypeInfo();
|
||||
var baseType = typeof(TestSetPageModel);
|
||||
var pageModel = new PageApplicationModel(new PageActionDescriptor(), typeInfo, new object[0]);
|
||||
|
||||
// Act
|
||||
var handlerModels = provider.CreateHandlerModels(typeInfo);
|
||||
provider.PopulateHandlerMethods(pageModel);
|
||||
|
||||
// Assert
|
||||
var handlerMethods = pageModel.HandlerMethods;
|
||||
Assert.Collection(
|
||||
handlerModels.OrderBy(h => h.MethodInfo.DeclaringType.Name).ThenBy(h => h.MethodInfo.Name),
|
||||
handlerMethods.OrderBy(h => h.MethodInfo.DeclaringType.Name).ThenBy(h => h.MethodInfo.Name),
|
||||
handler =>
|
||||
{
|
||||
Assert.Equal(nameof(InheritsMethods.OnGet), handler.MethodInfo.Name);
|
||||
|
|
@ -423,18 +572,20 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateHandlerModels_IgnoresNonPublicMethods()
|
||||
public void PopulateHandlerMethods_IgnoresNonPublicMethods()
|
||||
{
|
||||
// Arrange
|
||||
var provider = new TestPageApplicationModelProvider();
|
||||
var typeInfo = typeof(ProtectedModel).GetTypeInfo();
|
||||
var baseType = typeof(TestSetPageModel);
|
||||
var pageModel = new PageApplicationModel(new PageActionDescriptor(), typeInfo, new object[0]);
|
||||
|
||||
// Act
|
||||
var handlerModels = provider.CreateHandlerModels(typeInfo);
|
||||
provider.PopulateHandlerMethods(pageModel);
|
||||
|
||||
// Assert
|
||||
Assert.Empty(handlerModels);
|
||||
var handlerMethods = pageModel.HandlerMethods;
|
||||
Assert.Empty(handlerMethods);
|
||||
}
|
||||
|
||||
private class ProtectedModel
|
||||
|
|
@ -449,17 +600,19 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateHandlerModels_IgnoreGenericTypeParameters()
|
||||
public void PopulateHandlerMethods_IgnoreGenericTypeParameters()
|
||||
{
|
||||
// Arrange
|
||||
var provider = new TestPageApplicationModelProvider();
|
||||
var typeInfo = typeof(GenericClassModel).GetTypeInfo();
|
||||
var pageModel = new PageApplicationModel(new PageActionDescriptor(), typeInfo, new object[0]);
|
||||
|
||||
// Act
|
||||
var handlerModels = provider.CreateHandlerModels(typeInfo);
|
||||
provider.PopulateHandlerMethods(pageModel);
|
||||
|
||||
// Assert
|
||||
Assert.Empty(handlerModels);
|
||||
var handlerMethods = pageModel.HandlerMethods;
|
||||
Assert.Empty(handlerMethods);
|
||||
}
|
||||
|
||||
private class GenericClassModel
|
||||
|
|
@ -470,19 +623,21 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateHandlerModels_IgnoresStaticMethods()
|
||||
public void PopulateHandlerMethods_IgnoresStaticMethods()
|
||||
{
|
||||
// Arrange
|
||||
var provider = new TestPageApplicationModelProvider();
|
||||
var typeInfo = typeof(PageModelWithStaticHandler).GetTypeInfo();
|
||||
var expected = typeInfo.GetMethod(nameof(PageModelWithStaticHandler.OnGet), BindingFlags.Public | BindingFlags.Instance);
|
||||
var pageModel = new PageApplicationModel(new PageActionDescriptor(), typeInfo, new object[0]);
|
||||
|
||||
// Act
|
||||
var handlerModels = provider.CreateHandlerModels(typeInfo);
|
||||
provider.PopulateHandlerMethods(pageModel);
|
||||
|
||||
// Assert
|
||||
var handlerMethods = pageModel.HandlerMethods;
|
||||
Assert.Collection(
|
||||
handlerModels,
|
||||
handlerMethods,
|
||||
handler => Assert.Same(expected, handler.MethodInfo));
|
||||
}
|
||||
|
||||
|
|
@ -498,19 +653,21 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateHandlerModels_IgnoresAbstractMethods()
|
||||
public void PopulateHandlerMethods_IgnoresAbstractMethods()
|
||||
{
|
||||
// Arrange
|
||||
var provider = new TestPageApplicationModelProvider();
|
||||
var typeInfo = typeof(PageModelWithAbstractMethod).GetTypeInfo();
|
||||
var expected = typeInfo.GetMethod(nameof(PageModelWithAbstractMethod.OnGet), BindingFlags.Public | BindingFlags.Instance);
|
||||
var pageModel = new PageApplicationModel(new PageActionDescriptor(), typeInfo, new object[0]);
|
||||
|
||||
// Act
|
||||
var handlerModels = provider.CreateHandlerModels(typeInfo);
|
||||
|
||||
provider.PopulateHandlerMethods(pageModel);
|
||||
|
||||
// Assert
|
||||
var handlerMethods = pageModel.HandlerMethods;
|
||||
Assert.Collection(
|
||||
handlerModels,
|
||||
handlerMethods,
|
||||
handler => Assert.Same(expected, handler.MethodInfo));
|
||||
}
|
||||
|
||||
|
|
@ -524,19 +681,21 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateHandlerModels_IgnoresMethodWithNonHandlerAttribute()
|
||||
public void PopulateHandlerMethods_IgnoresMethodWithNonHandlerAttribute()
|
||||
{
|
||||
// Arrange
|
||||
var provider = new TestPageApplicationModelProvider();
|
||||
var typeInfo = typeof(PageWithNonHandlerMethod).GetTypeInfo();
|
||||
var expected = typeInfo.GetMethod(nameof(PageWithNonHandlerMethod.OnGet), BindingFlags.Public | BindingFlags.Instance);
|
||||
var pageModel = new PageApplicationModel(new PageActionDescriptor(), typeInfo, new object[0]);
|
||||
|
||||
// Act
|
||||
var handlerModels = provider.CreateHandlerModels(typeInfo);
|
||||
provider.PopulateHandlerMethods(pageModel);
|
||||
|
||||
// Assert
|
||||
var handlerMethods = pageModel.HandlerMethods;
|
||||
Assert.Collection(
|
||||
handlerModels,
|
||||
handlerMethods,
|
||||
handler => Assert.Same(expected, handler.MethodInfo));
|
||||
}
|
||||
|
||||
|
|
@ -558,13 +717,15 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
// Arrange
|
||||
var provider = new TestPageApplicationModelProvider();
|
||||
var typeInfo = typeof(PageModelWithHandlerNames).GetTypeInfo();
|
||||
var pageModel = new PageApplicationModel(new PageActionDescriptor(), typeInfo, new object[0]);
|
||||
|
||||
// Act
|
||||
var handlerModels = provider.CreateHandlerModels(typeInfo);
|
||||
provider.PopulateHandlerMethods(pageModel);
|
||||
|
||||
// Assert
|
||||
var handlerMethods = pageModel.HandlerMethods;
|
||||
Assert.Collection(
|
||||
handlerModels.OrderBy(h => h.MethodInfo.Name),
|
||||
handlerMethods.OrderBy(h => h.MethodInfo.Name),
|
||||
handler =>
|
||||
{
|
||||
Assert.Same(typeInfo.GetMethod(nameof(PageModelWithHandlerNames.OnPutDeleteAsync)), handler.MethodInfo);
|
||||
|
|
@ -591,12 +752,14 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
var provider = new TestPageApplicationModelProvider();
|
||||
var typeInfo = typeof(PageWithHandlerParameters).GetTypeInfo();
|
||||
var expected = typeInfo.GetMethod(nameof(PageWithHandlerParameters.OnPost));
|
||||
var pageModel = new PageApplicationModel(new PageActionDescriptor(), typeInfo, new object[0]);
|
||||
|
||||
// Act
|
||||
var handlerModels = provider.CreateHandlerModels(typeInfo);
|
||||
provider.PopulateHandlerMethods(pageModel);
|
||||
|
||||
// Assert
|
||||
var handler = Assert.Single(handlerModels);
|
||||
var handlerMethods = pageModel.HandlerMethods;
|
||||
var handler = Assert.Single(handlerMethods);
|
||||
|
||||
Assert.Collection(
|
||||
handler.Parameters,
|
||||
|
|
@ -743,14 +906,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
}
|
||||
}
|
||||
|
||||
private class TestPage
|
||||
{
|
||||
public string Property1 { get; set; }
|
||||
|
||||
[FromRoute]
|
||||
public object Property2 { get; set; }
|
||||
}
|
||||
|
||||
private class PageWithModelWithoutHandlers : Page
|
||||
{
|
||||
public ModelWithoutHandler Model { get; }
|
||||
|
|
@ -775,6 +930,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
public override Task ExecuteAsync() => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
[PageModel]
|
||||
private class TestPageModel
|
||||
{
|
||||
public string Property1 { get; set; }
|
||||
|
|
|
|||
|
|
@ -1,17 +0,0 @@
|
|||
// 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.
|
||||
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||
{
|
||||
public partial class DefaultPageApplicationModelProviderTest
|
||||
{
|
||||
private class PocoModel
|
||||
{
|
||||
// Just a plain ol' model, nothing to see here.
|
||||
|
||||
[ModelBinder]
|
||||
public int IgnoreMe { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
// 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.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure;
|
||||
|
||||
namespace RazorPagesWebSite
|
||||
{
|
||||
[PageModel]
|
||||
public class HelloWorldWithPageModelAttributeModel
|
||||
{
|
||||
public string Message { get; set; }
|
||||
|
||||
public void OnGet(string message)
|
||||
{
|
||||
Message = message;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
@page
|
||||
@model RazorPagesWebSite.HelloWorldWithPageModelAttributeModel
|
||||
Hello, @Model.Message!
|
||||
|
|
@ -10,7 +10,7 @@ using Microsoft.AspNetCore.Mvc.RazorPages;
|
|||
namespace RazorPagesWebSite
|
||||
{
|
||||
[HandlerChangingPageFilter]
|
||||
public class ModelWithPageFilter
|
||||
public class ModelWithPageFilter : PageModel
|
||||
{
|
||||
public string Message { get; private set; }
|
||||
|
||||
|
|
|
|||
|
|
@ -2,11 +2,12 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
|
||||
namespace RazorPagesWebSite
|
||||
{
|
||||
[AllowAnonymous]
|
||||
public class AnonymousModel
|
||||
public class AnonymousModel : PageModel
|
||||
{
|
||||
public void OnGet()
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue