Redirect request to matching controller - asp.net-mvc

If user hits http://somewebsite/Cnt but i dont have controller with that name and i would like to redirect user to http://somewebsite/Country. Same way if user hits /ofr then i will redirect him to /Offer.
How do i do that?

First, you could create RouteHandler that would handle shortened routes - to not repeat entire code of MvcHandler, you could just derive from it and replace RouteData["controller"], and let MvcHandler execute
public class ShortenedUrlHandler : MvcRouteHandler
{
public static Dictionary<string, string> _shortenedControllers = new Dictionary<string, string>
{
{ "Cnt", "Country" },
{ "Ofr", "Offer"}
};
protected override IHttpHandler GetHttpHandler(RequestContext requestContext)
{
string shortenedControllerName = requestContext.RouteData.Values["controller"].ToString();
if (_shortenedControllers.ContainsKey(shortenedControllerName))
{
requestContext.RouteData.Values["controller"] = _shortenedControllers[shortenedControllerName];
}
return base.GetHttpHandler(requestContext);
}
}
than just register this handler instead of MvcHandler (this is registered by default for all mvc routes)
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Default", action = "Index", id = UrlParameter.Optional } // Parameter defaults
).RouteHandler = new ShortenedUrlHandler();
If you do not want all the requests to pass additional check whether they are shortened or not, you could create another route and set constraints for its {controller} value

Sounds like you want to identify when a user hits a non-existent url on your site and send them to a existing page. If this is what you want then update your last route in your Global.asax.cs file to point to your "Country" page:
routes.MapRoute(null, "{*url}",
new { controller = "Country",
action = "Index" }
);

Related

How to get the add the query string to actionLink?

The below link gives be the following url: http://localhost:11111/files/Details/3
#Html.ActionLink("Details", "Details", "mycontroller", new { id = item.id },null)
But I'm trying to have a url parameter like this http://localhost:11111/files/Details?id=3 or http://localhost:11111/files/Details.aspx?id=3
How do I get the actionlink to show the url like details?i=3
Here is my controller View:
public ActionResult Details(int? id)
{
...
return View();
}
Why would you like to see the parameter's name in the link?
Asp.Net MVC uses user-friendly URLs.
If you have created a project in Visual Studio using the MVC template, probally your routes, by default, are configured to interpret the parameter after the controller/action/ like the id.
So the id parameter's value in your action will be automatically replaced, by model binding, with the id number present in you URL.
The routing codes can be found under the RegisterRoutes method in the Global.asax file of our project.
I see a cookie already in the RegisterRoutes method.
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults);
Using the MapRoute method above, we defined a new route.
Sample ;
public class HaberController : Controller
{
public ActionResult Listele()
{
// Listing codes will be written
return View("Listele");
}
public ActionResult Detay(string HaberId)
{
// Detail codes will be written
return View("Detay");
}
}
We go to our Global.asax file and edit it as follows.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"HaberListeleme",
"Haber",
new { controller = "Haber", action = "Listele" }
);
routes.MapRoute(
"HaberDetay",
"Haber/{id}",
new { controller = "Haber", action = "Detay" }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
}
If we do the routing as follows:
routes.MapRoute(
"HaberDetay",
"Haber/{*Id}",
new { controller = "Haber", action = "Detay" }
);
So if we write * by putting the character next to our parameter name, it will be sent to the related parameter of the Detail method in the Controller, no matter what it says after the News / url tab.
For example:
http://www.doguhanaydeniz.com/Haber/Turkiye/Guncel/34389
If a URL is requested as Turkey / current / 34389 will be sent as a parameter.

ASP .Net custom route not working

ASP .Net custom route not working.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//default route
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Account", action = "LogOn", id = UrlParameter.Optional } // Parameter defaults
);
//custom route
routes.MapRoute(
"Admin",
"Admin/{addressID}",// controller name with parameter value only(exclude parameter name)
new { controller = "Admin", action = "address" }
new { addressID = #"\d+" }
);
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
public ActionResult address(int addressID = 0)
{
//code and redirection
}
Here I want to hide everything from the url if possible...like i want to hide action name and parameter name and value if possible...
Suggest me the possible way to do this
Like I want URL like this (on priority basis)
1.http: //localhost:abcd/Admin
or
2.http: //localhost:abcd/Admin/address
or
3.http: //localhost:abcd/Admin/1
or
4.http: //localhost:abcd/Admin/address/1
for quick reference.
the custom route should appear before the default.
try naming your custom rout as null.
routes.MapRoute(
null, // Route name...
check that your calling the correct action.
if youre dealing with actions that dont recieve a parameter upon initial load(example paging)
makesure that your parameter is nullable address(int? addressID)
and on your custom route it should be like this
//custom route
routes.MapRoute(
null, //<<--- set to null
"Admin/{addressID}",// controller name with parameter value only(exclude arameter name)
new { controller = "Admin", action = "address" }
//new { addressID = #"\d+" } <<--- no need for this because based from your example " 2.http: //localhost:abcd/Admin/address" the parameter can be null.
);
thanks

URl rewriting in mvc

Hy
i had write below code
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Home", // Route name
"", // URL with parameters
new { controller = "Home", action = "Index" } // Parameter defaults
);
routes.MapRoute(
"Controller_Action", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { id = UrlParameter.Optional } // Parameter defaults
);
foreach (var route in GetDefaultRoutes())
{
routes.Add(route);
}
routes.MapRoute(
"UserPage", // Route name
"{id}", // URL with parameters
new { controller = "Home", action = "Get" } // Parameter defaults
);
}
private static IEnumerable<Route> GetDefaultRoutes()
{
//My controllers assembly (can be get also by name)
Assembly assembly = typeof(test1.Controllers.HomeController).Assembly;
// get all the controllers that are public and not abstract
var types = assembly.GetTypes().Where(t => t.IsSubclassOf(typeof(Controller)) && t.IsPublic && !t.IsAbstract);
// run for each controller type
foreach (var type in types)
{
//Get the controller name - each controller should end with the word Controller
string controller = type.Name.Substring(0, type.Name.IndexOf("Controller"));
// create the default
RouteValueDictionary routeDictionary = new RouteValueDictionary
{
{"controller", controller}, // the controller name
{"action", "index"} // the default method
};
yield return new Route(controller, routeDictionary, new MvcRouteHandler());
}
}
i am new to mvc,i want to rewrite my url somthing like this,suppose my url is like www.myhouse.com/product/index/1 then i want to display only www.myhouse.com/prduct-name for better seo performance,i am using mvc4 beta,i had also one through URL Rewriting in .Net MVC but it is not working for me....
but i don't know how to pass pass value to this method.
After lots of searching on the internet, i got my solution
add below code to global.asax
routes.MapRoute(
"Home", // Route name
"", // URL with parameters
new { controller = "Home", action = "Index" } // Parameter defaults
);
routes.MapRoute(
"jats", // Route name
"{jats}", // URL with parameters
new { controller = "Home", action = "Content" } // Parameter defaults
);
then add below code to view:
#Html.ActionLink("test", "Content", new { jats= "test-test" })
add below code to HomeController:
public ActionResult Content(string jats)
{
return View();
}
then you done...now URL is same as you pass in query string...so your controller name and query string parameter will not display.

asp.net mvc - null parameter exception - could be routing problem?

I'm kind of new to MVC. I have a controller called PostItemsController in an area called CaseManagers with an action method called GetByUmi(int caseNumber):
[HttpGet]
public ViewResult ViewByUmi(int umi)
{
//implementation omitted
}
The routing configuration looks like this (not my work):
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("{resource}.aspx/{*pathInfo}");
//ignore route for ico files
routes.IgnoreRoute("{*favicon}", new { favicon = #"(.*/)?../Images/MauriceFavicon.ico(/.*)?" });
routes.IgnoreRoute("{*favicon}", new { favicon = #"(.*/)?Images/MauriceFavicon.ico(/.*)?" });
routes.IgnoreRoute("{*favicon}", new { favicon = #"(.*/)?Content/Images/MauriceFavicon.ico(/.*)?" });
routes.IgnoreRoute("{*favicon}", new { favicon = #"(.*/)?/favicon.ico(/.*)?" });
//ignore javascript files routing
routes.IgnoreRoute("{file}.js");
//ignore routing for files ending .doc
routes.IgnoreRoute("{resource}.doc");
routes.MapRoute(
"CaseManagers", // Route name
"CaseManagers/PostItems/ViewByUmi/{id}", // URL with parameters
new { controller = "PostItems" } // Parameter defaults
);
//InvoicesLookUp route
routes.MapRoute(
"InvoicesLookUpShortDefault", // Route name
"InvoicesLookUp/{action}/{id}", // URL with parameters
new { controller = "InvoicesLookUp", action = "Index", area = "Home", id = UrlParameter.Optional } // Parameter defaults
,
null,
new[] { "MooseMvc.Areas.Accounts.Controllers" } // Parameter defaults
).DataTokens.Add("area", "Accounts");
//Invoices route
routes.MapRoute(
"InvoicesShortDefault", // Route name
"Invoices/{action}/{id}", // URL with parameters
new { controller = "Invoices", action = "Index", area = "Accounts", id = UrlParameter.Optional } // Parameter defaults
,
null,
new[] { "MooseMvc.Areas.Accounts.Controllers" } // Parameter defaults
).DataTokens.Add("area", "Accounts");
//administrating route
routes.MapRoute(
"AdministratorShortDefault", // Route name
"Administrator/{action}/{id}", // URL with parameters
new { controller = "Administrator", action = "Index", area = "Administrator", id = UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
//add root route route
routes.MapRoute(
"Root",
"",
new { controller = "Home", action = "Index", id = "" }
);
When I try to call this method with the URL http://localhost:[portnumber]/CaseManagers/PostItems/ViewByUmi/1234 I get the following exception:
The parameters dictionary contains a null entry for parameter 'umi' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ViewResult ViewByUmi(Int32)' in 'MooseMvc.Areas.CaseManagers.Controllers.PostItemsController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
Parameter name: parameters
I don't intend the ID parameter to be optional and I don't understand why MVC can't find the ID.
Can anyone tell me what I need to do?
EDIT:
Phil Haack's route tester is telling me that the following route is being mapped:
routes.MapRoute(
"CaseManagers", // Route name
"CaseManagers/PostItems/ViewByUmi/{id}", // URL with parameters
new { controller = "PostItems" } // Parameter defaults
);
But it is being mapped AFTER another route CaseManagers/{controller}/{action}/{id}. But this route isn't anywhere in the Global.asax file (take a look, it's reproduced in full above).
Any idea what's going on?
Method parameters in ASP.NET MVC match up 1-1 with route parameters. Since you have no routes that take in a route value named umi, no route will catch what you're trying to do.
You have one of two choices:
If you want the default route to handle that action, then change:
public ViewResult ViewByUmi(int umi)
{
//implementation omitted
}
to:
public ViewResult ViewByUmi(int id)
{
//implementation omitted
}
However, if you want to keep umi(because it has contextual meaning that makes that code easier to follow), then you want to add a route to explicitly deal with it:
//UMI route
routes.MapRoute(
"umi",
"/case/postitems/view/{umi}",
new { area = "CaseManager", controller = "PostItems", action = "ViewByUmi", umi = "" }
);
Turns out that Global.asax isn't the only place that routing happens. Each of the areas in this application has its AreaRegistration class. I added a new route to the top of this class to produce the following:
public class CaseManagersAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "CaseManagers";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"PostItems", // Route name
"CaseManagers/PostItems/ViewByUmi/{umi}", // URL with parameters
new { area = "CaseManagers", controller = "PostItems", action = "GetByUmi", umi = "{umi}" } // Parameter defaults
);
context.MapRoute(
"CaseManagers_default",
"CaseManagers/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
The routing debugger now tells me this is getting matched first. Now I just need to work out why I've got an error telling the the resource cannot be found...
You don't have a route for CaseManagers/PostItems/ViewByUmi/1234 and it would appear that it is taking ViewByUmi and try to convert it to an System.Int32 because it is falling into the Default route. If you create a Route for your CaseManagers you should no longer have this problem.
Use Phil Haacks' Route Debugger to help you out :o)
routes.MapRoute(
"CaseManagers", // Route name
"CaseManagers/PostItems/ViewByUmi/{id}", // URL with parameters
new { controller = "PostItems" } // Parameter defaults
);

Dynamic ASP.Net Routing problem

I am new to ASP.Net MVC. May be this question looks simple, but i couldn't fix it. Here the scenario. I have an application listing data based on city. So the url will be looking like this
www.xxxxxx.in/chennai
www.xxxxxx.in/mumbai
www.xxxxxx.in/delhi
In normal routing the first part (chennai/mumbai) is controller in the above url, But here i dont want this to be a controller. instead i want to map the single controller (LocationController) to these URl's. Because later time i can add any number of city.
I am struck here, can someone help me out.
Try this:
routes.MapRoute(
"CityRoute", // Route name
"{city}", // URL with parameters
new { controller = "Location", action = "Index", city = "" } // Parameter defaults
);
I am not sure there won't be easier option than this, but you can try this - using route constraint. Basically, you need to know the list of cities you have and then constrain the route to match only entries in that list.
The route constraint can be implemented as follows
public class CityConstraint : IRouteConstraint
{
public static IList<string> CityNames = (Container.ResolveShared<ICityService>()).GetCities();
bool _IsCity;
public CityConstraint(bool IsCity)
{
_IsCity = IsCity;
}
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
if (_IsCity)
return CityNames.Contains(values[parameterName].ToString().ToLower());
else
return !CityNames.Contains(values[parameterName].ToString().ToLower());
}
}
And then put the route as follows:
routes.MapRoute("Location", "{cityName}", new { controller = "LocationController", action = "Index" }, new { cityName = new CityConstraint(true) });
Also make sure the above route is listed before the default route
routes.MapRoute("Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional
);
Also note that, no controller name can be a city name.
Try this and see.
If all your routing is related to these cities than remove default route and replace it with this route definition:
routes.MapRoute(
"Default",
"{city}",
new { controller = "Location", action = "Index", city = "Mumbai" }
);
Then create a LocationController class:
public class LocationController : Controller
{
public ActionResult Index(string city)
{
// do whatever needed; "city" param has the city specified in URL route
}
}
If you still need your default route (controller/action/id) for other pages not just cities then it's probably better to put a constraint on your default route and define them like this:
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new { controller = "Home|...|..." } // put all controllers here except "Location"
);
routes.MapRoute(
"Location",
"{city}",
new { controller = "Location", action = "Index", city = "Mumbai" }
);
This will make other controllers still working and location will work just as well. The problem is of course if there's a city name that's the same as a name of one of your regular controllers. :) But you can control/avoid that as well.
You can do that by adding a route that hardcodes the controller name:
routes.MapRoute(
"location", // Route name
"{cityName}", // URL with parameters
new { controller = "location", action = "index" } // Parameter defaults
);
routes.MapRoute(
"Location", // Route name
"{controller}/{action}/{cityName}", // URL with parameters
new { controller = "Location", action = "index"} // Parameter defaults
)
This will route all requests of the form "/mumbai" to LocationController action method Index with parameter cityName set to "mumbai". It will also be able to route full controller/action spec using the second route.

Resources