Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I Create a Controller instance manually, then run it as a user?

For example, from a controller I want to do something like this:

var controller = new SomeController(); //different controller
//as of now, the controller.User is null, I want to set it
controller.DoSomething();

I want to set the User as it uses the roles to decide what to do here. I would prefer to leave all the role handling in that controller (not my code). Is there any way to set the User? Or possibly run it as the same user as I am calling this from another controller in the same MVC project?

EDIT: My solution after Sergey's help, in my Controller BaseClass:

public T RunControllerAsCurrentUser<T>(T controller, RouteData routeData = null) where T : ControllerBase
{
    var newContext = new ControllerContext(new HttpContextWrapper(System.Web.HttpContext.Current), routeData ?? new RouteData(), controller);
    controller.ControllerContext = newContext;
    return controller;
}

Then to use it:

var someController = RunControllerAsCurrentUser(new Some.NameSpace.SomeController());
var result = someController.SomeAction();
like image 919
naspinski Avatar asked Dec 11 '14 22:12

naspinski


People also ask

Can we create object of Controller in MVC?

ASP.NET MVC framework itself creates controller objects at run time. There is only one prerequisite, that is controller class must have a parameter less constructor.

Which component in ASP.NET MVC can be used to pass data between Controller to view assume you have to pass current date and time?

To pass data from the controller to view, either ViewData or ViewBag can be used. To pass data from one controller to another controller, TempData can be used.

Which component helps Controller send the data to view?

By using ViewBag, we can pass the data from Controller to View.


1 Answers

It depends what your method is using. If you just need to execute method then you can try something like that:

var factory = DependencyResolver.Current.GetService<IControllerFactory>() ?? new DefaultControllerFactory();
TestController controller = factory.CreateController(this.ControllerContext.RequestContext, "Test") as TestController;

RouteData route = new RouteData();
route.Values.Add("action", "Test"); // ActionName, but it not required

ControllerContext newContext = new ControllerContext(new HttpContextWrapper(System.Web.HttpContext.Current), route, controller);
controller.ControllerContext = newContext;
ActionResult result = controller.Test();

This approach will do some basic controller initialization, but if your method uses some parameters, or request specific data, then it might require specifying them in RouteData.Values.

Try this approach and tell in comments if it works for you or not.

like image 93
Sergey Litvinov Avatar answered Oct 13 '22 07:10

Sergey Litvinov