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
Related
I am using tweetsharp nuget package for adding tweets to my website.
I put my partialview on footer and it is visible on everpage of website.
here is my codes on Basecontroller.
public PartialViewResult _PartialView_twitter_feed()
{
var service = new TwitterService("key", "key");
service.AuthenticateWith("key", "key");
IEnumerable<TwitterStatus> tweets = service.ListTweetsOnUserTimeline(new ListTweetsOnUserTimelineOptions { ScreenName="my_screen_name", Count=5 });
ViewBag.Tweets = tweets;
return PartialView();
}
and I call it like this on footer view.
#Html.Action("_PartialView_twitter_feed", "base")
Now is the question, How can I make output caching or some kind of caching for this implementation on asp net mvc 5?
I dont want to call twitter api in every page view again and again. Because partial view is on footer.
How can I make it only once and show it until user leaves my website?
What can be the best practise to achive this?
Thanks for any help.
You can use OutputCache attribute. I hope the following example will help you.
Controller
[OutputCache(Duration = 6000)]
public PartialViewResult Footer()
{
return PartialView("Footer");
}
public ActionResult MainPage1()
{
return View();
}
public ActionResult MainPage2()
{
return View();
}
View
MainPage1
<h2>MainPage1</h2>
#Html.Action("Footer")
MainPage2
<h2>MainPage2</h2>
#Html.Action("Footer")
When user access the MainPage1 first time, the Footer partial view will return from server. From second time onwards it will return from cache. Even when user access MainPage2 the footer partial view will return from cache. You can increase the duration seconds based on your requirement
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.
I used the following tutorial to help me build an RSS Reader in my ASP.NET MVC3 Razor application:
http://weblogs.asp.net/jalpeshpvadgama/archive/2011/08/17/creating-basic-rss-reader-in-asp-net-mvc-3.aspx
However, unlike the tutorial example, I want the RSS feed to be displayed on every page, and have therefore added it to my layout file, /Views/Shared/_Layout.cshtml
I currently only have 2 views on my site, and to get the RSS Reader to work on both views I've got the following code in my HomeController:
public class HomeController : Controller
{
//
// GET: /Index/
public ActionResult Index()
{
return View(CT.Models.RssReader.GetRssFeed());
}
public ActionResult About()
{
return View(CT.Models.RssReader.GetRssFeed());
}
}
From my WebForms experience, I would simply add the RSS Reader code in my master page code behind, and it would automatically work on every page.
Is there a Controller for layout pages which allows me to do the same?
How can I get this to work on every call of the layout page, without having to return anything?
EDIT: Following #Sebastian's advice, I've now added this code to a Partial View, removed CT.Models.RssReader.GetRssFeed() from return View() and included this in my layout file:
#Html.Partial("_MyPartialView")
The code in this partial view is:
<ul>
#foreach (var item in Model)
{
<li>
#item.Title
</li>
}
</ul>
However, I'm not getting a runtime error:
Object reference not set to an instance of an object.
It's erroring on the line #foreach (var item in Model)
You have to create a partial view and add functionality there.
Then in your layout, render this partial.
EDIT
Is your partial view really a partial view? The reason I said that is because you have "_" in front of the name which suggests that it might be a layout (might just be a naming convention).
To fix object reference error, you have to add the #Model declaration on top of your partial view.
Hope it helps.
UPDATE
In order to use different model in partial view, you need to explicitly declare which model you are going to use on render partialmethod.
#{Html.RenderPartial("../YourFeed", Model.YourFeedModel);}
Let me know if that resolved your issue.
The new error you are having is due to you not passing a Model to the partial view. You can do this with the second argument of the Html.Partial function...
Html.Partial("ViewName", MyModel);
As I think you are trying to do this in a Layout page you could also consider using a static reference to get your RSS feed. So forget about needing to pass in a Model and in your partial have:
#foreach (var item in RssRepository.GetFeed())
{
<li>
#item.Title
</li>
}
this like to a class something like...
public static RssRepository
{
public static MyModel GetFeed()
{
return new MyModel();//<- return what you would normally pass as a Model for RSS feeds
}
}
Hope that all makes sense
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";
}
}
i want dynamically create ascx files, to partial render them.
but as i know, ot show them , i at least need dummy method:
public ActionResult test()
{
return PartialView();
}
how can i create this method for each new ascx file?
upd: i need factory?
Why would you create dynamic ascx files?
If you want to create all the layout in the controller you should be able to return it directly.
But then, why would you do that?
This way it will be really hard to do unit testing and refactoring and reuse.
You'd need to create your .ascx controls ahead of time. If you are doing this, I would recommend that you register a new view engine to provide a new PartialView location.
public class MyViewEngine : WebFormsViewEngine
{
public MyViewEngine()
{
PartialViewLocationFormats = new[]
{
"~/Views/{1}/{0}.ascx",
"~/Views/GeneratedControls/{0}.ascx",
"~/Views/Shared/{0}.ascx"
};
}
}
This allows you to write your dynamic views to the /Views/GeneratedControls/ folder. If you need to use a specifically named control (i.e. the control you generate has a random name) then you simply need to adjust your call to PartialView:
public ActionResult test()
{
return PartialView("name-of-control");
}
Otherwise MVC will use the name of the Action as the name of the control to use.