Search code examples
c#asp.net-mvc-4httpcontext

Accessing an Attribute in a different Controller Class


I have an field is a Controller Class(User) that keeps track of the current User. In a different Controller Class (Blog) I want to access that attribute(CurrentUser) but the issue is that I have to create a new instance of the controller class which doesn't work. Is there a good way to access this attribute without creating a new class?

Here is an example:

User Controller Class:

public class UserController : Controller 
{
    public int CurrentUserId = -1; // This line as been removed

    //Methods go below
    // ...

    public void Login(User user)
    {
           HttpContext.Items["UserId"] = user.Id;
    }

Blog Controller Class:

public class BlogController : Controller
{
    public ActionResult NewBlogPost(Article ArticleToCreate)
    {
         ArticleToCreate.AudthorId = (int)HttpContext.Items["UserId"];
    }
}

Solution

  • First, I don't think that you really mean to Attribute, but to Field.

    This is how a Attribute looks like:

    [HelpAttribute("http://localhost/MyClassInfo")]
    

    And this is how a Field looks like:

    public int CurrentUserId = -1;
    

    Second, if all you need is the user details, use the User property: HttpContext.Current.User in your Action context.

    You can use it in any Controller, since HttpContext is a Controller property (this.HttpContext).

    As for sharing other controllers data, I don't think that it make any sense because each new request initialize another Controller class instance, HTTP is stateless.

    In addition, in order to add extra user's details, like: UserId, use the HttpContext.Items Dictionary property, This data will be available for you in any controller, at any new request, just like the User property, for example:

    HttpContext.Items["UserId"] = 200;
    

    UPDATE

    In order to be able to access the HttpContext.Items property at any Conroller's Action, set it in the Application_BeginRequest handler in the Global.asax file and not in the Controller, as you did:

    protected void Application_BeginRequest(Object sender, EventArgs e)
    {     
      int userId = //Logic to retrieve the `UserId`.
      Context.Items["UserId"] = userId;
    }
    

    This is an ideal spot to load request specific state to carry through until ASP.NET MVC completes the request.