I want to use Application_Error() in global.asax to log bad URL's on a website and redirect to custom error landing page. The problem is why does the website not passing through application error when controller doesn't exist.
I tested the following URL's and everything passed through application error:
http://localhost:11843/Account/randomtext
http://localhost:11843/Home/randomtext/randomval
This one doesn't pass through application error and returns 404:
http://localhost:11843/nonExistingController
Application error code:
protected void Application_Error(object sender, EventArgs e)
{
var requestTime = DateTime.Now;
Exception ex = Server.GetLastError().GetBaseException();
//log Request.Url.ToString()
}
RouteConfig.cs code:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Account",
url: "Account/{action}/{id}",
defaults: new { controller = "Account", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Home",
url: "Home/{action}/{test}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "HomeBlank",
url: "",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Please add the following to your RouteConfig.cs :
routes.MapRoute(
name: "NotFound",
url: "{*url}",
defaults: new { controller = "Error", action = "NotFound", id = UrlParameter.Optional }
);
Some URLs will fail to be parsed and adding above will handle these cases. In your action NotFound of ErrorController, you can show the user your Custom Error page.
public class ErrorController : Controller
{
public ActionResult NotFound()
{
Response.StatusCode = 404;
return View();
}
}
Related
I'm coding a website like a platform where we can access the user profile from the following URL:
www.mywebsite.com/DanielVC
The controller that has the details about the profile is the following
Controller: Perfil
Action: Perfil
I already have the following Route for all application:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Pages", action = "Index", id = UrlParameter.Optional }
);
I already tried to create the following route:
routes.MapRoute(
name: "Perfil",
url: "Pages/{id}",
defaults: new { controller = "Pages", action = "Index", id = UrlParameter.Optional }
);
But didn't work
Put this BEFORE (above) the default route.
routes.MapRoute(
name: "Perfil",
url: "{id}",
defaults: new { controller = "Pages", action = "Index", id = UrlParameter.Optional }
);
Also, this will result in every route to be redirected to Perfil route. You must create a redirection in that action if a username is not found (e.g. mywebsite.com/randomuserthatdoesntexist) and/or other routes (mywebsite.com/contact).
EDIT
Example for your method
public class PagesController : Controller
{
public ActionResult Index(string id)
{
if (matchesOtherRoute(id))
RedirectToAction("OtherAction", "OtherController");
if (!userExists(id))
RedirectToAction("NotFoundAction", "ErrorController");
// Do other stuff here
}
}
it should be like
routes.MapRoute(
name: "Perfil",
url: "Pages/{id}",
defaults: new { controller = "Perfil", action = "Perfil", id = UrlParameter.Optional }
);
I just created below action in my controller:
public ActionResult Serial(string letterCase)
{
string serial = "SAM_ATM_1.0.0";
if (letterCase == "lower")
{
return Content(serial.ToLower());
}
return Content(serial);
}
and added below routing rules above default action:
routes.MapRoute(
name: "Serial",
url: "serial/{letterCase}",
defaults: new { controller = "Home", action = "Serial", letterCase = "upper" }
);
However calling url http://localhost:5532/home/serial/lower in debug session, letterCase is passed with null value.
Because you call localhost:5532/home/serial/lower, try to call localhost:5532/serial/lower
or, if you need localhost:5532/home/serial/lower, rewrite your route rule to
routes.MapRoute(
name: "Serial",
url: "home/serial/{letterCase}",
defaults: new { controller = "Home", action = "Serial", letterCase = "upper" }
);
I've declared Index action in Home controller:
[HttpGet]
public ActionResult Index(string type)
{
if (string.IsNullOrEmpty(type))
{
return RedirectToAction("Index", new { type = "promotion" });
}
return View();
}
That accepts:
https://localhost:44300/home/index?type=promotion
and
https://localhost:44300/?type=promotion
Everything was ok until I config route for 404 page:
routes.MapRoute(
name: "homepage",
url: "home/index",
defaults: new { controller = "Home", action = "Index" }
);
routes.MapRoute(
name: "default",
url: "/",
defaults: new { controller = "Home", action = "Index" }
);
routes.MapRoute(
"404-PageNotFound",
"{*url}",
new { controller = "Error", action = "PageNotFound" }
);
Invalid syntax:
The route URL cannot start with a '/' or '~' character and it cannot
contain a '?' character.
If I remove the second configuration,
https://localhost:44300/?type=promotion
wouldn't be accepted. -> Show 404 page.
My question is: Is there a way to config route URL start with '/' (none controller, none action)?
Your route is misconfigured, as the error states it cannot begin with a /, and for the home page it doesn't need to. In that case it should be an empty string.
routes.MapRoute(
name: "default",
url: "",
defaults: new { controller = "Home", action = "Index" }
);
However, it is a bit unusual (and not SEO friendly) to want to map more than one route to the home page of the site as you are doing.
It is also unusual to do a redirect to a home page, which does an additional round trip across the network. Usually routing directly to the page you want will suffice without this unnecessary round trip.
routes.MapRoute(
name: "homepage",
url: "home/index",
defaults: new { controller = "Home", action = "Index", type = "promotion" }
);
routes.MapRoute(
name: "default",
url: "/",
defaults: new { controller = "Home", action = "Index", type = "promotion" }
);
// and your action...
[HttpGet]
public ActionResult Index(string type)
{
return View();
}
I am having trouble implementing the routing in MVC 5. While debugging the expected url(e.g. http://localhost/Download/Blog/1cf15fe6033a489a998556fedeab20a2/Test/1cd15fe6033a489a998556fedeab20a2) causes the correct method on the Download controller to be called however the did and fid are always null. What am I doing wrong? I also tried removing the Download route and defining the routes in the controller with the following attributes:
[RoutePrefix("Download")] //on the controller
[Route("{action}/{did:guid}/Test/{fid:guid}")] //on the Blog Action
Here is what I have in my RouteConfig.cs:
routes.MapRoute(
name: "Download",
url: "Download",
defaults: new { controller = "Download", action = "Index" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new {
controller = "Home",
action = "Index",
id = UrlParameter.Optional
}
);
here is my controller:
[Route("{action}/{did}/Test/{fid}")]
public class DownloadController : Controller
{
public ActionResult Index()
{
return Redirect(HandleBadResponse(webResponse));
}
[Route("{action}/{did}/Test/{fid}")]//nope
public ActionResult Blog(HttpRequestMessage request,string did,string fid)
{
string server = Request.ServerVariables["SERVER_NAME"];
string pathStr = #"\\mypath\1cf15fe6033a489a998556fedeab20a2.xls";
byte[] fileBytes = System.IO.File.ReadAllBytes(pathStr);
string fileName = "test.txt";
return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, fileName);
}
I got the expected result by adding the following to my RouteConfig.cs I placed this route at the top of my RegisterRoutes method, I think you should go from most detailed route to the least detailed route:
routes.MapRoute(
name: "DownloadBlogAttachment",
url: "Download/Blog/{did}/fid/{fid}",
defaults: new { controller = "Download", action = "Blog"}
);
I removed the Route attributes in my controller as well.
Problem Statement:
I'm trying to route to a Login view under Area(Test Area) not working.
Exception:
HTTP Error 403.14 - Forbidden The Web server is configured to not list the contents of this directory
Most likely causes:
A default document is not configured for the requested URL, and directory browsing is not enabled on the server.
If I route to view other than the login view under area it works fine
What I'm doing wrong in routing??
Area:
Test Area Registartion.cs
public class TestAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Test";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Test_default",
"Test/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
Roue Config in App_Start :
If I use default route for login it works fine ,but if I give route to login view under test area it gives HTTP Error 403.14 - Forbidden The Web server is configured to not list the contents of this director why??
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
// Default Route for Login
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Login", action = "Index", id = UrlParameter.Optional }
);
//Area View Route for Login
routes.MapRoute(
name: "Test",
url: "Test/{controller}/{action}/{id}",
defaults: new { controller = "Login", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "WebApplication1.Areas.Test.Controllers" }
);
}
}
Global.asax.cs :
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
Database.SetInitializer<WebApplication1.Areas.Test.Models.Test_DB>(null);
}
Try with this:
routes.MapRoute(
name: "Test",
url: "{controller}/{action}/{id}",
defaults: new {controller = "Login", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "WebApplication1.Areas.Test.Controllers" }).DataTokens["area"] = "Test";