0

I can't get route value in controller constructor, if I run same line in any function it's working great but inside constructor not working, any ideas please:

[RoutePrefix("st/{id}")]

public class USERsController : ApiController
{
    private Entities db = new Entities();
    
    public USERsController()
    {
        var routeValue = ControllerContext.RouteData.Values["id"]; // getting error here *****
        db.Configuration.ProxyCreationEnabled = false;            
    }
}
  • Does this answer your question? [What is a NullReferenceException, and how do I fix it?](https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – Roman Marusyk Nov 18 '20 at 23:50
  • 1
    An object isn't even created until *after* the constructor exits. There's no request or route at that point. Why are you trying to handle the request in the controller instead of an action? – Panagiotis Kanavos Nov 19 '20 at 09:38
  • I suggest you follow one of the documentation tutorials, eg [Adding a Controller](https://docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started/introduction/adding-a-controller) before writing your own code. No tutorials show processing a request in the constructor. All make it explicit that requests are processed by actions. – Panagiotis Kanavos Nov 19 '20 at 09:40

1 Answers1

-1

To begin with, please read this: https://www.davidhayden.me/blog/asp-net-mvc-5-attribute-routing

In order to get the route value for parameter id in your question, you should:

  1. set RoutePrefix on your Class to [RoutePrefix("st")]
  2. set route on your method to [Route("{id:int}")]

Once that is done, you will get your value on the line where you used to get the null reference exception.

Here is a screenshot of the value during debug session: enter image description here

I called the API from Postman like so:

enter image description here

Updated Answer

If you really want to get the value in the constructor, the following (not recommended) will do the trick:

var routeValues = (IHttpRouteData[])HttpContext.Current.Request.RequestContext.RouteData.Values["MS_SubRoutes"]; 
var theValueWeAreLookingFor = routeValues.SelectMany(x => x.Values).Where(x => x.Key == "id").Select(x => x.Value).FirstOrDefault();

Thanks to https://stackoverflow.com/users/134204/panagiotis-kanavos for remarks regarding Constructor.

Okta
  • 60
  • 10
  • There's no `Request` in the constructor yet. The NRE will remain – Panagiotis Kanavos Nov 19 '20 at 09:24
  • The NRE will not remain, take a look at the screenshot from my debug session. – Okta Nov 19 '20 at 09:34
  • There's no constructor in that screenshot. You're proving that the OP should use an Action, not a constructor. – Panagiotis Kanavos Nov 19 '20 at 09:36
  • You're right, my answer does not work directly in the constructor, and frankly, doing so in the constructor is just wrong and slower. If he wants to do it in the constructor, then the following will get the value: var routeValues = (IHttpRouteData[])HttpContext.Current.Request.RequestContext.RouteData.Values["MS_SubRoutes"]; var theValueWeAreLookingFor = routeValues.SelectMany(x => x.Values).Where(x => x.Key == "id").Select(x => x.Value).FirstOrDefault(); – Okta Nov 19 '20 at 10:20
  • Thank you very much, you saved my day!. var routeValues = (IHttpRouteData[])HttpContext.Current.Request.RequestContext.RouteData.Values["MS_SubRoutes"]; var theValueWeAreLookingFor = routeValues.SelectMany(x => x.Values).Where(x => x.Key == "id").Select(x => x.Value).FirstOrDefault(); – Waleed Al-Yazidi Nov 20 '20 at 17:31
  • but why it's not recommended? – Waleed Al-Yazidi Nov 20 '20 at 17:32
  • Take this with a grain of salt, but it is not recommended because it seems to be ~6 times slower than doing it in an Action. Feel free to run the test yourself and compare. – Okta Nov 20 '20 at 21:08