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"
Related
I'm migrating some old ASP.NET MVC 5 code to .NET 6.0 and having some trouble with an AuthorizationFilter that, within its OnAuthorization implementation, accesses the decorated method's controller class instance, like this:
// Get the decorated method's name
string actionName = filterContext.ActionDescriptor.ActionName;
// Get the controller instance and then, its type
Type controllerType = filterContext.Controller.GetType();
I just canĀ“t see how I would get the controller instance (or event the method's name) from the AuthorizationFilterContext available in .NET 6.0. Any help?
create new class
public class LogEntry : IAuthorizationFilter
{
public void OnAuthorization(AuthorizationFilterContext context)
{
var controllerActionDescriptor = context.ActionDescriptor as
ControllerActionDescriptor;
string controllerName =
controllerActionDescriptor?.ControllerName;
string actionName =
controllerActionDescriptor?.ActionName;
}
}
In Program.cs register LogEntry class
builder.Services.AddScoped<LogEntry>();
on controller action method
[ServiceFilter(typeof(LogEntry))]
public IActionResult Index()
{
return View();
}
I want to use api version in my .net core project.Then search web and find that's solution.
Even though do exactly all solutions,but I can't get desired result.
So if any can help me,Please show me..
I add Microsoft.AspNetCore.Mvc.Versioning 4.0.0 Package in my project and ..
StartUp.cs
Then in my Controller Add Rout Attribute as Shown :
[ApiController]
[Authorize]
[Route("v{version:apiVersion}/[Controller]")]
[ApiVersion("1.0")]
public class SellerController : Controller
{
private readonly IBus _client;
private readonly string AppBaseUrl = MyHttpContext.AppBaseUrl;
//private readonly IGetUrl _globalUrl;
public SellerController(IBus client/*, IGetUrl globalUrl*/)
{
_client = client;
//_globalUrl = globalUrl;
}
[HttpGet("/Sellers/{SellerId}")] // Dashboard
public async Task<IActionResult> Info(long SellerId)
{
...
}
}
With these code I expected that I can send request to 'Info' method by this url :
But that's not working and get 404 error code status.. when I delete "/v1.0" from url and send request, that's working. I will be glad to help me .. Thanks
In your code, we can find that you applied [HttpGet("/Sellers/{SellerId}")] with route
template begin with / to Info action method, which don't get combined with route templates applied to the controller. To make request to 'Info' method, you could use below URL.
https://localhost:5090/sellers/17
I expected that I can send request to 'Info' method by this url : https://localhost:5090/v1.0/sellers/17
To achieve your requirement, you can try to modify the code like below.
[HttpGet("/v{version:apiVersion}/Sellers/{SellerId}")]
public async Task<IActionResult> Info(long SellerId)
{
//...
//for testing purpose
return Ok(SellerId);
}
Test Result
Update:
If you'd like to include v{version:apiVersion} in route template of controller level attribute routing, you can try to apply [HttpGet("{SellerId}")] to Info action method and make request with https://localhost:5090/v1.0/seller/17.
[ApiController]
[Authorize]
[Route("v{version:apiVersion}/[Controller]")]
[ApiVersion("1.0")]
public class SellerController : Controller
{
[HttpGet("{SellerId}")] // Dashboard
public async Task<IActionResult> Info(long SellerId)
{
//...
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?
As per description on title, I have created a class which derived from ClaimsPrincipal and have additional properties:
public class CustomeUser: ClaimsPrincipal
{
// additional properties
}
Wrote a middleware and assigned values to that from the claims:
public async Task Invoke(HttpContext context)
{
// context to read header and assign to custome properties
context.User = new CustomeUser() {
ClientIP = /*reading from claims*/,
UserId = /*reading from claims*/};
}
and in configuration service add following line to get HttpContext to fetch that custom user properties from controller in start up class.
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
from controller to fetch custome user properties
public BaseController(IHttpContextAccessor httpContextAccessor)
{
customeUser = httpContextAccessor.HttpContext.User as CustomeUser;
}
Is this a correct approach?
You don't need IHttpContextAccessor if you access HttpContext from a controller. Microsoft.AspNetCore.Mvc.ControllerBase class from which controllers inherit (through Controller class) has HttpContext property. So your code could be changed as:
public BaseController()
{
customeUser = HttpContext.User as CustomeUser;
}
All the rest seems good. HttpContext.User will contain instance of CustomeUser that you filled in Invoke() method so that nasty type conversion to CustomeUser will work just fine.
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?