i have created a master page with lots of effort but i am not able to figure out how to make my tab selected based on the user click.
i have used one method to do that but finding very complicated as i have pass a viewdata from each of my controller which i dont like it, below is how i have done code in controller
ViewData["ActiveMenu"] = "Inbox";
and in my master page i have written a jquery like below to make the tab highlighted.
$('#lnkInbox').mouseout(function () {
$('#aInbox').removeClass('aInbox-Hover');
$('#aInbox').addClass('aInbox');
//put hover effect on the selected menu
var activeMenu = '<%:ViewData["ActiveMenu"] %>';
if (activeMenu == "Account") {
$('#aAccount').removeClass('aAccount');
$('#aAccount').addClass('aAccount-Hover');
}});
this is how i am doing but is there any other way i can do that...
please suggest
i have found one good link active menu item - asp.net mvc3 master page
but the answer which is showed there i am not able understand how to i utilize in my code and where to write the code in my project.
Use the answer you found.
To create helper class add new class to you project, i.e. like this
public static class LinkHelpers
{
//copy here the first block of code from the answer
}
Add to your HomeController methods (probably you already have them):
public class HomeController : Controller
{
public ActionResult About()
{
return View()
}
public ActionResult Index()
{
return View()
}
}
Create respective views and add to your master page
<ul>
<li>#Html.MenuLink("Main", "Index", "Home")</li>
<li>#Html.MenuLink("About us", "About", "Home")</li>
</ul>
And finally in your css file declare
.current{background-color:red;}
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
We have recently decided to switch from asp.net webforms to asp.net mvc for some new projects. As a long time webforms developer I have watched and read quite a lot of introductory tutorials and how to switch articles and video's. However some things still bug me (no pun intended) a litte bit. And I'm hoping I could get some answers from the community here.
First, we have a cms-system that we are required to use for a client. In the system they obviously manage the navigation (menu) for the webproject. My first question is, how would I go about to adding this dynamic navigation to all the pages (views). In webforms I would simply create a custom user control and throw it onto the masterpage or template. I suspect the answer to be viewmodels? Or partial views?
The second question is related. Often we would have a few pages that show some news for example in a side panel. Others would not. Would I create a different viewmodel for the different scenarios, work with sections?
I don't expect a definite answer, but more some guidelines/best practices. Any input is appreciated.
Your question is extremely broad so I'll only give a high level way of achieving this.
For the menu system you can create two Div elements, one for the menu and one for the content. The menu div should contain an Action that calls JavaScript to replace the content of the main Div with a Partial View returned by your Controller.
In your _Layout page you can something like this
<body>
#Html.Action("RetrieveSideBar", "SideBar", new { area = "" })
<div id="mainScreenDiv">
#RenderBody()
</div>
</body>
RetrieveSideBar renders the menu items
public class SideBarController : MyControllerBase {
/// <summary>
/// Retrieves the side bar.
/// </summary>
/// <returns></returns>
public ActionResult RetrieveSideBar() {
var menuItems = new List<MenuItem>();
return PartialView("_SideBar", MenuItems());
}
private List<MenuItem> NotAuthenticatedMenuItems() {
var menuItems = new List<MenuItem>();
menuItems.Add(new MenuItem() { Title = "Register Firm", ActionUrl = Url.Action("Create", "FirmPreRegistration") });
return menuItems;
}
}
Where MenuItem is
public class MenuItem {
public string Title { get; set; }
public string ActionUrl { get; set; }
}
_SideBar renders the menu as follows
#model List<MenuItem>
<ul class="nav nav-sidebar">
#foreach (var menuItem in Model) {
<li class="text-info leftMenuHeading ">
<a href="#" onclick="NavigateTo('#menuItem.ActionUrl')">
<span>#menuItem.Title</span>
</a>
</li>
}
</ul>
Note that clicking on a menu item calls NavigateTo which is defined as follows in the '_Layout' page
function NavigateTo(view) {
$.ajax({
url: view,
type: "GET",
cache: false,
success: function(data) {
$('#mainScreenDiv').html(data);
});
}
This creates an Ajax based navigation system that will replace the content in the page with the navigated page, note that Action methods need to return PartialView or else _Layout renders again.
My first question is, how would I go about to adding this dynamic navigation to all the pages (views). In webforms I would simply create a custom user control and throw it onto the masterpage or template.
Asp.Net MVC has something similar - _Layout.cshtml. By default it is inside Views/Shared folder and it is like master page for all pages. You can generate your dynamic menu in following way
public abstract class BaseController : Controller
{
public YourMenuModel YourMenuModel { get; set; }
public BaseController()
{
this.YourMenuModel = //load dynamically your menu. For example from database
ViewBag.MenuModel = this.YourMenuModel ;
}
}
Inside _layout view you can get your menu model and render in any way
#{
var YourMenuModel = (YourMenuModel)ViewBag.MenuModel;
}
Often we would have a few pages that show some news for example in a side panel. Others would not. Would I create a different viewmodel for the different scenarios, work with sections?
I would create partial view for news and put it inside some views
#Html.Partial("_YourNewsPartial")
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
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
Okay, I'm pretty new to ASP.Net / MVC 2. Can anyone explain how to use the Html.ActionLink thing? I understand that the first parameter is the displayed text, but for the second one, what is the action name??
User action in the asp.net MVC framework is based around Controllers and Actions that enable you to create pages (or links) to specific sections.
For example you might want a page to edit a Product so you have a Product Controller with an Edit Action. You can then create a Html ActionLink that will direct the user to this page.
In summary the 'action' will be the ActionResult method you want to direct your user to.
<%: Html.ActionLink("Edit Product", "Edit", "Product") %>
public class ProductController : Controller
{
public ActionResult Index() // Index is your action name
{
}
public ActionResult Edit(int id) // Edit your product
{
}
}
I am using the following code in my master page:
<% Html.RenderAction("RecentArticles","Article"); %>
where the RecentArticles Action (in ArticleController) is :
[ChildActionOnly]
public ActionResult RecentArticles()
{
var viewData = articleRepository.GetRecentArticles(3);
return PartialView(viewData);
}
and the code in my RecentArticles.ascx partial view :
<li class="title"><span><%= Html.ActionLink(article.Title, "ViewArticle", new { controller = "Article", id = article.ArticleID, path = article.Path })%></span></li>
The problem is that all the links of the articles (which is built in the partial view) lead to the same url- "~/Article/ViewArticle" .
I want each title link to lead to the specific article with the parameters like I'm setting in the partial view.
Thanks.
I think your not using the ActionLink correctly. Change the ActionLink code to:
Html.ActionLink(
article.Title,
"ViewArticle",
"Article", // put the controller here
new
{
id = article.ArticleID,
path = article.Path
},
null)
Notice the null at then end.
EDIT: Why are you using [ChildActionOnly] in your controller? Since it is an MVC 2 feature I am assuming that you are using MVC2? Try removing it and check out the following article:
http://www.davidhayden.me/2009/11/htmlaction-and-htmlrenderaction-in-aspnet-mvc-2.html
I think the issue has to do with your partial not rendering. I would start by just trying to verify that your partial is rendering properly. Once you confirm that start to debug why the partial is not outputing.
I was able to solve the problem by using the following call in my RecentArticles action:
return PartialView("~/Views/Shared/Article/RecentArticles.ascx", viewData);
It seems like the partial view was not being rendered at all,
Thanks !