Execute action without redirect - asp.net-mvc

I have a little question to community. Does ASP.NET MVC allow to execute an action of another controller without RedirectToAction() method and without creation of an instance of this controller?

This is impossible. For an instance method to execute there must be an instance to execute in. Action methods are simply methods like all other methods, so you always need an instance to call the method.

Do you mean you wish to have a View which returns nothing. No view. No nadda?
If so, u can return a EmptyResult ViewResult class...
HTH.

You can call it through the Reflection technic, But It's Not Recommended. Shortly because it's not in the request/response/controller context.
Personally, I prefer to have an internal static method(bla bla){...} and call it where ever i want.
But if you drop the
without creation of an instance of this controller
Clause, Then you can use this methodology. But as it explains, It's Not Recommended Too. the following is summarized:
var controller = new FooController();
controller.ControllerContext = new ControllerContext(this.ControllerContext.RequestContext, controller);
var jsonResult = controller.BlaMethod(someInputParams);

Related

How do I call a specific Controller Action to test code within it, especially session variables?

I am using MVC5 on ASP.NET 4.5
I want to debug specific Controller Actions without running the whole application where I would need to know how to navigate to the specific Action, in addition to it taking much time, since I have much code to refactor and test.
I have considered Unit Tests, but using the debugger seems more appropriate for what I am doing.
Also I have session variables within the Action Code.
The closest I have come to a solution is to have a wrapper Action in Home ie:
public ActionResult Tx()
{
return new MyApp.Areas.Area1.Controllers.OrderController().Index();
}
I would then copy and paste the relevant Namespace, Controller and Action with any relevant parms into the "Tx" Action.
This does invoke the relevant Action without me needing to navigate to the specific Action. I just call Home/Tx. However I am getting null exception errors with my Session variable code:
Session["OrderID"]=null
Debugging the Action, with the Session variables works fine when I navigate directly from the application. When I use Home/Tx it is still on the Dev Web Server and within the Debug process, but perhaps I am in a new context as another Action is creating the Controller.
1) Any idea why my idea does not work with Session variables?
2) If anybody has a better idea on how to invoke specific Controller Actions then I would appreciate that.
Thanks.
You need to call the Initialize method on your controller before using it. Try something like:
var httpContext = new HttpContextWrapper(HttpContext.Current);
var routeData = RouteTable.Routes.GetRouteData(httpContext);
var controller = new MyApp.Areas.Area1.Controllers.OrderController();
controller.Initialize(new RequestContext(httpContext, routeData));
return controller.Index();

How to use ActionInvoker.InvokeAction? - ASP.Net

I am new to MVC ASP.NET and needed to call an action from one controller in an action of another controller. There I created object of controller and called my required action as below,
controllerOne co = new controllerOne();
co.requiredFunction();
but one of my senior advised me to not use this approach, which kills the MVC pattern use its given ActionInvoker.InvokeAction() function to call function of other controller and I am using now as below,
public class HomeController : Controller
{
this.ActionInvoker.InvokeAction(new System.Web.Mvc.ControllerContext(
this.ControllerContext.RequestContext, new controllerOne()),
"requiredAction");
}
This works fine, but I don't know if the way I am using ActionInvoker.InvokeAction() is correct. I searched to find any example but I could find any.
So my question is: Am I using it correctly?
To do this many people would create a service that encapsulates this requiredFunction and inject the service through it's interface into both controllers
use this
var ctrl= new MyController();
ctrl.ControllerContext = ControllerContext;
//call action
return ctrl.Action();

Can we create Static ActionResult method in Controller?

Someone ask following question to me in interview, to which I cannot able to answer. Somebody please help me.
Can we create Static ActionResult method in controller?
If yes. What is the benifits? and if no. What is the reason?
If "ActionResult method" is a method that returns ActionResult, you can declare it static, of course, but it will not be called when you initiate that action. When calling some action, ASP.NET MVC creates an instance of the controller (using ControllerFactory), and since your method is static, it is not related to any instance, and thus, it will not be called by MVC
Don't think it is a good idea to create a static action method, as you will no longer have access to all the controller properties, such as controllercontext, etc.

ASP.NET MVC: Uses a delegate field as an action method?

Is it possible in ASP.NET MVC via some extension/override points to allow a "delegate field" to be used as an "action"?
Something like:
using System;
using System.Web.Mvc;
namespace Company.Web.Controllers
{
public class SwitchboardController : BaseController
{
public Func<ActionResult> Index, Admin, Data, Reports;
public SwitchboardController()
{
// Generic views
Index = Admin = Data = Reports =
() => View();
}
}
}
I know I'm a little hell-bent for this one but if this is possible it'd open up many new ways of making actions. You could, for example, have Django-style generic views in MVC with only a single line of code to define the action or have different ways to factor duplicate logic across multiple controllers.
I'm not quiet sure where would be the place to slap this logic into or how much work would be required to alter something so fundamental in the framework.
You will probably have to build your own Controller factory. This class builds controllers, and implements IControllerFactory. You can inherit from DefaultControllerFactory. Override CreateController() to return your own IController.
Register your controller factory in Application_Start() of MvcApplication using this line:
ControllerBuilder.Current.SetControllerFactory(typeof(MyControllerFactory));
In your implementation of IController, override the Execute method. You can use the RequestContext to decide which delegate to invoke. It would probably be easiest to inherit from ControllerBase, and override Execute in there if you don't want to fully implement IController.
The RequestContext passed into Execute carries a RouteData object. This is a dictionary populated by the routing engine that tells you what action should be invoked, and any parameters. You can get the action name like this:
//context is a RequestContext object passed to IController.Execute()
string actionName = requestContext.RouteData.Values["action"];
You could even define your action as a dictionary, and just pull them out once you get the action name.
One last thing, normal action methods return an ActionResult, which the framework uses to decide which view to render. Once you execute your delegates, I think you'll have to set some stuff manually in your special base controller. I'm not exactly sure what to set or how to get your View executed from here without cracking open the MVC source.
Good luck! This looks like an interesting idea.
As you seem to be implementing a BaseController in your code sample, if you override the Execute (from the IController) you'll be able to interpret the request => action however you like.
No, it isn't. The base controller is looking for methods and not for fields to dispatch an action.
EDIT:
Sorry, I was a bit fast and fixed to the standard classes provided.
You can do that but you have to overwrite the Execute Method in your controller or implement and provide your own IActionInvoker to dispatch the action to fields. Look into the post action processing in detail. It explains the dispatching in detail.

Controller equivalent of HttpContext.Current in ASP.NET MVC

I'd like to get access to the current executing Controller so I can offload the return of the appropriate ActionResult onto a helper method. To this end, I'm looking for the equivalent of what I would have thought would be ControllerContext.Current but isn't. Thanks!
Edit for clarification: I've got a generic form control which is JavaScript-based but I'd like to add an option so that it works with noscript. At the moment my Controller sets the ViewData.Model to a JSON-ified Models.FormResponse<T>.
This FormReponse is set up with the status of the post and any error messages that were generated, so I'd like a GetActionResult() method which does the script/noscript check (a hidden form input) and either:
Sets the Model to the JSONed FormResponse and returns a View(), or
Serializes the FormResponse to the Session and returns a Redirect().
As this obviously changes the return value and I don't want to do the check myself every time, I need to call View or Redirect from the FormResponse's GetActionResult method in order to call this as:
return formResponse.GetActionResult();
I know with a more astronautical design this could be made even more robust but as the noscript option is not a major feature at the moment, I just need to get a quick solution working that doesn't break other things.
Update #2
The following, implemented in an ActionResult class, does the job for me. Thanks CVertex!
public override void ExecuteResult(ControllerContext context)
{
if (CMSEnvironment.NoScript)
{
Oracle.Response.Redirect(Oracle.Request.UrlReferrer.ToString(), true);
}
context.Controller.ViewData.Model = _model.ToJSON();
new ViewResult()
{
ViewName = Areas.Site.Helpers.SharedView.Service,
ViewData = context.Controller.ViewData
}.ExecuteResult(context);
}
Statics are bad for testability, and very much discouraged in MVC.
Why do you want to access the current controller and action method?
The best way to do this is to implement your own ActionFilter.
This gives you a means of intercepting requests before or after actions methods execute.
EDIT:
By intercepting the result inside OnActionExecuted of a filter, you can do your noscript/script checks and modify your ViewData accordingly for consumption by the View.
Inside OnActionExecuted, you can also do the noscript check and have complete control over the final ActionResult or the ViewData, as you please.
Or, you can write your own ActionResult that makes all these decisions.
So, your controller action ultimately does
return new MyActionResult(format_and_view_agnostic_model_object);
There doesn't appear to be a way to navigate to the current Controller from a thread. That is you could get the ControllerBuilder and you can get the MvcHttpHandler but neither then lets you access the controller instance that the handler is using.

Resources