I am Creating a new partial view in MVC 3 as this functionality is required through out my application.Is it possible to have a separate controller for my partial view only
Yes, you can. Create controller (consider to disable non-child action calls if you need to use controller only for partial view):
public class FooController : Controller
{
[ChildActionOnly]
public PartialViewResult Bar()
{
var model = new BarModel();
return PartialView("_Bar", model);
}
}
And use it
#Html.RenderAction("Bar", "Foo")
Related
I have the following in my _Layout.cshtml:
<title>#ViewData["PageTitle"]</title>
I then have a Child Action that is called, and I want to be able to set change this value in that controller action.
Is this possible?
You could try using the parent context. In your _Layout.cshtml:
<title>#ViewContext.ViewData["PageTitle"]</title>
and in your child action:
[ChildActionOnly]
public ActionResult Foo()
{
ControllerContext.ParentActionViewContext.ViewData["PageTitle"] = "foo";
return View();
}
I want to return an object on HTTPGet method and different object in HTTPPost method of the same action method in the controller, but i dont know what to write in the view, which model to get.
Here is the controller code , i have been trying
[HttpGet]
public ActionResult Create()
{
var intSrNo = Convert.ToInt64(TempData["sr_no"]);
MEntities obj_entity = new MEntities();
UDP_get_a_Result obj_proc = obj_entity.UDP_get_a(intSrNo).SingleOrDefault();
return View(obj_proc);
}
[HttpPost]
public ActionResult Create(Table_a obj_a)
{
if (ModelState.IsValid)
{
db.Table_a.AddObject(obj_a);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(obj_a);
}
i'm confused which model to write in view.(Table_a or UDP_get_a_Result) and i want both HttpGet to show values when the page is loaded and HttpPost when the submit is clicked.
View
#model ABC.models.Table_a
#{
ViewBag.Title = "Create";
}
A view can only be strongly typed to a single class. You cannot have different controller actions returning the same view and passing different models to this view. You could use view models: define a class which will hold all the information necessary for this view and then have your controller actions fill this view models and pass it to this view.
I think it would work to have the view typed to some base class (object) and then cast the model to whatever you needed it to be based on get/post. I wouldn't want to maintain it tho. :-D
Can we call the Method of a controller from another controller in asp.net MVC?
You could also simply redirect straight to the method like so:
public class ThisController
{
public ActionResult Index()
{
return RedirectToAction("OtherMethod", "OtherController");
}
}
Technically, yes. You can call a static method of a controller or initialize an instance of a controller to call its instance methods.
This, however, makes little sense. The methods of a controller are meant to be invoked by routing engine indirectly. If you feel the need to directly call an action method of another controller, it is a sign you need some redesign to do.
Well, there are number of ways to actually call an instance method on another controller or call a static method off that controller type:
public class ThisController {
public ActionResult Index() {
var other = new OtherController();
other.OtherMethod();
//OR
OtherController.OtherStaticMethod();
}
}
You could also redirect to to another controller, which makes more sense.
public class ThisController {
public ActionResult Index() {
return RedirectToRoute(new {controller = "Other", action = "OtherMethod"});
}
}
Or you could just refactor the common code into its own class, which makes even more sense.
public class OtherClass {
public void OtherMethod() {
//functionality
}
}
public class ThisController {
public ActionResult Index() {
var other = new OtherClass();
other.OtherMethod();
}
}
Try This.
var ctrl= new MyController();
ctrl.ControllerContext = ControllerContext;
//call action
return ctrl.Action();
As controllers are just classes: Yes, we can do it. We can do it by some of the following ways:
By directly redirecting- return RedirectToAction("MethodName", "ControllerName");
By creating object - ControllerName objController=new ControllerName();
objController.methodName(parameters)
Yes, you can call a method of another controller.
public ActionResult Index()
{
AccountController accountController = new AccountController {ControllerContext = ControllerContext};
return accountController.Index();
}
The controller is also a simple class. Only things are that its inheriting Controller Class. You can create an object of the controller, but it will not work for Routing if you want to redirect to another page.
public ActionResult Index(){
var dataContext = new DataEvidencijaDataContext();
MembershipUser myObject = Membership.GetUser();
string KorisnickoIme = myObject.UserName.ToString();
var user = from i in dataContext.korisniks
where i.korisnik1 == KorisnickoIme
select i;
ViewData.Add("user", user);
return View(user);
}
In master page i put this
<%= Html.RenderPartial("profPredmeti", ViewData["user"])%>
but this is not work
You can use RenderAction for this to delegate menu rendering to some controller. Another option is to have your controller (or base controller class, or action filter) put the menu object into ViewData, and then your master page will do
<% Html.RenderPartial("MenuRenderView", ViewData["menu"]) %>
where MenuRenderView.aspx partial view consumes the menu object from ViewData["menu"]. What does this object contain depends on your database/code.
The approach that I have taken in the past is to have a base controller class from which all the other controllers inherit. In that base controller class, you can add items into ViewData after the controller is initialized:
protected override void Initialize(System.Web.Routing.RequestContext requestContext)
{
base.Initialize(requestContext);
ViewData.Add("CommonPageData", CommonPageData);
}
The "CommonPageData" in this case is a property or type CommonPageData (a custom class) whose properties are lazy-loaded. One of the properties is a navigation item collection that is consumed on the master page.
User RenderPartial for the Menu, but you're gonna need to pass in the ViewData the datasource for the menu all the time, a solution is to make an abstract BaseController and to put the datasource in the ViewData in the constructor of that base controller
all the controllers will inherit from the base controller
I have this block sitting in my Site.Master page:
<script runat="server" type="text/C#">
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
MasterModel = SiteMasterViewData.Get();
}
protected SiteMasterViewData MasterModel;
</script>
That Get() method is a static factory method tacked on to the View Data class. All of this is embarrassing but here we are.
Is it possible for an ASP.NET MVC controller to create a new instance of a different controller and effectively delegate resonsibility to that?
Let's say for example that I have two controllers in the /Controllers/ directory:
public class HomeController : Controller
{
public ActionResult Index()
{
var otherController = new OtherController();
return otherController.ShowNumberOfThings(100);
}
}
public class OtherController : Controller
{
public ActionResult ShowNumberOfThings(int index)
{
return View(index);
}
}
...and a View called Views/Other/ShowNumberOfThings.aspx:
<%# Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="ViewPage<int>" %>
Number of things: <%= Model.ToString() %>
When I hit the url:
http://localhost/Home/Index
I want to be presented with a page that reads:
"Number of things: 100"
I would like to be able to persist temporary data between controller redirections without being forced to use the session object (TempData[""] uses the session object for cross-controller redirections). My real world case has a complex object which needs passing (not just an int) so using a URL/Cookie is out of the question, and session state is a no-no.
In WebForms at least we could use Server.Transfer and maintain any state in the HttpContext.Items collection. In MVC the only option I can see is to call the controller method directly passing in required arguments.
At the moment it's having trouble trying to resolve the view folder as the "context" is still running under the HomeController.
I guess where I am going with this is trying to cludge ASP.NET MVC into acting like a FrontContoller.
Any ideas?
EDIT
In the end we had to serialise everything into a session and use that. A shame, but I have heard that MVC2 will support serialising objects into a ViewState.
If you want to be presented with "Number of things: 100" when you hit the Index action why not directly render the corresponding view:
public class HomeController : Controller
{
public ActionResult Index()
{
return View("~Views/Other/ShowNumberOfThings.aspx", 100);
}
}
I think it would be preferred to use.
return RedirectToAction("Controller", "Action")
However I'm guessing you want to maintain the Url Home/Index.
If you're looking at the FrontController pattern then you should investigate writing a Custom ControllerFactory which inherits from DefaultControllerFactory then Override the CreateController method.
You can register your factory using the code below.
protected void Application_Start()
{
ControllerBuilder.Current.SetControllerFactory(new MyCustomControllerFactory();
RegisterRoutes(RouteTable.Routes);
}
In the Controller factory you have access to the RequestContext so you can change the RouteData as needed and delegate to the correct controller.
You could of course just set a a Custom route for Home/Index which goes to OtherController.ShowNumberOfThings()
routes.MapRoute("Home", "Home/Index/{id}",
new {controller = "Other", action = "ShowNumberOfThings", id = 100});
a different approach would be the use of partial views
instead of ~Views/Other/ShowNumberOfThings.aspx
you could put your view in ~Views/shared/ShowNumberOfThings.ascx
have both views ~Views/Other/ShowNumberOfThings.aspx and ~Views/Home/Index.aspx implement the partial view
public class HomeController : Controller
{
public ActionResult Index()
{
return View(100);
}
}
public class OtherController : Controller
{
public ActionResult ShowNumberOfThings(int index)
{
return View(index);
}
}
and in both views implement the partial view
<% Html.RenderPartial("~Views/shared/ShowNumberOfThings.ascx", ViewData.Model); %>
you can change the int for any object that will be passed to the model
Another possibility (similar to partial views) is to use Html.RenderAction. This allows for different view model classes and separate controller methods.
<% Html.RenderAction("yourActionName", "yourControllerName", routeValues); %>