Change URL to remove query string variable name - asp.net-mvc

I have an MVC application and the url looks like this;
/celebritypage/celebrityname=Elma Fudd
What I'd like is to only have;
/celebritypage/Elma Fudd
Is this possible within routing?

Sure, something like this should work:
routes.MapRoute(
"RouteName",
"celebritypage/{name}",
new { controller = "celebritypage", action = "celebrityname" }
);
Then make sure your controller action is ready for the parameter:
//inside celebritypage Controller
public ActionResult celebrityname(string name) {
//code
return View("ViewName");
}

Related

How do I form the URL to call this WebAPI function?

I have this controller in an MVC 5 WebAPI application and I can't seem to figure out how to form the URL to call it. I keep getting a 404. tried .../ssa, /ssa/ssamedians, /ssa/ssamedians?titles=abc... What am I missing?
public class ssaController : ApiController
{
public IHttpActionResult getSsaMedians(string Titles = "")
{
SsaDB db = new SsaDB();
try
{
IEnumerable<Title_Medians> medians = db.getTitleMedians(Titles, null, null);
System.Web.HttpContext.Current.Response.AppendHeader("Access-Control-Allow-Origin", "*");
return Ok(medians);
}
catch
{
return NotFound();
}
}
There are also Actions called getSsaMediansByAaa() and getSsaMediansByBbb(). Once I got rid of the api/ in the routeTemplate, I now get a "Multiple actions were found that match the request".
Open your WebApiConfig.cs file and add this:
config.Routes.MapHttpRoute(
name: "SSATitles",
routeTemplate: "api/{controller}/{action}/{Titles}",
defaults: new { controller = "ssa", action = "getSsaMedians", Titles = UrlParameter.Optional }
);
For more information on webapi routing look here:
http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api
You have an parameter in your method, that means that you need to add an extra link in your url.
Examlple.com/DirToApi/getSsaMedians/YourString
You may also want to check your RouteConfig file in your App_Start

Redirect with ASP.NET MVC MapRoute

On my site, I have moved some images from one folder to another.
Now, when I receive a request for old images '/old_folder/images/*' I want to make a permanent redirect to new folder with these images '/new_folder/images/*'
For example:
/old_folder/images/image1.png => /new_folder/images/image1.png
/old_folder/images/image2.jpg => /new_folder/images/image2.jpg
I have added a simple redirect controller
public class RedirectController : Controller
{
public ActionResult Index(string path)
{
return RedirectPermanent(path);
}
}
Now I need to setup proper routing, but I don't know how to pass the path part to the path parameter.
routes.MapRoute("ImagesFix", "/old_folder/images/{*pathInfo}", new { controller = "Redirect", action = "Index", path="/upload/images/????" });
Thanks
I would do in next way
routes.MapRoute("ImagesFix", "/old_folder/images/{path}", new { controller = "Redirect", action = "Index" });
and in controller like that
public class RedirectController : Controller
{
public ActionResult Index(string path)
{
return RedirectPermanent("/upload/images/" + path);
}
}
first download and install RouteMagic package from this link , then redirect your old address to the new address Like the below code :
var NewPath = routes.MapRoute("new", "new_folder/images/{controller}/{action}");
var OldPath = routes.MapRoute("new", "old_folder/images/{controller}/{action}");
routes.Redirect(OldPath ).To(NewPath );
for more information please check out the following link
Redirecting Routes To Maintain Persistent URLs
Answer above using RouteMagic is a good idea, but the example code is wrong (it's included in Phil's post as a bad example).
From the RouteMagic Github demo site global.asax.cs:
// Redirect From Old Route to New route
var targetRoute = routes.Map("target", "yo/{id}/{action}", new { controller = "Home" });
routes.Redirect(r => r.MapRoute("legacy", "foo/{id}/baz/{action}")).To(targetRoute, new { id = "123", action = "index" });
If you specify two routes, you will be setting up an extra mapping that will catch URLs which you don't want.

ASPMvc Routing Issues with legacy url

I have got a legacy url that I cannot change, which is output on a page which needs to now post to a new MVC version of the page:
http://somesite.com/somepage?some-guid=xxxx-xxxx
Now I am trying to map this to a new controller but I need to get the some-guid into my controller:
public class MyController : Controller
{
[HttpGet]
public ActionResult DisplaySomething(Guid myGuid)
{
var someResult = DoSomethingWithAGuid(myGuid);
...
}
}
I can change the controller and routes as much as I like, however the legacy url cannot change. So I am a bit stumped as to how I can get access to the some-guid.
I have tried routing with the ?some-guid={myGuid} but the routing doesn't like the ?, so then I tried to let it autobind, but as it contains hyphens it doesn't seem to bind. I was wondering if there was any type of attribute I could use to hint that it should bind from a part of the querystring...
Any help would be great...
I would have thought you would have done a route a bit like this..
routes.MapRoute(
"RouteName", // Name the route
"somepage/{some-guid}", // the Url
new { controller = "MyController", action = "DisplaySomething", some-guid = UrlParameter.Optional }
);
The {some-guid} part of URL matches your url parmater and passes it to the controller.
So if you have your action like so :
public ActionResult DisplaySomething(Guid some-guid)
{
var someResult = DoSomethingWithAGuid(some-guid);
...
}
Give that a go and see how you get on..
routes.MapRoute(
"Somepage", // Route name
"simepage", // URL with parameters
new { controller = "MyController", action = "DisplaySomething"
);
And then in your controller:
public class MyController : Controller {
public ActionResult DisplaySomething(Guid myGuid)
{
var someResult = DoSomethingWithAGuid(myGuid);
...
}
}
Try this:
routes.MapRoute("SomePageRoute","Somepage",
new { controller = "MyController", action = "DisplaySomething" });
And then in your controller:
public ActionResult DisplaySomething() {
Guid sGuid = new Guid(Request.QueryString["some-guid"].ToString());
}

How can map an asp.net MVC route with more than 3 components?

I'm trying to learn asp.net mvc, and almost everywhere I see route description with three components like /Controller/Action/{anyParams}
I'd like to know if I can map a route similar to,
/Folder(or namespace)/Controller/Action/params...
ex:
/Admin/Student/Edit/id
/ABC/Faculty/Add/`
/XYZ/Student/Edit/id
or in general,
/XYZ/Controller1/Action/{param}
Yep the second parameter in the MapRoutes function (usually in Global.asax.cs is Url and this can be any pattern you want. something like
routes.MapRoute("MyRoute", "XYZ/Controller1/Action/{param}",
new {controller = "Controller1", action = "Action"}});
should do the trick.
You can make your routes as complex as you want.
F.e. the following route:
routes.MapRoute("some-route", "products/detail/order/{id}/{name}/",
new { controller = "Products", action = "Order" },
new { id = "^\d+" });
will route to the following function:
public class ProductsController : Controller {
public ActionResult Order (int id, string name) {
}
}
So you can specify as many parameters as you want, and they will be passed into your action as function parameters.

Pretty URL ASP.NET MVC

How can I get pretty urls like localhost:8888/News/Example-post instead of localhost:8888/Home/Details/2
My HomeController has the following for the Details method
public ActionResult Details(int id)
{
var ArticleToView = (from m in _db.ArticleSet where m.storyId == id select m).First();
return View(ArticleToView);
As the ASP.NET routing system is somewhat complicated, there are many ways to accomplish what you describe.
First of all, do you just want to have a pretty URL for the Details method? If so, you might consider renaming HomeController to NewsController or moving the Details method into a new NewsController class - that will automatically form the /News part of the URL. If you don't want a /Details part, you might rename your Details method Index, as that will be automatically called by /News. Finally, you need to change your int id parameter into string name.
If you want many custom URLs, you're going to have to define your own routes. Here are two ways of doing this:
1.
The easiest way I've found is to use an ASP.NET MVC Attribute-Based Route Mapper. That way, all you have to do is add an attribute on each method you want a pretty URL for and specify what URL you want.
First, you must follow a few steps to set up the attribute-based route mapping system, as outlined on that link.
After completing those steps, you must change your method to look like this:
[Url("News/{name}")]
public ActionResult Details(string name)
{
var ArticleToView = (from m in _db.ArticleSet where m.storyName == name select m).First();
return View(ArticleToView);
}
2.
Alternatively, you can define your custom routes manually in Global.asax.cs. In your RegisterRoutes method, you can add the following in the middle:
routes.MapRoute(
"NewsDetails",
"News/{name}",
new { controller = "News", action = "Details", name = "" }
);
What I do on my sites is that I check the URL against either the Page Title or Page Stub in cases where the page titles could have the same name for instance if you have a site that posts a "Picture of the Week" you may want to use a stub instead of title as you'll have multiples named the same thing.
URLs look like this: http://mySite.com/Page/Verse-of-the-Week
Global.asax contains this:
routes.MapRoute("Pages", "{controller}/{pageID}", new { controller = "Page", action = "Index", pageID = "Home" });
PageController is this:
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Index(string pageID)
{
if (pageID == null)
{
pageID = pageRepository.HomeOrLowest();
}
var p = pageRepository.ByStub(pageID);
if (p == null) { return RedirectToAction("NotFound", "Error"); }
return View(p);
}
The repository looks like this:
private static Func<mvCmsContext, string, Page> _byStub =
CompiledQuery.Compile((mvCmsContext context, string pageTitle) =>
(from p in context.Pages
where p.pageTitle.Replace(" ", "-") == pageTitle
select p).SingleOrDefault());
public Page ByStub(string pageTitle)
{
return _byStub(context, pageTitle);
}
I hope that helps.
Edit to add duplicate handling:
private static Func<mvCmsContext, string, int> _pageExists =
CompiledQuery.Compile((mvCmsContext context, string pageTitle) =>
(from p in context.Pages
where p.pageTitle.Replace(" ", "-") == pageTitle
select p).Count());
public bool PageExists(string pageTitle)
{
return Convert.ToBoolean(_pageExists(context, pageTitle));
}
Validates like this:
IValidationErrors errors = new ValidationErrors();
if (CreateOrEdit == "Create")
{
if (pageRepository.PageExists(model.pageTitle) && !String.IsNullOrEmpty(model.pageTitle))
errors.Add("pageTitle", "A page with this title already exists. Please edit it and try again.");
}
Please check out this package I've created: https://www.nuget.org/packages/LowercaseDashedRoute/
And read the one-line configuration here: https://github.com/AtaS/lowercase-dashed-route

Resources