1

In my asp.net core web API, i want to access variable in my controller. The variable will set while GetAllStudents method running. StudentController and StudentRepository is in same solution but different project. How can i access from StudentRepository.cs to variable in StudentController.cs? There is some solution for MVC, but i can't find for web API. So, question is not duplicate.

StudentController.cs :

 int requestedUserId;

 [HttpGet("GetAllStudents")]
 public async Task<ServiceResult>GetAllStudents()
    {
        requestedUserId= context.HttpContext.Request.Headers["Authorization"];
        return await (studentService.GetAllStudents(requestedUserId));
    }

StudentService.cs :

 public async Task<ServiceResult> GetAllStudents()
    {
        return await unitOfWork.studentRepo.GetAllStudents();
    }

StudentRepository.cs :

public async Task<List<Student>> GetAllStudents()
    {
        ?????var requestedUserId= StudentController.requestedUserId;?????
        LogOperation(requestedUserId);
        return context.Students.ToList();
    }

2 Answers 2

1

You can just pass it in.

GetAllStudents(int userId)


Update:

Re: Thanks for your reply. But this variable is used every method in every controller. So i don't want write everywhere (int userId).

You should pass it to every method that needs it:

  1. It's a common pattern
  2. Methods don't depend on a controller
  3. Passing it is actually less code than: var requestedUserId= StudentController.requestedUserId;?????
Sign up to request clarification or add additional context in comments.

12 Comments

And it's probably worth noting that it doesn't make sense it being a class-scoped variable.
Thanks for your reply. But this variable is used every method in every controller. So i don't want write everywhere (int userId). I ask this question for this reason @John
@Hasan but the API calls are stateless, so in each API method you're assigning it requestedUserId= context.HttpContext.Request.Headers["Authorization"];. Are you asking how to avoid that?
@HasanOzdemir It's absolutely amazing that a product you're working on manged to ignore authentication until it has 5000 operations!
@HasanOzdemir If your requirement is to log user details for database operations, you should use log context. It is easier to write a middleware for pushing custom properties(user details) into log context and log them wherever required.
|
0

I found the solution. The solution is "IHttpContextAccessor". You can inject by dependency injection and then you can use from everywhere (forexample dbcontext class)

public class StudentService : IStudentService
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public StudentService(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

public async Task<List<Student>> GetAllStudents()
    {
        var requestedUserId= _httpContextAccessor.HttpContext.Headers["Authorization"];
        LogOperation(requestedUserId);
        return context.Students.ToList();
    }
}

3 Comments

How is adding var requestedUserId= _httpContextAccessor.HttpContext.Headers["Authorization"]; easier than passing the value in?
Because writing only one time instead of 30.000 times. Forexample, architecture in question, there are 10 method in controller.cs. Then 10 method in service.cs which is called from controller. Then 40 methods in repository.cs which called from service. If i write like you, i must add parameter UserId said for every method (60 times). @tymtam
But if use IHttpContextAccessor, I write repository.cs only one time. And then call it if i need. If you want also, you can do global by writing DbContext on overrided saveChanges method. And for every database operation it automatically trigger. So, by your solution, if i have 30.000 method in my application, then i must write more than 30.000 row code. But in "IHttpContextAccessor" solution you will write only 4 row code. It is easily understandable that 4 much more smaller and easier than 30000. @tymtam

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.