ASP.NET | Call another controller's action from a controller in MVC - c#

I am thinking about a scenario rather similar to this question asked some time ago: How to call another controller Action From a controller in Mvc
In the scenario I am thinking of, controller B would however return a partial view that I would like to incorporate into the ViewResult returned by the Home controller, so the code might look like this:
public class Home
{
public ActionResult Index()
{
ActionResult partialViewFromCtrl_B = RedirectToAction(actionName: "SomeAction",
controllerName: "Controller_B");
// The returned view should include the partial view `partialViewFromCtrl_B`
return View();
}
}
public class Controller_B
{
public ActionResult SomeAction()
{
// Do some stuff
return PartialView(viewName: "_SomeAction", model: someModel);
}
}
Is there a way to combine the partial view returned from controller B into the view returned from the Home controller?
If possible, I would like to keep the logic and the views defined for controller B separate from the Home controller rather than merging everything into the Home controller.
Your help is very much appreciated!
Edit:
One possible solution to my scenario might by if the Index.cshtml of the Home controller looks like this
#model SomeModelType
...
#Html.Partial(partialview: "~/Controller_B/_SomeAction", model: Model)
...
and the Index() action of the Home controller would look like this:
public ActionResult Index()
{
// Get the model from Controller_B instead of the partial view
SomeModelType someModelFromCtrl_B = new Controller_B().returnSomeModel();
return View(someModelFromCtrl_B);
}
This however does not seem to be the best approach to take here for me.
So if possible I would like to combine the partial view Controller_B/_SomeAction and the Index view of the Home controller in the action method of the Home controller if that is possible.

Through the code posted I can not understand what you want to return.
based on your little code I think you intend to return Index values in PartialView.
Take a look at the code below:
public class Home
{
public ActionResult Index()
{
if(//cond){
// Do some stuff
return PartialView(viewName: "_SomeAction", model: someModel);
}
else{
ActionResult partialViewFromCtrl_B = RedirectToAction(actionName: "SomeAction",
controllerName: "Controller_B");
// The returned view should include the partial view `partialViewFromCtrl_B`
return View("Index");
}
}
}

Related

Why PartialAsync doesn't call coresponding controller method?

I have a .NET Core 2.1 MVC application.
I have a Home controller that looks like this:
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
public IActionResult CountView(MyModel model)
{
...
return PartialView(model);
}
}
In the Index view I want to display a patial view called CountView.
But when I use the following method in the Index.cshtml:
#await Html.PartialAsync("CountView", Model)
the view is displayed as I wanted to but the method in the controller never gets called and thus the partial view doesn't get the data it needs that is intended to be fetched by the controller method.
Why is that so?
And how can I make it to work as desired?
#await Html.PartialAsync("CountView", Model)
Renders a Partial View, it doesn't call any Controller for that. The correct way for doing this in ASP.NET Core is to create a View Component.
As for the implementation, here's a simple one modified from the official documentation previously linked:
Create a ViewComponents folder at the root of the project
Inside it, create a ``CounterViewComponent` class:
public class CounterViewComponent: ViewComponent
{
public async Task<IViewComponentResult> InvokeAsync(MyModel model)
{
// magic here
return View(model);
}
}
Call it in your view:
#await Component.InvokeAsync("Counter", new { model = Model })

How to pass the name of one controller to another controller ASP.NET MVC 5

I'm trying to pass the name of Home controller to Article controller based on which I'm trying to assign a _layout page.
Following is my code which i have tried.
public class HomeController : Controller
{
public ActionResult Index()
{
TempData["Ctrl"] = "Home";
}
}
public class ArticleController : Controller
{
public ActionResult Index()
{
if (TempData["Ctrl"] != null)
{
return View("Index", "~/Views/Shared/_Layout.cshtml", articles);
}
return View("Index", "~/Views/Shared/_otherLayout.cshtml", articles);
}
}
The problem is I'm assigning TempData value in each and every method in the Home controller (which I don't want to do it) as I'm losing TempData value. I tried assigning the value in the constructor of home controller without luck.
Could anyone please help me or point me in the right direction thanks.
You can assign your data in the Session object
this.HttpContext.Session.Add("Ctrl","Home")

ASP.NET MVC - T4 MVC - POST with Model

I have a controller that looks like this:
[RoutePrefix("items")]
public partial class ItemsController : Controller
{
public ActionResult Index()
{
var model = new MyApp.Models.Items();
return View(model);
}
// POST: /items/delete
[HttpPost]
[Route("delete")]
public ActionResult Delete(DeleteItemModel model)
{
// delete the item
model.Delete();
return RedirectToAction("Index");
}
}
In my Index.cshtml, I have the following:
#model MyApp.Models.Items
<h2>Hello</h2>
<form action="#Url.Action(MVC.Items.Delete())" method="post">
<button type="submit">delete</button>
</form>
The above is clearly a subset of my view. My main concern is, how to pass a DeleteItemModel from my form back to the Delete action. What am I missing? The MVC.Items.Delete path was generated from T4MVC. Yet, I can't figure out how to pass a model into it. Is there a fix here, or do I have to use some other approach entirely?

Route Hijacking in umbraco 7

I'm trying to set up route hijacking on Umbraco 7 with little success.
I have a view called Home.cshtml, the top few lines of which are:
#inherits Umbraco.Web.Mvc.UmbracoTemplatePage
#{
Layout = "Master.cshtml";
}
I added a controller:
-EDIT-
updated question to include Index() controller action.
namespace CLIAUmbraco7.Controllers
{
public class HomeController : Umbraco.Web.Mvc.RenderMvcController
{
public override ActionResult Index(RenderModel model)
{
string country = "";
return base.Index(model);
}
public ActionResult Index()
{
return View();
}
}
Sticking a breakpoint on the Layout line catches the site before it loads but HomeController is never called. Any idea what I'm doing wrong?
By default the controller needs to be called
[TheDocumentTypeAliasYouWantToHijack]Controller
If your document type is not "Home" then it will not be intercepted.
You are missing an Index() controller action. Your controller should look like this:
public class HomeController : Umbraco.Web.Mvc.RenderMvcController
{
public override ActionResult Index(RenderModel model)
{
//Do some stuff here, then return the base method
return base.Index(model);
}
}
Take a look at the article on Umbraco website.

Pass viewbag to partial view from action controller

I have a mvc view with a partial view.There is a ActionResult method in the controller which will return a PartialView. So, I need to pass ViewBag data from that ActionResult method to Partial View.
This is my Controller
public class PropertyController : BaseController
{
public ActionResult Index()
{
return View();
}
public ActionResult Step1()
{
ViewBag.Hello = "Hello";
return PartialView();
}
}
In Index.cshtml View
#Html.Partial("Step1")
Step1.cshtml partial view
#ViewBag.Hello
But this is not working. So, what is the correct way to get data from viewbag.
I think I'm following wrong method. Please guide me.
You can use it as mentioned below :
In your View :
#Html.Partial("[ViewName]", (string)ViewBag.Message)
And Your partial View :
#model String
<b>#Model</b>
As Shown Above ViewBag.Message will be passed to the partial view. and in your partial view you can use it as a #Model.
Note : here type of ViewBag.Message is string. You can pass any type.
If you don't have to use ViewBag, you can use TempData. TempData is shared for the whole execution chain.
public class PropertyController : BaseController
{
public ActionResult Index()
{
return View();
}
public ActionResult Step1()
{
TempData["Hello"] = "Hello";
return PartialView();
}
}
In Index.cshtml View
#Html.Partial("Step1")
Step1.cshtml partial view
#TempData["Hello"]
"Child actions follow a different controller/model/view lifecycle than parent actions. As a result they do not share ViewData/ViewBag."
The answer provides an alternate way of passing data.
Does a child action share the same ViewBag with its "parents" action?
Old question but if anyone here to find solution for this question..
You can pass viewbag value to partial with viewdatadictionary.
In your view:
#Html.Partial("_Partial", "", new ViewDataDictionary { { "permalink", ViewBag.Permalink } })
and in partial view use it like this:
ViewData["permalink"]
You can try this in order to pass ViewBag to partial view from action:
Your controller:
public class PropertyController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Step1()
{
ViewBag.Hello = "Hello";
return PartialView("_Partial1", ViewBag.Hello);
}
}
Your view (Index.cshtml):
#Html.Action("Step1")
Your partial view (_Partial1.cshtml):
#ViewBag.Hello
return PartialView("partialviewname", obj);

Categories

Resources