asp mvc create seo friendly URL with parameter - c#

I am trying to create seo friendly url.
current url:
http://www.example.com/Product/free-mobile-images/Mobile
expected ouput:
http://www.example.com/Product/free-mobile-images/
I am using id to fetch moblie data from database.
ActionMethod
public ActionResult Product(string seotext, string id)
{
return View();
}
Route.config
routes.MapRoute(
"Product",
"Product/{seotext}/{id}",
new { controller = "Home", action = "Product" });
I tried to remove moblie from the route value:
RouteData.Values.Remove("id");
RouteData.Values.Remove("Mobile");
But still I get /Mobile at the end of url.
May I know what wrong I am doing, any help would be great.

Why don't you just create a folder structure to mimic the path you want and then call your file Index.aspx, it will have the same effect but is much simpler.
Eg folder called Product, then inside that a folder called free-mobile-images and then your file called index.aspx

Related

I'm seeing strange ActionLink behaviour, why is the url displayed in the browser not displaying the seemingly correct controller?

I have the following ActionLink:
#Html.ActionLink("Upload", "Upload", "File")
yet when I hover over the link, the url displayed in the browser is http://localhost:44334/Upload. Where is the controller in this url? Strangely, clicking the url takes me to my File/Upload view, and yet stranger, the url displayed in the browser's address bar is https://localhost:44334/Upload.
The ActionLink is on page Home/Explorer, so AFAIK a controller name is normally necessary.
Why is the ActionLink helper leaving out the controller name, and why is the link still working? I have tried refreshing the page with cache clearing, with no difference. I don't know what else do besides leave it alone because it works, but I'm concerned this is some quirk and it will no longer work when I deploy my site.
My routing is still standard, out-of-box, in the Startup class's Configure method:
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
Strangely enough, I have now added a Download link each row of an HTML table of files, looking like this:
#Html.ActionLink("Download", "Download", "File", new { filePath = file.Path })
and this link also renders without the controller name, e.g:
https://localhost/Download?filePath=....
Http{Verb}("{routeTemplae}") is usually used when building a REST API. In order to be able to generate URLs for the default MVC controllers when using attribute routing you will need to use Route attribute.
The original controller probably did not have a route prefix which meant that
//POST /Upload //<-- when there is no prefix on the controller
[HttpPost("Upload")]
on the controller would route to /Upload with no controller prefix.
By including a prefix for the route on the controller it will include the controller name when generating URLs when using attribute routing.
[Route("[controller]"]
public class FileController : Controller {
//POST File/Upload
[HttpPost]
[Route("Upload")]
public async Task<ActionResult> Upload(UploadFilesViewModel model, IEnumerable<IFormFile> files) {
//...
}
//GET File/Download
[HttpGet]
[Route("Download")]
public async Task<IActionResult> Download(string filePath) {
//...
}
}
Reference Routing in ASP.NET Core
Reference Routing to Controller Actions
This is most strange, but in my FileController, I had leftover attribute routing from when I was using the the controller for a Web API instead of in the MVC web application. The methods essentially looked like this:
[HttpPost("Upload")]
public async Task<ActionResult> Upload(UploadFilesViewModel model, IEnumerable<IFormFile> files)
[HttpGet("Download")]
public async Task<IActionResult> Download(string filePath)
Now that I have removed the route names from the attributes, and have just plain [HttpPost] and [HttpGet], the actionlinks work correctly and render URLs that now do contain the controller name.
[HttpPost("Upload")]
Here Using POST method so no need of prefix like '/' on MVC controller
[HttpGet("Download")]
public async Task Download(string filePath)

ASP.NET MVC routing aspx file

So I'm writing an ASP.NET MVC app and I have a little bit problem with routing aspx file - in general making this work.
Let's say I have a razor page and I want to, for example open specific row from database and show it, it's very simple and I just write in index.cshtml:
#Url.Action("Details", new { id = item.DB_Id })
And details page opens and I can see specific informations of this row in database
Code of routing:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home",
action = "Index",
id = UrlParameter.Optional
}
But when I want do the same but instead of opening details.cshtml file I'd like to do it with details.aspx (Web Form) appears a problem. Is controller has to be different, is code of routing has to be different? Or is it basically possible? And ideas or hints?
Url.Action helper doesn't create URL's to Web Forms pages because they aren't Actions. You'll need to do something like
#Url.Content("~/somefolder/Details.aspx?id=" + item.DB_Id)
Url.Content is meant for creating URL's to static files, but it also works well with Web Forms.
You could create your own helper that handles parameters more cleanly. I don't have time to do the implementation right now, but you could create something like:
#Url.WebFormsPage("~/somefolder/Details.aspx", new { id = item.DB_Id })
The helper could use reflection to generate the appropriate query string and append it to the URL.

How to redirect custom aspx page to mvc action

I have upgrade aspx project to mvc. Now some of my old customer calling url with .aspx page and they are getting 404(not found) in mvc project.
So now I have to redirect .aspx to mvc page.
Old URL
www.domain.com/bookshop/pc-58573-53-{product_name}.aspx
New URL
www.domain.com/{product_name}
I am thinking to do via routing mechanism of mvc. like once this type of url come then it should be call my custom mvc action and in string parameter i will get pc-58573-53-{product_name}.aspx
Can you please suggest a best way to do this with minimal code.
Just define an action with route 'bookshop/{pageName}'
Here are examples for 2 scenarios using Route attribute:
In case, you don't want the URL to change:
[Route("bookshop/{pageName}")]
public ActionResult MyAction(string pageName)
{
// add logic according to what you receive in pageName property
return View();
}
or, In case you want to Redirect to a new URL:
[Route("bookshop/{pageName}")]
public ActionResult MyAction(string pageName)
{
// Create and use a method to ExtractProductNameFromPageName
string productName = ExtractProductNameFromPageName(pageName);
return Response.Redirect("~/" + productName);
}
The parameter 'pageName' here should catch the page name past 'bookshop/'.
In case, you don't have route attribute mapping enabled, add code below in RegisterRoutes method of RouteConfig.cs file:
// enable mapping of routes defined using Route attribute on specific actions.
routes.MapMvcAttributeRoutes();

route not mapping mvc 3

I am new in mvc and I have a situation where I am convinced that I am mapping a route correctly although it is not.
it is a very basic login form with the option of passing in parameters.
this is the html
<li>Login</li>
and this is the action method in the 'Home' controller
public ViewResult LoginForm(string userName)
{
return View();
}
This is how is my attempt at mapping the route
routes.MapRoute(
null,
"Login/{userName}",
new { controller = "Home ", action = "LoginForm", UrlParameter.Optional }
);
The url is however displaying as follow
/Home/LoginForm?loginUser=user
my aim would be the following
Login/user
Advice perhaps as to why it is not mapping correctly. I have already registered a number of routes in the Global.asax.cs file. Could it have something to do with the order with which they were registered?
Try this:
<li>Login</li>
change the parameter loginUser to userName.
Use userName instead of loginUser
<li><a href='#Url.Action("LoginForm", "Home", new {userName="user"})'>Login</a></li>
You are hitting a different address than the one specified in MapRoute. The mapped route will not fire. Change both the parameter and the action name.
<li>Login</li>
You need to access /Home/Login not /Home/LoginForm. The routing is done automatically if the right address is accessed.
EDIT:
Following your address edit:
As far as I know, you cannot generate a link such as Login/{userName} using Url.Action; if you don't specify a controller, this defaults to Home controller
You can however access the Login/{userName} link directly from the browser (due to the mapped route)
You can create a "static" (i.e. classic) link, passing a hard-coded address:
<li>Login</li>
Please note that the userName added/removed per JavaScript.

Correct Process for Routing with Admin Subsite

I'm building my first Asp.Net MVC2 Site, and i'm now trying to add an /Admin area to the site.
I don't want this area to be visibile to the main set of users so will only be accessible when you enter http://Intranet/Admin
What I have is a NewsController for my regular users but I also want an Admin NewsController and I'm not sure how to setup the Class hierarchy and folders so that when I add the Views they are in the correct location.
Inside my Global.Asax.cs I've added and the routes resolve correctly.
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new string[] { "Intranet.Controllers" }
);
routes.MapRoute(
"Admin", // Route name
"Admin/{controller}/{action}/{id}", // URL with parameters
new { controller = "Admin", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new string[] { "Intranet.Controllers.Admin" }
);
And in the folder hierarchy I've setup
Views/
Admin/
News/
...I want the new view to go here...
In the Controllers
Controllers/
Admin/
AdminController.cs
NewsController.cs (this is the one i want for administration)
NewsController.cs (this is the regular one for viewing the list, specific item etc)
The problem I face is when I go into the admin/NewsController.cs on Index and Add View it tries to create it at the /News/Index.aspx rather than /Admin/News/Index.aspx.
This is the code for my admin news controller Controllers/Admin->Add->Controller
namespace Intranet.Controllers.Admin
{
public class NewsController : Controller
{
public ActionResult Index()
{
return View();
}
}
}
Is there something I'm doing incorrectly, or what should I change so that when I add the views they are being created in the /Admin/{area} directory.
Since you're using MVC2, the easiest way to solve this is the create an actual MVC "Area" for your Admin section. Right now you're doing everything in the default section and just using an Admin folder. If you create an Admin area (under the well-known location Areas) folder, then you'll have an AdminAreaRegistration - where is where you'll configure your Admin routes. Because you'll do this as part of the Area, then the first segment of the URL "/Admin" will be used for the "area" token. This will disambiguate which controller to use and correctly pick up the controller you want. So you're folder structure will be:
/Areas
/Admin
/Controllers
NewsController.cs
etc.
When you try to create a View for the existing Controller Action it always create on the root folder of the Views. The default route for the View is always pointing to the root of the Views folder.
For example:
Controllers
Admin
AdminController.cs
HomeController.cs
HomeController.cs
In that hierarchy, both of the HomeController inside Admin and root shares the same Views in the Views Folder.
Views
Home
Index.aspx
Unless you return a specified View() in all of the ActionResults in your HomeController inside the Admin Folder of your Controllers. It will map to a certain View.
Example, ActionResult inside the HomeController.cs of Admin folder in Controllers.
namespace Intranet.Controllers.Admin
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View("Home/Index");
}
}
}
This will be mapped in the Views folder like this
Views
Admin
Home
Index.aspx
But if you do not specify the View path when you return a View in your ActionResult it will map to the default location of the Views which is like this.
Views
Home
Index.aspx
The reason for this is that even though you specify the routes in the Global.asax, that is only to map to which controller the url should point, not the Views folder.
When you right click and Create View on ActionResult of any Sublevels of the Controllers, it always create on the root of the Views folder to its corresponding Controller.

Categories