MVC3 Overloading the Index action getting 500 errors - c#

I having some problems overloading the Index action in a controller. In the controller I have the following actions:
public ActionResult Index(int id)
{
return View();
}
public ActionResult Index()
{
return View();
}
Going to either URL (controllername/ or controllername/1) results in a 500 error. However when I use:
public ActionResult Index(int? id)
{
return View();
}
The controllername/ URL works but controllername/1 results in a 404 error. My global.asax is pretty vanilla:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
What I would like to do is be able to handle a null id as well as an integer id value. Any suggestions would be greatly appreciated.
Thanks!

I think you will need to explicit the routes for that:
routes.MapRoute(
"ControllerName", // Route name
"ControllerName/{id}", // URL with parameters
new { controller = "ControllerName", action = "Index", id = UrlParameter.Optional }
);
if it doesn't work, you may need to be more explicit and add this before:
routes.MapRoute(
"ControllerName",
"ControllerName",
new { controller = "ControllerName", action = "Index"}
);

I think you don't need an overload here, but just need a check inside the index action for the null.
Overloading action is not a good idea, because framework would have no idea of which action to call incase of null index.
Adding custom routing for every action overload will cause slower response time because of too many custom routes to resolved.

Related

Why my link doesn't have the current route values?

Here is my route
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{testId}/{lg}",
defaults: new { controller = "Home", action = "Index", testId = UrlParameter.Optional, lg = UrlParameter.Optional }
);
Here is my controller code
public class TestController : Controller
{
//
// GET: /Test/
public ActionResult Index(int testId,string lg)
{
return View();
}
public ActionResult Index2(int testId, string lg)
{
return View();
}
}
Here is my view code (Index.cshtml)
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
#Url.Action("Index")<br/>
#Url.Action("Index2")
When I open "/Test/INdex/1/EN"
This gives me
/Test/Index/1/EN
/Test/Index2
The first link is ok because it uses the current route value (lg =EN and testId = 1)
But the second is not using the values, I don't get it !
I wouldn't have expected the first link to have route values, honestly. Maybe the view engine is smart enough to know that it's linking to the current route and automatically populates them?
In any event, linking to something entirely different isn't going to populate route values by default. The framework has no reason to believe that those route values are applicable to an entirely different action.
Specify them explicitly:
#Url.Action("Index2", new { testId = 1, lg = "EN" })
I found a workaround : the route parameters must be before the action ! :
routes.MapRoute(
name: "Default",
url: "{controller}/{testId}/{lg}/{action}",
defaults: new { controller = "Home", action = "Index", testId = UrlParameter.Optional, lg = UrlParameter.Optional }
);
If someone can say me why...

How to connect a Form with Controller in MVC3?

So, I am trying to submit a form on a List Page(http://example.com:3480/List) which is actually a Search implementation. So far I have done this:
index.cshtml
#using(Html.BeginForm("Search","ListController"))
{
<input id=query type=text name=query />
<input id=btnsearch type=submit value=Search />
}
ListController.cs
[HttpPost]
public ActionResult Search(FormCollection collection)
{
Response.Write("We are here");
// Get Post Params Here
string var1 = collection["query"];
Response.Write(var1);
return View();
}
Global.asax
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Details",
"Details/{id}/{orderid}",
new { controller = "Details", action = "Index", id = UrlParameter.Optional, orderid = UrlParameter.Optional }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional} // Parameter defaults
);
}
Upon Clicking it goes to http://example.com:3480/ListController/Search which seems fine.
Now I guess I need to define route in Global.aspx but not sure. What I want is to show result in same View file instead of creating a new one.
At this moment I am unable to get into Search method after POSTing form
Assuming you are currently just using the default route, the reason you are not reaching the action method is that the "Controller" suffix on your route is implicit - it shouldn't be part of your URL.
#using(Html.BeginForm("Search","List"))
Additionally, regarding:
What I want is to show result in same View file instead of creating a new one.
You can easily return a specific view from any controller action by specifying the name of the view in the call to the View method:
return View("Index");

Trying to hide to HomeController /Home from the URL

I was referencing this question to try and get this done, but it only works for my index method and I am not sure why.
My project has one area in it (if that is relevent) and I have about 5 different views that I want to hide /home/ in the url.
Code:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"JobResults", // Route name
"JobSearch/{title}-{id}", // URL with parameters
new { controller = "JobSearch", action = "Job" }, // Parameter defaults
new[] { "inkScroll.Web.Controllers" }
);
routes.MapRoute("home", "{action}",
new { controller = "Home", action = "index" });
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new
{
controller = "^(account|common|base|jobsearch)$", //every controller goes in here
action = "Index",
id = UrlParameter.Optional
},
new[] { "inkScroll.Web.Controllers" }
);
I am solving the same problem with the help of Attribute based Routing feature of ASP.NET MVC 5. Say, I have an action named ContactUs in my Home Controller as follows:
public ActionResult ContactUs()
{
return View();
}
I used to get Url for ContactUs as /Home/ContactUs. But, I wanted it to be simply /ContactUs. So, I am decorting the ContactUs action with Route Attribute as follows:
[Route("ContactUs")]
public ActionResult ContactUs()
{
}
So, this is working perfectly for me. Therefore, if you are using ASP.NET MVC 5, I would say, utilize this excellent feature of MVC5. It will not only save you from separating Route Logic and Actions, but also, it solves many problems very easily.
If ASP.NET MVC5 is not an option for you, or if you dont want to use Route Attribute on Action Methods, then, perhaps the following route can work: ( I did not test it though)
routes.MapRoute("Default", "",
new { controller = "Home", action = "index" });
This page contains helpful resource about Attribute Routing: http://blogs.msdn.com/b/webdev/archive/2013/10/17/attribute-routing-in-asp-net-mvc-5.aspx
Catch all wildcard route as the last one would work
routes.MapRoute("home2", "{*path}",
new { controller = "Home", action = "index" });

How to route request to www.MyDomain.com to specific controller class and method

In my MVC application, when user goes to www.MyDomain.com/Home, this request is processed in HomeController class Index method due to following routing entry in Global.asax
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
Let's say if user goes to www.MyDomain.com/SomeParameters, I want this request to be processed in MyController class Index method. An example for the parameters will be www.MyDomain.com/John. For this I have created following entry in Global.asax but it does not seem to get hit. Can anyone point out what I am doing wrong here?
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "MyController", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
The routing handles John as the controller, not the action. So in your example John is the controller and because you don't provide an action, it takes Index as the default action.
If you want www.MyDomain.com/John to be routed to controller MyController, action Index and a parameter that contains John, a solution could be to add the following route (before the default route):
routes.MapRoute(
name: "MyController",
url: "{myparameter}",
defaults: new { Controller = "MyController", Action = "Index" });
And the controller:
public ActionResult Index(string myparameter)
{
return View("whatever");
}
This will lead www.MyDomain.com/John to the Index action with myparameter = "John".
ps. In the example myparameter is mandatory.
In order to have www.MyDomain.com/SomeParameters you simply need to create a route where the Controller and the Action method are defaulted since they will not be provided in the URL.
Make sure the route definition only includes the someparameters and does not have anything else. This way you can just treat anything in the URL after / as a parameter.
routes.MapRoute(
name: "MyController",
url: "{someparameters}",
defaults: new { Controller = "MyController", Action = "Index" });
public ActionResult Index(string someparameters)
{
...
return View();
}

Razor file name with a dash

I need my page names to have a dash in the name. E.G our-vision
I'm new to MVC & c# so I may be going about all this wrong.
Here is my controller:
public class HomeController : Controller
{
//
// GET: /Home/
public ActionResult Index()
{
return View();
}
//
// GET: /our-vision/
public ActionResult ourVision()
{
return View();
}
}
And then in my views, I have Views/Home/ourVision.cshtml.
When I compile and go to http://localhost/ourVision it works, but when I go to http://localhost/our-vision it does not.
Here is my routing:
routes.MapRoute(
"Default", // Route name
"{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
You'll need to do a few things in order to achieve that.
First, to achieve our-Vision, you'll need to give your action method the ActionName attribute, like so:
[ActionName("our-Vision")]
public ActionResult ourVision()
Next, you'll have to rename your ourVision.cshtml view to be our-Vision.cshtml
Finally, whenever you're using Url.Action or ActionLink, you need to use our-Vision and not vision, like so:
Url.Action("our-Vision", "Home");
IMHO
The best way to do this - is define new route in route engine:
routes.MapRoute(
"OurVision", // Route name
"our-vision", // URL with parameters
new { controller = "Home", action = "ourVision" } // Parameter defaults
);

Categories