How to use DataTokens in ASP.NET Core 3.1 when performing dynamic routing? - asp.net-core

I am using the class DynamicRouteValueTransformer built into ASP.NET Core 3.1 to perform dynamic controller routing as demonstrated in the code below.
public class UrlRouteTransformer : DynamicRouteValueTransformer
{
public override ValueTask<RouteValueDictionary> TransformAsync(HttpContext httpContext, RouteValueDictionary values)
{
var controller = "home";
var action = "index";
//Make decision here on which controller and action to call. i.e call the database etc
values["controller"] = controller;
values["action"] = action;
return new ValueTask<RouteValueDictionary>(values);
}
}
This code is working as expected, but I want to know how you would set data tokens?

Related

Can Blazor Use Custom IAuthorizationFilter

Hi I was trying to use TypeFilter and IAuthorizationFilter like discussed in these post:
How do you create a custom AuthorizeAttribute in ASP.NET Core? and How to include multiple policies
for blazor (server side, not blazor wasm, not asp.net core), but the IAuthorizationFilter is never executed.
I want to use IAuthorizationFilter, because using custom policy requirement and IAuthorizationHandler is so not flexible.
I cannot find explicitly that IAuthorizationFilter and Blazor don't work together, every keyword using blazor and custom filter only point to using that policy requirement IAuthorizationRequirement.
So anybody has their blazor server side application works with IAuthorizationFilter? would you mind sharing your resources.
Thank you.
updated:
This is the codes I used from https://stackoverflow.com/a/43788693/423356
public enum PermissionItem
{
User,
Product,
Contact,
Review,
Client
}
public enum PermissionAction
{
Read,
Create,
}
public class AuthorizeAttribute : TypeFilterAttribute
{
public AuthorizeAttribute(PermissionItem item, PermissionAction action)
: base(typeof(AuthorizeActionFilter))
{
Arguments = new object[] { item, action };
}
}
public class AuthorizeActionFilter : IAuthorizationFilter
{
private readonly PermissionItem _item;
private readonly PermissionAction _action;
public AuthorizeActionFilter(PermissionItem item, PermissionAction action)
{
_item = item;
_action = action;
}
public void OnAuthorization(AuthorizationFilterContext context)
{
bool isAuthorized = MumboJumboFunction(context.HttpContext.User, _item, _action); // :)
if (!isAuthorized)
{
context.Result = new ForbidResult();
}
}
}
This is how I declare in my blazor server side .NET 5.0 page:
#attribute [Authorize]
#attribute [Authorize(PermissionItem.User, PermissionAction.Read)]
Using Custom policy requirement works but not flexible, as explained better in my 2 sources above.

How to find controller name in ASP.NET Core

How to find the controller name in ASP.NET Core?
I googled it, very first I got the solution ControllerContext.ActionDescriptor.ControllerName.
But in my ASP.NET Core application, ControllerContext is not showing any properties.
Please help me.
If you're using ASP.NET Core 3+, you can utilize endpoint routing and get the current endpoint inside a controller action.
Controller actions have a ControllerActionDescriptor metadata, which provides you info about the action.
[ApiController]
[Route("")]
public class HelloController : ControllerBase
{
[HttpGet]
public async Task<IActionResult> Index(CancellationToken cancellationToken)
{
var endpoint = HttpContext.GetEndpoint();
var actionDescriptor = endpoint!.Metadata.OfType<ControllerActionDescriptor>().First()!;
var controllerName = actionDescriptor.ControllerName;
// -> gives you "Hello"
return Ok(controllerName);
}
}
If you're looking for the fully-qualified name, you can use the controller type info
var controllerFullName = actionDescriptor.ControllerTypeInfo.FullName;
// -> gives you "ApiPlayground.HelloController"

How to modify ViewComponent result in ASP.NET Core 3.1

I want to modify the result of ViewComponent by using a filter as we do with MVC ActionFiltersAttribute. I've tried ActionFilterAttribute but it's not working with ViewComponent even it's not calling.
public class BeforeCheckoutCallFilter : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext context)
{
if (context.RouteData.Values["action"].ToString().Equals("ProductDetails_AttributeChange", StringComparison.InvariantCultureIgnoreCase))
{
//Business logic
}
return;
}
}
I'm registering this filter inside Startup.cs
public void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
services.Configure<MvcOptions>(options =>
{
options.Filters.Add<BeforeCheckoutCallFilter>();
}
}
Is there a way to get the ViewComponent result and modify it as we were used to doing with MVC filters?
Updated: I want to intercept the call after returning IViewComponentResult.
Note: I've got know that the ViewComponent does not take part in the controller lifecycle, which means we can’t use filters in a view component.
There is no support for direct interception of ViewComponents, as it does not take part of the request pipeline. From the official doc:
A view component class:
Doesn't take part in the controller lifecycle, which means you can't use filters in a view component
But you can do it indirectly by invoking the ViewComponent from an Action instead. Then decorate the Action with your Filter:
[BeforeCheckoutCall]
public IActionResult Checkout()
{
return ViewComponent("PriorityList", new { maxPriority = 3, isDone = false });
}

Inject validator in ASP.NET core filter

I have the following ASP.NET Core controller action:
public async Task<IActionResult> Post([FromBody]Model model) {
IValidator<Model> validator = new Validator<Model>();
if (!validator.IsValid)
return await validation.ToErrorResponse();
// Remaining code
}
I configured ASP.NET core to inject IValidator on Startup.
I would like to make the validation automatic using a filter:
public class ValidateAttribute : ActionFilterAttribute {
public overrideTask OnActionExecutionAsync(
ActionExecutingContext context,
ActionExecutionDelegate next) {
}
}
Inside the filter I need to request the correct Validator according to the Model being submitted and returning the errors.
How can I get the validator and the model being submitted inside the filter?

Ninject for Asp.net Web API

I got this error when using Ninject with Web API, but it works with MVC Controller:
Type 'App.Web.Controllers.ProductController' does not have a default constructor
NinjectControllerFactory :
public class NinjectControllerFactory : DefaultControllerFactory
{
private IKernel ninjectKernel;
public NinjectControllerFactory()
{
ninjectKernel = new StandardKernel();
AddBindings();
}
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
return controllerType == null ? null : (IController)ninjectKernel.Get(controllerType);
}
public void AddBindings()
{
ninjectKernel.Bind<IProductRepository>().To<EFProductRepository>();
}
}
Global.asax.cs :
BundleConfig.RegisterBundles(BundleTable.Bundles);
ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
ProductController :
public class ProductController : ApiController
{
private IProductRepository repository;
public ProductController(IProductRepository ProducteRepository)
{
this.repository = ProductRepository;
}
public IEnumerable<Product> GetAllProducts()
{
return repository.Products.AsEnumerable();
}
}
You have overriden the DefaultControllerFactory. But this is used to instantiate ASP.NET MVC controllers (one deriving from System.Web.Mvc.Controller). It has strictly nothing to do with ASP.NET Web API controllers (the ones deriving from System.Web.Http.ApiController).
So basically what you have done here is dependency injection into ASP.NET MVC. If you want to use this for the Web API you may take a look at the following guides:
http://www.strathweb.com/2012/05/using-ninject-with-the-latest-asp-net-web-api-source/
http://www.peterprovost.org/blog/2012/06/19/adding-ninject-to-web-api/
You should use the latest Ninject Web API package, which solves these problems already. See here: http://nuget.org/packages/Ninject.Web.WebApi.WebHost/
You need to set DependencyResolver property of the HttpConfiguration. What you have done was for ASP.NET MVC and not ASP.NET Web API.
So get the NuGet package and set DependencyResolver:
var kernel = new StandardKernel();
// use kernel to register your dependencies
var dependencyResolver = new NInjectResolver(kernel);
config.DependencyResolver = dependencyResolver; // config is an instance of HttpConfiguration based on your hosting scenario