ASP.NET MVC - Reg Menu item in nav with Authentication - html

I am new to MVC world. I have a nav in my Layout file used by logged in users :
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>#Html.ActionLink("Home", "Index", "Member")</li>
<li>#Html.ActionLink("My Profile", "MyProfile", "Member")</li>
<!-- User type Admin, then Admin Menu -->
<li>#Html.ActionLink("Admin Index", "AdminIndex", "Member")</li>
<li>#Html.ActionLink("About", "About", "Home")</li>
<!-- Throws error /User/Logout not found -->
<li>#Html.ActionLink("Logout", "Logout", "User")</li>
<!-- Works Perfectly fine, but the link is on new line & different font/color/underlined -->
#if (Request.IsAuthenticated)
{
using (Html.BeginForm("Logout", "User", FormMethod.Post, new { id = "logoutForm" }))
{
<li>Logout</li>
}
}
</ul>
</div>
The #Html.ActionLink("Logout" doesn't work. It throws "/User/Logout" not found Error How to make that work like the below logout with <a href ??? Is the error b'coz in href, their is form and calling Form.Post method ??
Controller code :
public class UserController : Controller
{
// Registeration Action
[HttpGet]
public ActionResult Registeration() {..... }
// Login
[HttpGet]
public ActionResult Login() {.... }
// Login Post
[HttpPost]
public ActionResult Login(UserLogin userLogin, string returnUrl) { ...}
// Logout
[Authorize]
[HttpPost]
public ActionResult Logout()
{
FormsAuthentication.SignOut();
return RedirectToAction("Login", "User");
}
}
Can anyone please help me get this work !! Any help is highly appreciated.
Thanks

I suspect, although it is difficult to tell, that the controller is not UserController but maybe AccountController (the default) or MemberController.
In which case the call should be
#Html.ActionLink("Logout", "Logout", "Account")
or
#Html.ActionLink("Logout", "Logout", "Member")
Following your additional edit I think the issue will be that logout is a Post and a link is only ever a Get request so Mvc is looking for a get action /User/logout. There is an answer here about how to convert a link to a Post here.
I would probably get your link to call an ajax command in some js code. To make the most of the Razor goodness you can use #Url.Action. Alter your code as follows.
Your nav will look like this;
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>#Html.ActionLink("Home", "Index", "Member")</li>
<li>#Html.ActionLink("My Profile", "MyProfile", "Member")</li>
<!-- User type Admin, then Admin Menu -->
<li>#Html.ActionLink("Admin Index", "AdminIndex", "Member")</li>
<li>#Html.ActionLink("About", "About", "Home")</li>
<li>Log Out</li>
}
}
</ul>
</div>
Then your javascript function needs to be somewhere accessible to your nav page (the bottom of your _Layout page is probably easiest).
<script type="text/javascript">
function LogOut() {
$.ajax({
type: "POST",
url: "#Url.Action("Logout", "User")"
});
}
</script>
Hope that makes sense, I haven't tested it but your link should now look like all the others and your controller will now be getting a POST request so will access your logout method. Any problems shout.

Related

Why bootstrap file is not loading when i add double mapping in href?

<!-- this working fine, load all bootstrap files -->
<li class="nav-item" id="products">
<a class="nav-link" href="/productlist">Products</a>
</li>
<!-- this failed to laod bootstap file when i add one more /string in href -->
<li class="nav-item" id="products">
<a class="nav-link" href="/productlist/id">Products</a>
</li>
#working fine
#RequestMapping(value= "/productlist")
public ModelAndView productlist() {
ModelAndView mv = new ModelAndView();
mv.addObject("categoryList", categoryService.getAllCategory());
mv.setViewName("products");
return mv;
}
#failed to load bootstrap file
#RequestMapping(value= "/productlist/id")
public ModelAndView product() {
ModelAndView mv = new ModelAndView();
mv.addObject("categoryList", categoryService.getAllCategory());
mv.setViewName("products");
return mv;
}
When I put href="/productlist/id", my code is failed to load bootstrap file but it working fine in case of href="productlist"
Failed to load bootstrap file
I changed static file path and add slash before the path.
before
<script src="assets/js/myapp.js"></script>
after
<script src="/assets/js/myapp.js"></script>

Laravel - Add class to any nav-link if its generated url matches the current route

I'm working with Bootsrtap 4 and I'm trying to add the class active to my nav-item elements whenever their nav-link href attribute is the same as the current url.
On the html side, I uesd a basic url generator as shown below:
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="{{ url('/brands') }}" role="button">Brands</a>
</li>
<!-- ... -->
</ul>
And then I used a jQuery method to compare them with the current url:
$('.navbar-nav .nav-item .nav-link').each( () => {
// If the current path and the link url are the same...
if ($(this).attr('href').indexOf(location.pathname) !== 1) {
// ...then add the class 'active' to 'nav-item', its parent
$(this).parent().addClass('active')
}
})
However, I noticed that $(this).attr('href') was undefined, probably because it's a generated url, and therefore nav-item doesn't get the active class.
EDIT: as an example, for now it's a very basic url, without parameter, which looks like this:
http://domain.example/brands
Does anyone know how to solve this problem? Thanks in advance.
I'd recommend you to go another way. Instead of "activating" the link with jQuery, you could easily do it server-side with Laravel:
<ul class="navbar-nav">
<li class="nav-item">
<a class="{{ Request::is('brands*') ? 'nav-link active' : 'nav-link' }}"
href="{{ url('/brands') }}"
role="button">Brands</a>
</li>
<!-- ... -->
</ul>
Explanation:
Laravel uses the template-engine twig for rendering the HTML server-side. Instead of manipulation the DOM client-side, you can easily add an conditional to check for the current request parameters. Laravel gives you nativeliy the possibility to check the request path even with a wildcard.
Your problem is most likely caused by the difference between using () => {} or function () {}
When you use the arrow syntax the prop this is unbound. Meaning that also $(this) will return an empty jQuery object instead of returning the anchor. Any follow up jQuery chaining will return something empty/undefined.
So, changing .each( () => { to .each(function() { will at least fix your undefined problem.
Information about the arrow syntax: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
Okay this is what i do generally do in all my laravel projects when it comes to make sidebar or any link "active" on click :-
<li class="nav-item {{ in_array(Route::currentRouteName(),[
'admin.dashboard',
'admin.updates',
])? 'active show' : ''}}">
<i class="typcn typcn-clipboard"></i>Dashboard
<nav class="nav-sub">
Home
</nav>
</li>
Now notice this {{ BladeHelper::sideBar_link_isActive('admin.dashboard') }}
I created dynamic helper function to get the current url and return "active" class
Path : app\Helpers\BladePageHelper
<?php
namespace App\Helpers;
use Route;
class BladePageHelper
{
public static function sideBar_link_isActive($selectedLink){
$currentRouteName = Route::currentRouteName();
if($selectedLink === $currentRouteName){
return 'active';
}else{
return '';
}
}
}
I'm using route name here like
Route::("/","MyController#mymethod")->name("myname")
You can do this with url too.
I hope this helps.
Happy Coding

Make Bootstrap tabs active on MVC action

I want the tab to be set to active once I click on that tab (action). However, the issue I am experiencing is that the "Dashboard" tab is always set to active
<div class="row top-buffer">
<ul class="nav nav-tabs">
<li class="active">#Html.ActionLink("Dashboard", "Index")</li>
<li>#Html.ActionLink("Users", "Users")</li>
<li>#Html.ActionLink("Investigator Groups", "Groups")</li>
<li>#Html.ActionLink("Assign Games", "AssignGames")</li>
<li>#Html.ActionLink("Reports", "Reports")</li>
</ul>
</div>
Edit:
I tried doing the following, which now allows the tabs to be set to active, but no longer redirects to the action.
<li class="active" data-toggle="tab">#Html.ActionLink("Dashboard", "Index")</li>
<li data-toggle="tab">#Html.ActionLink("Users", "Users")</li>
follow this tutorial Setting the active menu item in a MVC C# Bootstrap application
by adding an extension method
public static class HtmlHelpers
{
public static string IsActive(this HtmlHelper htmlHelper, string action, string controller)
{
var routeData = htmlHelper.ViewContext.RouteData;
var routeAction = routeData.Values["action"].ToString();
var routeController = routeData.Values["controller"].ToString();
var returnActive = (controller == routeController && action == routeAction);
return returnActive ? "active" : "";
}
}
and then use it
<li class="#Html.IsActive("Index", "Dashboard")">#Html.ActionLink("Dashboard", "Index")</li>
<li class="#Html.IsActive("Users", "Users")">#Html.ActionLink("Users", "Users")</li>

asp.net mvc, show username in navbar

In an ASP.NET MVC project I would like to display a brief message to the user, eg. 'Hello, username!'
i the navigational bar, if the user is signed in. I'm using the standard bootstrap layout, and trying this, but it appears weirdly. I'm not sure what CSS ot HTML to change. Here's what I'm trying.
#if (Session["Username"] != null)
{
<ul class="nav navbar-nav navbar-right">
<li>Hello, #Session["Username"]</li>
<li>#Html.ActionLink("Logout", "Logout", "Home")</li>
</ul>
}
else
{
<ul class="nav navbar-nav navbar-right">
<li>#Html.ActionLink("Register", "Register", "Home")</li>
</ul>
}
That's in my _Layout page. The right text appears, but it's kind of off-centre and dark, not easily visible. How can I make it appear just like the actionlinks?
You can use htmlAttributes to change the style
<li>#Html.ActionLink("Logout", "Logout", "Home", htmlAttributes: new { #style="font-size:small;color:blue" })</li>

DRY approach to Razor syntax marking the currently viewed tab of a web page

I have some tabs at the top of a web page: home, features, contact, etc.
I need the category I am currently on to be marked as .
How can I appropriately code my _Layout.cshtml page with razor syntax so that I don't have to manually mark each page's appropriate tab as class="current" ?
<li class="current">#Html.ActionLink("Home", "Index", "Home")
<li>#Html.ActionLink("Blog", "Blog", "Home")
<li>#Html.ActionLink("Portfolio", "Portfolio", "Home")
Example way you could do it.
#helper BuildLink(string name, string action, string controller)
{
var url = Url.Action(action, controller);
bool isActive = Request.Url.AbsolutePath.Equals(url, StringComparison.InvariantCultureIgnoreCase);
<li class="#(isActive ? "current" : String.Empty)">#name</li>
}
#BuildLink("Home", "Index", "Home")
#BuildLink("Blog", "Blog", "Home")
#BuildLink("Portfolio", "Portfolio", "Home")
you can set on each controller ViewData["Home"] = "activeTab" class, and use that information in the view.
This will make the tab active if the value of that viewData dictionary is taken.
Is simple and very clean.
Inside controller set viewdata like this
ViewData["SomeTab"] = "activeTab";
return View("Index");
View side:
<li class="<# ((string)ViewData["SomeTab"] ?? "") >"><#Html.ActionLink("SomeTab", "Index", "Home")></li>
<li class="<# ((string)ViewData["MyPage"] ?? "") %>"><#Html.ActionLink("MyPage", "MyPage", "")></li>