Having two master pages in mvc 3 application? - asp.net

I have a MVC application that exist at the moment using a _MainLayoutPage for its Master Page.
I want to create another Master Page for a different purpose. I will be creating a new controller as well.
How can I do this?

The simplest way is in your Action Method, set a Viewbag property for your Layout
public ActionResult Index()
{
ViewBag.Layout= "~/Views/Shared/layout2.cshtml";
In your View, set the layout property
#{
Layout = #ViewBag.Layout;
}

In _ViewStart.cshtml, put this:
#{
try {
Layout = "~/Views/" + ViewContext.RouteData.Values["controller"] + "/_Layout.cshtml";
}
catch {
Layout = "~/Views/Shared/_Layout.cshtml";
}
}
And then you can put a controller specific _Layout.cshtml in your controller folders, like
~/Views/User/_Layout.cshtml for a controller named UserController
~/Views/Account/_Layout.cshtml for a controller named AccountController
And because of the try/catch, it will fall back to the '~/Views/Shared/_Layout.cshtml' layout if one is not defined for a specific controller.

Related

Using ViewBag in Layout page

I have my _Layout.cshtml file that uses the ViewBag model to render some dynamic content.
I understand ViewBag can be populated in the controller and accessed in the view and/or layout page.
My question is, if my Layout page is using #ViewBag.SiteName, I want to avoid having to set this variable in each controller before I return the view. Is there a way to set this variable on a global level? Or how else should I pass this data to the layout page?
If you set anything in ViewBag - this happens after the Layout has been rendered -
You've missed the boat.
As others have mentioned, you can create a "helper" controller:
public class LayoutController : BaseController
{
[ChildActionOnly]
public ActionResult SiteName()
{
return new ContentResult {Content = "Site name goes here"};
}
}
Then, in your layout:
#{Html.Action("SiteName", "Layout")}

How to create a module view and stick it onto a position in asp.NET MVC 4

Sory about my question, I am brand new to MVC 4 Razor, it's different from Asp.NET Web form.
Look like joomla, and other web languague, how can i create a "module", eg: "news, ads, counter" and stick it to asp.NET page.
I have a layout.cshtml in share folder, i think it's "Master Page" (like Master Page in Asp.NET webform)
How can i create some positions in that layout ?
You can create partial views or controller/actions that return a partial.
Partial Views
First create a partial view (which is a razor view without boilerplate markup like doctype, html and body elements.
To use a partial view in Razor:
#Html.Partial("name-of-partial-view", model-for-the-partial-view)
Actions returning a partial
To have a controller create a partial for you, create an action like this:
public DemoController : Controller
{
[ChildActionOnly] // Optional attribute, making this action invisible to the routing system
public ActionResult Demonstration(string someparam)
{
// Do something with someparam to get information to display
return PartialView();
}
}
You'll need to create a partial view to be returned from this action. (As before, a partial doesn't have the boilrplate markup like doctype, html and body.)
And to call it from Razor:
#Html.Action("Demonstration", "Demo", new { someparam = "something" });
If you want this partial on every page, put it somewhere in your layout page.

Insert _ViewStart.cshtml

Is that possible to use viewstart only for a particular controller and view?
I was using only _Layou.cshtml file inside views folder.
Now i added _ViewStart.cshtml as common view inside views folder and moved _Layout to Shared folder.
This is program structure:
Homecontroller
public ActionResult Index()
{
return View();
}
Index.cshtml
#{
Layout = "~/Views/_Layout.cshtml";
}
_Layout.cshtml
{
//design code for Index.chtml
}
as per the above code, _Layout rendered for homecontroller .
When done the changes mentioned at the very first line, I'm getting the controls inside _Layout.cshtml in every controller I use.
I use nearly 6 controllers.
How to make this change without disturbing the entire code.
Please help.
PS: I need to introduce _ViewStart into the program since I'm integrating openid with my already developed project.
You can create another _ViewStart.cshtml (in Views/[controller] a sub-folder for example) that will override the root one, something like:
#{ Layout = null; }
You can simply use the ViewBag to determine whether to use Layout or not:
public ActionResult AnotherAction()
{
....
ViewBag.NoLayout = true;
return View();
}
and in your _ViewStart:
#{
if (ViewBag.NoLayout == null || !ViewBag.NoLayout)
Layout = "~/Views/_Layout.cshtml";
}
You can read more about MVC3 Razor layouts on Scott Guthrie's Blog

Create controller for partial view in ASP.NET MVC

How can I create an individual controller and model for a partial view? I want to be able to place this partial view any where on the site so it needs it's own controller. I am current rendering the partial as so
#Html.Partial("_Testimonials")
Why not use Html.RenderAction()?
Then you could put the following into any controller (even creating a new controller for it):
[ChildActionOnly]
public ActionResult MyActionThatGeneratesAPartial(string parameter1)
{
var model = repository.GetThingByParameter(parameter1);
var partialViewModel = new PartialViewModel(model);
return PartialView(partialViewModel);
}
Then you could create a new partial view and have your PartialViewModel be what it inherits from.
For Razor, the code block in the view would look like this:
#{ Html.RenderAction("Index", "Home"); }
For the WebFormsViewEngine, it would look like this:
<% Html.RenderAction("Index", "Home"); %>
It does not need its own controller. You can use
#Html.Partial("../ControllerName/_Testimonials.cshtml")
This allows you to render the partial from any page. Just make sure the relative path is correct.
If it were me, I would simply create a new Controller with a Single Action and then use RenderAction in place of Partial:
// Assuming the controller is named NewController
#{Html.RenderAction("ActionName",
"New",
new { routeValueOne = "SomeValue" });
}
The most important thing is, the action created must return partial view, see below.
public ActionResult _YourPartialViewSection()
{
return PartialView();
}
You don't need a controller and when using .Net 5 (MVC 6) you can render the partial view async
#await Html.PartialAsync("_LoginPartial")
or
#{await Html.RenderPartialAsync("PartialName");}
or if you are using .net core 2.1 > you can just use:
<partial name="Shared/_ProductPartial.cshtml"
for="Product" />
Html.Action is a poorly designed technology.
Because in your page Controller you can't receive the results of computation in your Partial Controller. Data flow is only Page Controller => Partial Controller.
To be closer to WebForm UserControl (*.ascx) you need to:
Create a page Model and a Partial Model
Place your Partial Model as a property in your page Model
In page's View use Html.EditorFor(m => m.MyPartialModel)
Create an appropriate Partial View
Create a class very similar to that Child Action Controller described here in answers many times. But it will be just a class (inherited from Object rather than from Controller). Let's name it as MyControllerPartial. MyControllerPartial will know only about Partial Model.
Use your MyControllerPartial in your page controller. Pass model.MyPartialModel to MyControllerPartial
Take care about proper prefix in your MyControllerPartial. Fox example: ModelState.AddError("MyPartialModel." + "SomeFieldName", "Error")
In MyControllerPartial you can make validation and implement other logics related to this Partial Model
In this situation you can use it like:
public class MyController : Controller
{
....
public MyController()
{
MyChildController = new MyControllerPartial(this.ViewData);
}
[HttpPost]
public ActionResult Index(MyPageViewModel model)
{
...
int childResult = MyChildController.ProcessSomething(model.MyPartialModel);
...
}
}
P.S.
In step 3 you can use Html.Partial("PartialViewName", Model.MyPartialModel, <clone_ViewData_with_prefix_MyPartialModel>). For more details see ASP.NET MVC partial views: input name prefixes

Specify different _Layout.cshtml depending on controller

I created an asp mvc3 project, I want to have a different _Layout.cshtml depending on which controller is selected. This is because with controller 1 it has 2 buttons with the controller2 there will be 3 and with the controller3 there will be 4. Each controller is for a specific type of user, so it depends on the login.
How can i link a controller and its views to another Layout.cshtml, right now there is one layout and it's under the Shared folder.
Thanks!
The View should determine the layout, not the controller.
The Controller should just determine what View is returned.
Then in the top of your view you can specify the layout.
You could add a If statement around it to change it based on your data
#{
if(ViewBag.someValue)
Layout = "~/Views/Shared/_Layout.cshtml";
else
Layout = "~/Views/Shared/_otherLayout.cshtml";
}
At this point since the other one is a bit dated and with mvc 5 , I know you will have some issues with not having brackets. If you wish to use the View to be doing logic then here is a more complete answer.
Controller
public ActionResult Index()
{
ViewBag.Admin = 1;
return View();
}
View
#{
if (ViewBag.Admin == 1)
{
Layout = "~/Views/Shared/_AdminLayout.cshtml";
}
else
{
Layout = "~/Views/Shared/_Layout.cshtml";
}
}

Resources