How to pass Area in Url.Action? - asp.net-mvc

The problem in Html.ActionLink() is that you can't add additional html content inside the tag that it generates.
For example, if you want to add an icon besides the text like:
<i class="fa fa-users"></i> Go to Users
Using Html.ActionLink(), you can only generate:
Go to Users
So, to resolve this, you can use Url.Action() to generate only the URL inside the tag like:
// Here, Url.Action could not generate the URL "/admin/users". So this doesn't work.
<i class="fa fa-usesr"></i> Go to Users
// This works, as we know it but won't pass the Area needed.
<i class="fa fa-users"></i> Go to Users
So, how do you pass the Area using Url.Action()?

You can use this Url.Action("actionName", "controllerName", new { Area = "areaName" });
Also don't forget to add the namespace of the controller to avoid a conflict between the admin area controller names and the site controller names.
Something like this
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Admin_default",
"Admin/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional },
new[] { "Site.Mvc.Areas.Admin.Controllers" }
);
}

#Url.Action("{action}", "{controller}", new { Area = "areaname" });
#Html.ActionLink("LinkName", "{action}", "{controller}", new { area = "{areaname}" }, new { #class = "btn btn-cool" })
write area name as html attribute with anonymus object. you can use actionlink html helper extension method to achieve same thing.

If you want to create link for root controllers, it's enough to use this code:
Url.Action("ShowImage", "Page", new { Area = "" })

#Url.Action("{action}", "{controller}", new { Area = "areaname" });
#Html.ActionLink("LinkName", "{action}", "{controller}", new { area = "{areaname}"}, new { #class = "btn btn-cool" })
You can use above this

Related

Display query string in specific format in mvc form

when we submit form with get method, it pass parameters as querystring like below:
http://localhost:2564/Blog?SearchManufacturer=land
But, I want to display query string like below:
http://localhost:2564/Blog/SearchManufacturer/land
I have tried below code. but still it passing with query string.
#using (Html.BeginForm("Index", "Blog", new { CurrentFilter = Model.SearchManufacturer }, FormMethod.Get))
{
<div class="form-group col-lg-4 col-md-6 col-sm-6 col-lg-12">
<label>Search Manufacturer</label>
#Html.TextBoxFor(x => x.SearchManufacturer, new { #class = "form-control" })
</div>
<div class="form-group col-lg-4 col-md-6 col-sm-6 col-lg-12">
<input type="submit" value="Search" class="submit" />
</div>
}
also, in route.config, I have used different combinations of routing as below.
routes.MapRoute("Blog", "Blog/SearchManufacturer/{SearchManufacturer}", defaults: new { controller = "Blog", action = "Index" });
routes.MapRoute("BlogbyPageSortandFilter", "Blog/Page/{page}/CurrentFilter/{currentFilter}/SortBy/{sort}", defaults: new { controller = "Blog", action = "Index" });
routes.MapRoute("BlogbyPageandSort", "Blog/Page/{page}/SortBy/{sort}", defaults: new { controller = "Blog", action = "Index" });
routes.MapRoute("BlogbyPageandFilter", "Blog/Page/{page}/CurrentFilter/{currentFilter}", defaults: new { controller = "Blog", action = "Index" });
routes.MapRoute("BlogbySortandFilter", "Blog/SortBy/{sort}/CurrentFilter/{currentFilter}", defaults: new { controller = "Blog", action = "Index" });
routes.MapRoute("SortBlog", "Blog/SortBy/{sort}", defaults: new { controller = "Blog", action = "Index" });
routes.MapRoute("BlogbyPage", "Blog/Page/{page}", defaults: new { controller = "Blog", action = "Index" });
routes.MapRoute("BlogbyFilter", "Blog/CurrentFilter/{currentFilter}", defaults: new { controller = "Blog", action = "Index" });
these routing are used for sorting, paging, filtering using Pagedlist.mvc. all these are working fine. but searching is not passing parameter as in routing. it is passing parameter as query string.
please help me to fix this.
Thanks
Lalitha
If your form method is set to GET type, when you submit the form, form data will be appended to the action attribute url as querystring values (which starts with ?). This is something the browsers does. Your asp.net mvc routing cannot do anything on this.
If you absolutely need the /Blog/SearchManufacturer/land url when the form is submitted, you can hijack the form submit event with client side javascript and update the url however you want. The below code will give you the output you want.
$(function () {
$("#searchFrm").submit(function (e) {
e.preventDefault();
var formAction = $(this).attr("action");
if (!formAction.endsWith('/')) {
formAction += '/';
}
var url = formAction +'SearchManufacturer/'+ $("#SearchManufacturer").val();
window.location.href = url;
});
});
Assuming your form tag has an Id value "searchFrm"
#using (Html.BeginForm("Index", "Blog",FormMethod.Get,new { id="searchFrm"}))
{
// Your existing code goes here
}

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}))

.net MVC4 Form submit generates ? instead of / in url -- wrong routing?

i'm kinda new to asp.net mvc4 and try to get some practise now. after some research about routing i still got a problem to pass parameters after a form submit.
my form looks like this:
#using (Html.BeginForm("Index", "Resplaner", FormMethod.Get, new { name = "navigation", id = "navigation" }))
{
<select name="id" size="15" id="nav_menu">
#foreach (var categorie in Model.Categories)
{
<optgroup label="#categorie.Name">
#foreach (var ressource in Model.Ressources)
{
if (#categorie.Id == ressource.Type)
{
<option value="#ressource.Id">#ressource.Name</option>
}
}
</optgroup>
}
</select>
}
which is submitted by the following java script:
$('#nav_menu').on('click', function (event) {
if ($(event.target).is("option")) {
var form = $(event.target).parents('form');
form.submit();
}
});
my actual routes are configurated like this:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Resplaner",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Resplaner", action = "Index", id = UrlParameter.Optional }
);
so my problem is right now that my generated url after the form submit looks like this
http://localhost:62456/Resplaner?id=6
but my desired url look should look like this
http://localhost:62456/Resplaner/Index/6
if i type the second url manually to my browser, the correct result is shown... thats why i guess there is something wrong in the way how i submit my form. or my routes are still messing up.
i already did some example tutorials about forms in mvc4 but they are always used in a different case like my. so i would be happy about a helping hand.
i am thankful for every help :)
greetings Kurn
Here goes my solution -
Have your html like this -
#using (Html.BeginForm("Index", "Resplaner", new { name = "rami", id = "1" }, FormMethod.Get))
{
// ....
}
Then have a route this way -
routes.MapRoute(
name: "MyRoute",
url: "{controller}/{action}/{name}/{id}",
defaults: new { controller = "Resplaner", action = "Index" }
);
Then your jquery hits the form submit, your URL is going to be -
And the URL is going to be - http://localhost:5738/Resplaner/Index/rami/1?
NOTE: If you do not want that Question mark at the end, then make a POST instead of GET.
The other solution would be to use Hidden Fields -
#using (Html.BeginForm("Index", "Resplaner", FormMethod.Get))
{
#Html.Hidden("id", "1");
#Html.Hidden("name", "rami");
<input type="submit" value="click"/>
}
But again this approach will give you - http://localhost:5738/Resplaner/Index?id=1&name=rami
One more Alternative is to create a #Html.ActionLink() with the required URL and make it click in jquery.
Ok fixed it on another way.
To fix my actual problem i just added a new action in my Controller which receive the form parameter with the question mark and simply do a redirect to the desired url.
[HttpGet]
public ActionResult IndexMap(String id = "1")
{
return RedirectToAction("Index", "Resplaner", new { id = id });
}
It may be not the best way to do it because of the second server call. but for my project i dont see any performance issues since it will be only used in an intranet.
http://localhost:62456/Resplaner/IndexMap?id=2 will redirect to http://localhost:62456/Resplaner/Index/2
I would like to thank everyone who tried to help me. You gave me some great suggestions and ideas.

Routing issue with MVC

I'm working with MVC 3 and have an issue. Instead of giving mydomain/mydirectory/item like I expected I get this:
mydomain/mydirectory/list?animal=quack.
Here's the route in the global
//Default route mapping
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new { controller = #"[^\.]*", action = #"[^\.]*" }
);
Code showing how I'm building the link:
<div id="main-content" title="AnimalBox" style="float:none;">
<% Html.DataList(Model.PriceListAnimals).Columns(7).Item(item =>
{
item.Template(galleryImage =>
{%>
<div style="margin-left:20px; line-height:150%;">
<span><%= Html.ActionLink(galleryImage.AnimalName,"List",new { #animal = galleryImage.AnimalName }) %></span>
</div>
<% });
}).Render(); %>
</div>
Any ideas?
You have to define a route for special case routing like your instance. Since you are passing 'animal' as a parameter, you should create a route to handle that instance. In your global.aspx (above the default route), create something like below:
routes.MapRoute(
"Animal", // A distinct Route name
"{controller}/{action}/{animal}", // URL with parameters
new { controller = "MyDirectory", action = "List"}
);
This will define a route to the MyDirectory controller on the action list which has an animal parameter which is NOT OPTIONAL. Defining routes is what enables you to generate clean URLs from the html helpers and other methods (redirect to action, etc).
The overload for Html.ActionLink is:
Html.ActionLink("linkText", "actionName", "controller", object routeValues, object HtmlAttributes)
From what you've said, mydirectory = controller, and List = action, correct? If so, try:
<%= Html.ActionLink(galleryImage.AnimalName, "List", "mydirectory", new { #id = galleryImage.AnimalName }, null) %>
this should produce:
quack

#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>
}

Resources