ASP.NET MVC throws error when id is null - asp.net-mvc

I have a publicly available controller (The action cannot be hidden under any security attribute) . The controller has an action which is available publicly as well.
Following is a sample structure of the controller :
public SomeController : Controller {
[HttpGet]
public ActionResult show(int id){
}
}
The action has a id field which is required. However throws an error which unnecessary adds to the logs when someone enters a malformed URL without the required id (or when search engine bots hit the a URL with the required id).
What should be the ideal solution to deal with this solution.
Possible solutions that come to my mind are :
Set the id as Nullable (int? id) and explicitly handle the case of not having a value by redirecting the caller to some other page showing appropriate errors
explicitly send a 404 error
Is there a generic way using Attributes to do this?
P.S : (to be specific) by explicit I mean writing if else conditions to handle such cases per controller.
I would appreciate any hints in the right direction.

You need a route constraint. This will help the router throw out URLs earlier (resulting in a 404) rather than later (the route is valid, goes to action, action barfs because a parameter is missing).
http://www.asp.net/mvc/tutorials/controllers-and-routing/creating-a-route-constraint-cs
Example default route (potentially replacing the existing one in your global.asax.cx):
// order is important; more specific routes to less specific routes is what you want
//
// default index action, with no ID
routes.MapRoute(
"Default_Index",
"{controller}/",
new {controller="Home", action="Index"}
);
// default create action, with no ID
routes.MapRoute(
"Default_Create",
"{controller}/Create",
new {controller="Home", action="Create"}
);
// default action requiring an ID (such as EDIT)
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new {controller="Home", action="Index"},
new {id = #"\d+" }
);

I would suggest to return 404 status with a custom error page because some one is requesting a resource that doesn't exists.
You can make it as a Nullable type, if it can return a result which represents that request otherwise return 404 status.
For e.g. action method Index(int? id) could return list of items, if id is null or return that specific item. Depending on your business scenario.

Related

MVC 4 routing to a controller

I am new to MVC and I am trying to mess around by creating a practice site which will be a gallery site for viewing and uploading images. The problem I encountered is that I cannot get the routing to work correctly.
Here is a link to my routing code and solution tree:
https://imgur.com/a/Oc1Tt?
Did I set the views and controller up incorrectly?
The error I get is: The view 'Index' or its master was not found or no view engine supports the searched locations. The following locations were searched:
Thanks for any input
Routing works by converting an incoming request to route values or by using route values to generate a URL. The route values are either set as parameters in the URL itself, as default values, or both (in which the defaults make the URL parameters optional).
You have not set any route values in your route. Since you don't have route parameters in the URL, you need to set defaults (controller and action are required by MVC).
routes.MapRoute(
name: "Gallery",
url: "Gallery/Index",
defaults: new { controller = "Gallery", action = "Index" }
);
That said, your Default route already covers this URL. You only need to add custom routes if you desire behavior that the Default route doesn't cover.
Also, if you change the view names so they don't match the name of the action method, you have to specify the name explicitly from the action method.
public ActionResult Index()
{
return View("~/Views/Gallery/GalleryView.cshtml");
}
By default MVC uses conventions. It is much simpler just to name the view Index.cshtml instead of GalleryView.cshtml so you can just return View from the action method.
public ActionResult Index()
{
return View();
}

routing with just one of two parameters of controller

I have an actionresult with two parameter:
public ActionResult Index(int a,string b)
{
//some code
return View(b);
}
it creates this url automatically:
mysite.com/a=1&b=http://site.com/b=1
I just need to show first parameter "a" in my url:
mysite.com/a=1
I use the default route of MVC that creates in global.ascx:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
what should i do?
Thanks...
If you are seeing the "b" parameter bleed through from the current request, you can set the "b" parameter explicitly to empty string to avoid this behavior:
#Html.ActionLink("Home", "Index", "Home", new { a = 1, b = "" }, null)
I reported this "feature" as a bug, but the developers at Microsoft seem to think this behavior is supposed to make your URLs easier to configure, and they don't intend to fix it.
What you're seeing here is a feature of routing where "ambient" values (i.e. values that were detected in the incoming request's URL) are used to simplify (sometimes...) the generation of routes to other pages.
You can check our my answer (under the name "Eilon") in this StackOverflow post, where I explain the behavior in a bit more detail:
How Can I Stop ASP.Net MVC Html.ActionLink From Using Existing Route Values?
Ultimately if you want the most control over what gets generated for a URL there are a few options to consider:
Use named routes to ensure that only the route you want will get used to generate the URL (this is often a good practice, though it won't help in this particular scenario)
Specify all route parameters explicitly - even the values that you want to be empty. That is one way to solve this particular problem.
Instead of using Routing to generate the URLs, you can use Razor's ~/ syntax or call Url.Content("~/someurl") to ensure that no extra (or unexpected) processing will happen to the URL you're trying to generate.
Thanks,
Eilon

Routing-MVC-ASP.NET

In most of the articles, they put this code and explain it but I feel I am not getting it. could any body expalain it in simple terms please.
This question is looks simple but I cannot get it correct in my head.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
My Questions:
Why do we use route.IgnoreRoute and why the parameters in {} ?
Maproute has First parameter-Default, What that resembles, Second Parameter-"{controller}/{action}/{id}", What this for and third parameter, we use new ?
How do I intrepret these routing?
Why all these?
I have used webforms so far and Cannot get it in?
Any Gurus in MVC could explain all these please?
Why do we use route.IgnoreRoute
This tells routing to ignore any requests that match the provided pattern. In this case to ignore any requests to axd resources.
and why the parameters in {} ?
The {} indicates that the delimited string is a variable. In the ignore route this is used so that any .axd requests are matched.
Maproute has First parameter-Default, What that resembles,
The first parameter is the route name. This can be used when referring to routes by name. It can be null which is what I tend to use.
Second Parameter-"{controller}/{action}/{id}", What this for
This is the pattern that is matched. In this case it is setting up the default route which is a url formed by the controller name, action name and an optional id. The url http://mysite.com/Foo/Bar would call the Bar method on the Foo controller. Changing the url to http://mysite.com/Foo/Bar/1 would pass a parameter with the identifier id and value 1.
and third parameter,
The third parameter supplies defaults. In the case of the default route the default controller name is Home and the default action is Index. The outcome of this is that a request to http://mysite.com would call the Index method on the Home controller. The id part of the route is specified as being optional.
we use new ?
The new keyword is creating an object using the object initializer syntax that was introduced in version 3 of the .Net framework. Microsoft article.
The major advantage of using routing is that it creates a convention for your urls. If you created a new controller called Account and action methods called Index and Review then the methods would be availble at /Account and Account/Review respectively.
First of all: ASP.NET MVC is not a simple version of webforms.
MVC has a special structure. You can find a MVC description here: http://en.wikipedia.org/wiki/Model-View-Controller
MapRoute adds the URL structure mapping. For example, following the default route link like www.domain.com/home/users/1 means that the server should call the users action in the controller called home. The action gets a parameter called id with the value of 1.
If you want to add the new Route you can simply add this uin next way:
routes.MapRoute(
"NewRoad", // Route name
"/photos/{username}/{action}/{id}", // URL with parameters
new { controller = "Photos", action = "Index", string username, id = UrlParameter.Optional } // Parameter defaults
);
following this road the url will be: domain.com/photos/someuser/view/123. We can map the optional parameters like id, and static parameters, like username. By default we call photos controller and index action (if the action not set in ult, server will call default action "index", we set it in the route).

problem with routing asp.net

I am fairly new to asp.net and I have a starting URL of http://localhost:61431/WebSuds/Suds/Welcome and routing code
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{page}", // URL with parameters
new { controller = "Suds", action = "Welcome", page = 1 } // Parameter defaults
);
routes.MapRoute(
"Single",
"{controller}/{action}",
new { controller = "Suds", action = "Welcome" }
);
I am receiving the following error: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Can anyone please help me figure out how to route the beginning url to the controller.
Because the first part of your URL is WebSuds, the framework is trying to map the request to WebSudsController instead of SudsController. One thing you can try is to change the url parameter of your route to "WebSuds/{controller}/{action}".
Route tables are searched on a first come first served basis. Once an appropriate match is found any following routes will be ignored.
You need to add "WebSuds/{controller}/{action}" and put it above the default route. The most specific routes should always go above the more generic ones.
With the following Routes and Url you have given make sure you have these Methods in your Controller
public class SudsController
{
public ActionResultWelcome(int? page)
{
return View();
}
}
Since you have created two routes of the same Action, one with a parameter page and another without. So I made the parameter int nullable. If you don't make your parameter in Welcome nullable it will return an error since Welcome is accepting an int and it will always look for a Url looks like this, /WebSuds/Suds/Welcome/1. You can also make your parameter as string to make your parameter nullable.
Then you should have this in your View Folder
Views
Suds
Welcome.aspx
If does doesn't exist, it will return a 404 error since you don't have a corresponding page in your Welcome ActionResult.
If all of this including what BritishDeveloper said. This should help you solve your problem.

404 asp.net mvc - beginner question in routing

This is a beginner level question for asp.net MVC
I have the following code in global.asax.cs
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = (string)null } // Parameter defaults
);
}
in Homecontroller.cs i have updated the Index method as follows
public ActionResult Index(string id)
{
ViewData["Message"] = "Welcome to ASP.NET MVC1!"+ id;
return View();
}
My understanding is, if I give the url http://localhost/mvc1/default/1 it should work
instead it is throwing up 404 error
any help what is the reason behind this
I'm assuming your application is called "mvc1" and that's the root of your project. If that's the case:
So "default" is the name if your route, not the name of the action. Basically what the routing engine does is look for a controller and action that matches requests coming in. Given the route you have setup, it would break down like this:
http://localhost/MVCApplication1/default/1
(cont) (action)
If certain parts of the route are omitted, it will attempt to fill in the missing values with the defaults you have specified. As you can see, there is no controller named DefaultController in your project, and thus it uses the default you've specified which is Home. It then tries to find an action method called default and fails again, so it uses the default value in your route, which is Index. Finally, you have 2 segments left in your URL, and no route matches that pattern (2 segments after the action), so it can't find the right place to go.
What you need to do is remove one of your segments, and this should work. Routing can be a little tricky, so I would recommend reading up on it.
The URL you're requesting is asking for a controller called "mvc1" and an action called "default" which will receive an id of "1". Since you don't have a controller named "mvc1" (I assume?), you're getting the 404 error.
The defaults for controller and action are only used if controller and action aren't provided. Since you provided controller and action, MVC is looking for them specifically.

Resources