Search code examples
asp.netasp.net-core-mvcasp.net-mvc-routing

How to bind an ASP.NET controller property with part of the current URL?


I'm using netcoreapp1.1 (aspnetcore 1.1.1).

I would like to bind a part of the url to a controller property and not in an action parameter, is it possible?

Ex: GET: https://www.myserver.com/somevalue/users/1

public class UsersController {
    public string SomeProperty {get;set;} //receives "somevalue" here

    public void Index(int id){ 
        //id = 1
    } 
}

Solution

  • It's possible with action filter:

    [Route("{foo}/[controller]/{id?}")]
    [SegmentFilter]
    public class SegmentController : Controller
    {
        public string SomeProperty { get; set; }
    
        public IActionResult Index(int id)
        {
        }
    }
    
    public class SegmentFilter : ActionFilterAttribute, IActionFilter
    {
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            //path is "/bar/segment/123"
            string path = context.HttpContext.Request.Path.Value;
    
            string[] segments = path.Split(new[]{"/"}, StringSplitOptions.RemoveEmptyEntries);
    
            //todo: extract an interface containing SomeProperty
            var controller = context.Controller as SegmentController;
    
            //find the required segment in any way you like
            controller.SomeProperty = segments.First();
        }
    }
    

    Then the request path "myserver.com/bar/segment/123" will set SomeProperty to "bar" before action Index is executed.