How to use query string in asp.net mvc layout page - asp.net-mvc

I am getting confuse in understanding the query string and routing concept in asp.net mvc, and I will appreciate if some one can please help.
My problem is:
I have a login page where user will enter the Username, password and Id. After successful login I like to take the Id and pass it to my Profile page. Now profile page is part of layout page along with two other links.
<nav class="main">
<ul class="menu" >
<li>#Html.ActionLink("Profile", MVC.Profile.Index(), new { Id = Request.QueryString["Id"].ToString() })</li>
<li>#Html.ActionLink("Configuration", MVC.Configuration.Index(),new { Id = Request.QueryString["Id"].ToString() })</li>
<li>#Html.ActionLink("Transaction", MVC.Transaction.Index(), new { Id = Request.QueryString["Id"].ToString() })</li>
</ul>
</nav>
From my login page I am using the following code to Redirect the user to Profile page.
return RedirectToAction("Index", "Profile", new { Id =
viewModel.Id });
Now how can i pass the same value to configuration and transaction page, they are just action links on layout page.I thought of using Request.QueryString like below:
new { Id = Request.QueryString["Id"].ToString()
but this is throwing object reference exception.
my routing look like this:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Login", action = "Index", id = UrlParameter.Optional });
Thanks in advance.

So after you are redirecting to the Index action of your Profile controller, make sure your action takes in a int parameter like below and return it to the Profile view:
public ActionResult Index(int id)
{
return View(id);
}
Render your links in the Profile's Index view like below:
#model int
<nav class="main">
<ul class="menu" >
<li>#Html.ActionLink("Profile", "Index", new { Id = #Model })</li>
<li>#Html.ActionLink("Configuration", "Index",new { Id = #Model })</li>
<li>#Html.ActionLink("Transaction", "Index", new { Id = #Model })</li>
</ul>
</nav>
Let me know if you need more clarification.

Related

ASP.NET MVC - keep links to the root folder

I am trying to link inside the same folder, I have the following structure
/Home/Index
/Home/About
/Home/Contact
When I start the webpage, I link to the Index, so I get the webpage on the screen: www.example.com.
Now I would like to link to another page so I get: www.example.com/Contact.html (or even better I would like to get www.example.com/Contact) however I get www.example.com/Home/Contact.
I use this as an action link:
<li class="pure-menu-item pure-menu-selected">#Html.ActionLink("Contact us", "Contact", "Home")</li>
This is my route:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
What could I change to get the desired result?
Decorate you Contact action with a RouteAttribute and pass it the desired route as parameter (i.e. "Contact")
Edit
Here's an example HomeController using the RouteAttribute:
public class HomeController
: Controller
{
public IActionResult Home()
{
return this.View();
}
[Route("Contact")]
public IActionResult Contact()
{
return this.View();
}
}
Note that you can use the RouteAttribute on Controllers, too. For instance, if I added a Route("Test") attribute on the HomeController, all of my controllers actions would look like: "/Test/[ActionRoute]".
In your views, you can use the following syntax, instead of using the old #Html.ActionLink tag helper:
<li class="pure-menu-item pure-menu-selected">
<a asp-controller="Home" asp-action="Contact">Contact Us</a>
</li>
In my opinion, those attribute tag helpers are way cleaner and html friendly ;)
i was able to fix it with some good reading and searching and this is what i came up with:
i added this to the routeConfig for each link to a html page:
routes.MapRoute("Index", "Index", new { controller = "Home", action = "Index" });
routes.MapRoute("About", "About", new { controller = "Home", action = "About" });
routes.MapRoute("Contact", "Contact", new { controller = "Home", action = "Contact" });
and instead of using an action link i use a route link:
<li class="pure-menu-item">#Html.RouteLink("About us", "About")</li>
this gives the desired result: www.example.com/About

MVC Routes, adding a filter to existing page

I have a route:
context.MapRoute(
"ISPCCodeSearch_default",
"OnlineOrder/{controller}/ISPCCodeSearch/{ISPC}",
new
{
area = "OnlineOrder",
controller = "Home",
action = "ISPCCodeSearch",
ISPC = UrlParameter.Optional,
});
that brings up a number of products by a product code eg,
OnlineOrder/Home/ISPCCodeSearch/11011/
I want to further filter this by brand by clicking on a filter link on the above page.
OnlineOrder/Home/ISPCCodeSearch/11011/Xerox
How do I generate the links and the route?
<a class=" list-group-item" href='#(Url.Action("BrandFilter", new {brand = item.BrandName}))'>
#item.FriendlyBrandName <span class='badge'>#item.BrandItemsCount</span>
</a>
I have the above code which just gives me :
/BrandFilter/Xerox
I don't know how to implement this.
You will need to update route:
context.MapRoute(
"ISPCCodeSearch_default",
"OnlineOrder/{controller}/ISPCCodeSearch/{ISPC}/{param2}",
new
{
area = "OnlineOrder",
controller = "Home",
action = "ISPCCodeSearch",
ISPC = UrlParameter.Optional,
param2= UrlParameter.Optional,
});
And for a link, just add another property:
#(Url.Action("BrandFilter", new {brand = item.BrandName, prop2 = item.property2}))

Mvc: Exclude id from url

I have the next foreach in my cshtml page, it allows to me iterate in each Model item
#foreach (var item in Model)
{
<div class="date">
#item.pubDate
</div>
<a href="#Url.RouteUrl("Details", new { action = "Details", controller = "News", id = item.id, title = item.title })">
<img src="some route" alt="some alt" />
</a>
}
so now it's working fine and each element inside foreach loop has an url with something like
http://something.com/News/Details/1/first-title
http://something.com/News/Details/2/second-title
It's possible create urls with something like
http://something.com/News/Details/first-title
http://something.com/News/Details/second-title
but i can still sending id parameter to my controller ?
Thanks in advance
Add another route:
routes.MapRoute(
name: "NewsTitleRoute",
url: "News/Details/{id}/{title}",
defaults: new {
controller = "News",
action = "Details",
id = UrlParameter.Optional,
title = UrlParameter.Optional
}
);
In your controller declare the details method like this, with the two parameters as optional:
public ActionResult Details(int? id, string title="")
{
}
That route configuration and Details method will work for:
http://something.com/News/Details/
http://something.com/News/Details/1
http://something.com/News/Details/first-title
http://something.com/News/Details/1/first-title
You can just pass the title property for id parameter.
#Url.RouteUrl("Details",
new { action = "Details", controller = "News", id = item.title})
Then set type of id parameter as string in your action method:
public ActionResult Details(string id)
Or you can create custom route like in von-v's answer. Just make sure it's above the default route.

#Html.ActionLink not Rendering as Expected

I have this in my Global.asax.cs:
routes.MapRoute(
"User",
"User/{username}/{action}",
new { controller = "User", action = "Index", username = "*" }
);
Then on my _Layout.cshtml I have this code:
<ul id="menu">
#if (!String.IsNullOrEmpty(Context.User.Identity.Name))
{
<li>#Html.ActionLink("Home", "Home", new { controller = "User" }, new { username = Context.User.Identity.Name })</li>
}
</ul>
</div>
</div>
The thing is, it will render the link properly the first time it swings through here. (Link will be /User/rob/Home where "rob" is a username. If I navigate elsewhere on the page and then click back on my link, the link is rendered as /User/*/Home. When I step through the code, Context.User.Identity.Name is correct every time.
Am I missing something really basic here? I'm not sure what to search for.
That's exactly what you should expect given that route. You don't specify username in the route values dictionary but in the HTML attributes, so it takes the default from the route, *. You should be using the signature that allows you to specify both the controller and the action as strings with additional route values in the dictionary.
#if (!String.IsNullOrEmpty(Context.User.Identity.Name))
{
<li>#Html.ActionLink("Home", "Home", "User" new { username = Context.User.Identity.Name }, null )</li>
}

asp.net mvc can i have a menu that links by both id and username

I am basically taking the default ASP.NET MVC template and extending it:
Looking at the site.master, I see this for menus:
<ul id="menu">
<li><%= Html.ActionLink("Home", "Index", "Home")%></li>
<li><%= Html.ActionLink("About", "About", "Home")%></li>
</ul>
I am then editing it by the following:
<ul id="menu">
<li><%= Html.ActionLink("Home", "Index", "Home")%></li>
<li><%= Html.ActionLink("About", "About", "Home")%></li>
<li><%= Html.ActionLink("My Contact Info", "Details/" + Html.Encode(Page.User.Identity.Name), "Users")%></li>
</ul>
The issue is that, in the controller, I have two different methods:
//
// GET: /Users/Details/userName
public ActionResult Details(string loginName)
{
UserInfo user = repo.GetUserByName(loginName);
return View(user);
}
//
// GET: /Users/Details/5
public ActionResult Details(int id)
{
UserInfo user = repo.GetUser(id);
return View(user);
}
I get an exception that says, ambiguous method. Because it can't figure out which one to call. I would hope that it could figure it out by the data type but apparently not.
Does anyone have any suggestions for supporting details view and querying by different fields? (Of course all of the queryable fields are unique.)
If you had a route like:
routes.MapRoute(
"Users", // Route name
"Users/Details/{username}", // URL with parameters
new { controller = "Users", action = "Details", username = "" } // Parameter defaults
);
which could be used to avoid ambiguity with the default route .. You would need to put this before the default "{controller}/{action}/{id}" route so that it would get priority...
Then, you could have an action like :
// GET: /Users/Details/username or //GET: /Users/Details?id=theId
public ActionResult Details(string username, int? id)
{
if(id!=null)
{
UserInfo user = repo.GetUser(id.Value);
return View(user);
}
if(!String.IsNullOrEmpty(username))
{
UserInfo user = repo.GetUserByName(username);
return View(user);
}
...//Handle bad url.. redirect to error...you decide ;)
}
You could then access this action like this:
/Users/Details/username or..
/Users/Details?id=userId

Resources