MVC calling different method with same parameters - c#

I have a Controller that have 2 method with same parameters But if I call it I got an error
Several actions that matched the request were found:
I think that I must change Map routing to accomplish that but I dont know how to do it
My methods :
public IHttpActionResult RecuperarMenu(short idInstalacion,string secretKey)
public IHttpActionResult RecuperarClasesColectivas(short idInstalacion, string secretKey)
My route map
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new
{
controller = "Home",
action = "Index",
id = UrlParameter.Optional,
namespaces = new[] { "WebServicesRestAPI.Controllers" }
}
);
//routes.MapRoute(
// name: "Default",
// url: "{controller}/{action}/{id}",
// defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
//);
}

I guess the controller that contains your methods is a WebAPI controller (it is derived from the ApiController class). Correct?
Thus, being a WebAPI controller:
It is configured not by means of the MapRoute method, but by means of the HttpConfiguration.Routes.MapHttpRoute method (by default it is configured in the ~/App_Start/WebApiConfig.cs file):
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
The names within the controller should follow the GET/POST/PUT/DELETE pattern (or should be explicitly mapped by you).
If your methods correspond to the GET operation, they should differ by arguments (you have the same arguments if your methods).

Related

MVC Uri Parameter is null

When attempting to pass a parameter to a simple controller I receive the parameter as always being null.
Controller
public class GetOrgController : Controller
{
private DirectoryEntities de;
public getOrgController()
{
de = new DirectoryEntities();
}
// GET: getOrg
public ActionResult Index(string district)
{
getorg_Result org = de.getorg(district).FirstOrDefault();
return View(org);
}
}
When I try to navigate to that url with a parameter localhost:660366/GetOrg/Index/D123 the district variable is always null.
I thought maybe it had to do something with the default RouteConfig. When I put a new value ahead of the default route config it worked! However now, whenever I try to launch the application it goes to the GetOrgController first. What happens when I want a new controller with different parameters? I have to do this every time? Here is my new RouteConfig with the new entry.
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "GetOrg",
url: "{controller}/{action}/{district}",
defaults: new { controller = "GetOrg", action = "Index", district = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
I actually started doing Rest initially in Web Api 2, but the view-model attracted me to MVC. It is a lot easier specifiying above the method the routes/parameters I wanted like below. Is this possible in MVC?
WebApi2
[Route("Index/{district}")]
public ActionResult Index(string district)
{
getorg_Result orgs = de.getorg(district).FirstOrDefault();
return View(orgs);
}
The above method seems so much cleaner than having to rely on the order of controllers being correct in the RouteConfig
These two routes literally make no sense. The first one says, for ANY controller with ANY method default to GetOrgController. That isn't what you want because now id won't work for all the other controllers and the second MapRoute is close to a duplicate.
routes.MapRoute(
name: "GetOrg",
url: "{controller}/{action}/{district}",
defaults: new { controller = "GetOrg", action = "Index", district = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
What you really should be doing is saying for any call starting with GetOrg then call GetOrgController for any method....
routes.MapRoute(
name: "GetOrg",
url: "GetOrg/{action}/{district}",
defaults: new { controller = "GetOrg", action = "Index", district = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
thats because both routs are generic thats why it hits the first route by default so you can remove UrlParameter.Optional so that the route should be a little specific
routes.MapRoute(
name: "GetOrg",
url: "{controller}/{action}/{district}",
defaults: new { controller = "GetOrg", action = "Index"}
);
but still you can use the default route for that purpose no need of additional route unless you want to use a custom url like random/234

Routes in ASP.NET MVC

I am trying to route a link in MVC project.
I tried two methods:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
//method1
// routes.MapPageRoute("SchoolPage", "School", "~/home", false);
//method2
routes.MapRoute(name: "SchoolPage",url: "School", defaults: new { controller = "Home", action = "Index" });
}
For both methods I get the 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.
You need to specify the custom route first. Default route has no constraints so it will match to any URL. When you make a request ot http://example.org/School, ASP.NET MVC will look for a controller named SchoolController using the default route. You have to make sure it matches to SchoolPage route first by placing it before the default route.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(name: "SchoolPage",url: "School", defaults: new { controller = "Home", action = "Index" });
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}

Web API route being ignored

I have these two routes defined:
routes.MapRoute(
name: "GetVoucherTypesForPartner",
url: "api/Partner/{partnerId}/VoucherType",
defaults: new { controller = "Partner", action = "GetVoucherTypesForPartner"}
);
routes.MapRoute(
name: "Default",
url: "api/{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional}
);
In my PartnerProfile controller, I have 2 methods:
public Partner Get(string id)
{ }
public IEnumerable<string> GetVoucherTypesForPartner(string id)
{ }
If I hit the url ~/api/Partner/1234 then, as expected, the Get method is called.
However, if I hit the url ~/api/Partner/1234/VoucherType then the same Get method is called. I am expecting my GetVoucherTypesForPartner to be called instead.
I'm pretty sure something in my route setup is wrong...
You seem to have mapped standard MVC routes, not Web API routes. There's a big difference. The standard routes are used by controllers deriving from the Controller class, but if you are using the ASP.NET Web API and your controllers are deriving from the ApiController type then you should define HTTP routes.
You should do that in your ~/App_Start/WebApiConfig.cs and not inside your ~/App_Start/RouteConfig.cs.
So go ahead:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "GetVoucherTypesForPartner",
routeTemplate: "api/Partner/{partnerId}/VoucherType",
defaults: new { controller = "Partner", action = "GetVoucherTypesForPartner" }
);
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
and then:
public class PartnerController : ApiController
{
public Partner Get(string id)
{
...
}
public IEnumerable<string> GetVoucherTypesForPartner(string partnerId)
{
...
}
}
Things to notice:
We have defined HTTP routes not standard MVC routes
The parameter that the GetVoucherTypesForPartner action takes must be called partnerId instead of id in order to respect your route definition and avoid any confusions

MVC4 Route as /{controler}-{id} instead of /{controler}/{id}

During my work I must solve one URL rewriting problem. I have to use URLs as a template:
{controller}/{action}-{id}
instead of
{controller}/{action}/{id}
so the processed url should look like:
myController/myAction-128
where 128 is a parameter
My route map:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "NewRoute", // Route name
url: "{controller}/{action}-{id}/{extId}", // URL with parameters
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional, extId = UrlParameter.Optional } // Parameter defaults
);
}
Controller code:
[HttpGet]
public ActionResult DocumentDetails(int? id)
{
if (doc.HasValue)
{
...
}
}
This route doesn't provide any successful results. I still have 404 Errors. When I use / instead of "-" everything is ok, but my JS View environment won't work.
Is there something I could do to fix this? All help will be appreciated, thanks.
Routes are evaluated in the same order as you defined them, so make sure you respect the same order. Also adding a constraint for the id (as being a number for example) would help the routing engine disambiguate your routes. Not to mention that in your example you have made the id token optional which of course is not possible, only the last part of a route can be optional.
So:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "NewRoute",
url: "{controller}/{action}-{id}/{extId}",
defaults: new { controller = "Home", action = "Index", extId = UrlParameter.Optional },
new { id = #"\d+" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
I'm thinking your request is being processes by the first routing rule and then action-id is considered as a whole action and not being found.
Set your NewRoute before the Default route. Just move the code up.

URL Parameter Not Recognized in Controller

I'm learning MVC 4, and it's my understanding that going to this URL should pass an int of 44 to the Edit() method of the controller. Indeed, when I go here:
http://localhost:51921/TrackerJob/Edit/44
... this method gets invoked:
public ActionResult Edit(int trackerJobId = -1)
{
Debug.WriteLine(trackerJobId);
}
... but the parameter is always -1. I had this working in a different project, but for some reason it's always -1 in this project. I don't see a difference between the two projects that would cause one to work and this one to fail. If I change the method signature to this:
public ActionResult Edit(int trackerJobId)
{
Debug.WriteLine(trackerJobId);
}
I get an error:
The parameters dictionary contains a null entry for parameter 'trackerJobId' of non-nullable type 'System.Int32'
Any ideas? I'm not sure what to check...
Edit - Including routes, by request*
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
If you want to use the default routing then just make sure your parameter is called id.
Otherwise you could add a new route like this:
routes.MapRoute(
name: "TrackerJob",
url: "{controller}/{action}/{jobtrackerid}",
defaults: new { controller = "TrackerJob", action = "Index", id = UrlParameter.Optional }
);
Make sure you add this route BEFORE the default route. The order of routes is very important!
Only you know if the trackerJobId is optional or not.
Note that if you want something more fancy you can tweak the routes to produce what you want.
e.g. If you want URLs like http://localhost:51921/TJ-E-44 for editing then your route would look like this:
routes.MapRoute(
name: "TrackerJobEdit",
url: "TJ-E-{jobtrackerid}",
defaults: new { controller = "TrackerJob", action = "Edit", id = UrlParameter.Optional }
);
I'm sure you get the idea.

Categories