MVC routing parameters not working at all - c#

I've looked for a solution to this but even the simplest examples aren't working properly. Passing a single parameter {id} works successfully but that's the only parameter that is working. Changing the single parameter to anything else fails. In the example below multiple parameters also fail. It seems as the only workable parameter is "id".
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Servers",
url: "{controller}/{action}/{id}/{a}",
defaults: new
{
controller = "Test"
}
);
}
public class TestController : Controller
{
[HttpGet]
public ActionResult Monster(string id, string a)
{
return Json(new { success = id }, JsonRequestBehavior.AllowGet);
}
}
The url localhost/Test/Monster/hi Successfully reads the parameter as "hi". Specifying localhost/Test/Monster/hi/hello fails and gives a 404.

Try this:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Servers",
url: "{controller}/{action}/{id}/{a}",
defaults: new
{
controller = "Test",
id = UrlParameter.Optional,
a = UrlParameter.Optional
}
);
}
Also, is this your only route?
The order that the routes are set-up in is important, it's very easy to overwrite a route with a later route. I have done that mistake countless times.

In case action is not optional, you should specific the default value for it. Please try :
routes.MapRoute(
name: "Servers",
url: "{controller}/{action}/{id}/{a}",
defaults: new
{
controller = "Test",
action = "Monster"
}
);

In your method you have specified the parameter string a so when you pass the URl localhost/Test/Monster/hi/hello MVC will look for the parameter a in the url as it matches the form post parameters with the parameters in the function
So this link might help you as it helped me
http://www.codeproject.com/Articles/299531/Custom-routes-for-MVC-Application

This is a very late response but the issue with this was that there was an area being registered further downstream that was causing the routing issues. The area being registered had an optional url parameter that was taking the routes over. Utilizing this registered area fixed the issue.

sorry to say but as you saying
localhost/Test/Monster/Hi
working mean only one parameter routing is configured... did you try by restarting the IISExpress as routing get loaded on very first call and one time only..
after making the changes in routing you have to stop the IIS Express from the Icon Tray and re-run you project then with one parameter it should throw error.. as you have not set these option it will work only when u specify both the parameters.

Related

Force questionmark to show in querystring where only ID param is passed

I've implemented code to encrypt my query string parameter names and values. The code i have implemented will only encrypt query string that contain ?. (This is to prevent encryption of unneeded URL's, such as the .css files).
A way to combat this would be to always show the ? in query strings when only the ID parameter is passed.
For example I would like: http://domain/controller/Action/17
To show as: http://domain/controller/Action/?id=17
I understand that I probably need to edit my routes, I've tried adding the ? symbol to the route which throws the error : The route URL cannot start with a '/' or '~' character and it cannot contain a '?' character.
My routes are defined as:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("favicon.ico");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Login", id = UrlParameter.Optional } // Parameter defaults
);
How can I get my query strings to show like the example given above?
Don't define your parameters in routes.
ASP.NET automaticaly will add the question mark.
You can then call http://domain/controller/Action?id=17 and it will route to
public ActionResult Action(int id) { }
Update: If you want to kill domain/controller/action/id format completely, you need to define the route as:
routes.MapRoute(
name: "Parameterless", //or any name
url: "YourController",
defaults: new { controller = "YourController", action = "YourAction" }
);
Now you can use domain/controller/action?id={id} and domain/controller/action/id will 404.
If you are getting a Server Application Error, you need to provide more details, since it might be related to something else.

urls like "home.asp" redirect in mvc

I need to rebuild a website (in old they use classic ASP but they want to make it now MVC 4) and they dont want to change the urls. for example if the search screen's url is blabla.com/search.asp they want to keep it like this. But mvc doesn't allow to make urls like "search.asp". I want to keep url like this but render search View. Am I need to do this all one by one or there is a dynamic way for it?
for example
requested url = "blabla.com/string variable"
if variable.Substring(variable.Length - 4) == ".asp";
return View("variable.Substring(0, (variable.Length - 4))")
Note: Syntax is all wrong, I know. I just tried to explain the condition..
Note2: They want this because of "SEO" things. they don't want to lose their ratings. any method that doesn't change anything for google, they will accept that method I guess.
You need two things.
Define a route for *.asp
Add an handler for *.asp
RouteConfig
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "DefaultAsp",
url: "{controller}/{action}.asp/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Handler (WebConfig)
(This one needs to be inserted inside /system.webServer/handlers
<add name="AspFileHandler" path="*.asp" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
Doing this you are also making all URL's built with MVC available with .asp, that means that if you have an anchor that calls another View, that view will have the normal mvc URL with .asp suffix.
Note
This is generic, you only need to add this line once.
Home/Index displayed are just the default Controller and Action.
Note 2
Forgot to explain the handler.
You need it because IIS thinks you are asking for an ASP file an it'll try to reach that page and return an error since it doesn't exist.
With this handler you are allowing your application to handle those pages itself.
MVC does allows you to write a Route containing an extension, and pointing it to a specific Controller:
In RouteConfig.cs:
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute("Test", "test.asp", new {controller = "Test", action = "test" });
}
Then, in your TestController.cs:
public class TestController : Controller
{
public ActionResult Test()
{
var obj = new Foo();
//Do some processing
return View(obj);
}
}
In this way, you can access http://www.foo.com/test.asp without issues, and maintaining the .asp your client requires.

How to remove weird string after URL in ASP.Net MVC3

I'm working with ASP.NET MVC3, I created my routes and compose my urls but I have something weird in my url after navigated in browser.
Url actually rendered: /controller/action/page.html
Url navigated: /controller/action/page.html#.V7cdQJh97cw
I think that maybe is SessionID but I can't know how to remove it.
Appreciate any helps!
Go to the RegisterRoute method of RouteConfig.cs file in the App_Start folder of your project where Default Routing rule is written there.
Route Rule:- ControllerName/ActionName/id
where id is optional. So you want to remove Id parameter ,then make Id=" ".
for example:-
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 = "" } // Parameter defaults
);
}

How to ignore a specific route in ASP.NET MVC routing

What Is the proper syntax to put in the RouteConfig.RegisterRoutes method in an ASP.NET MVC application if I want the app to ignore all urls that start with the word "score" like
http://myserver/score*.*
?
In other words, any url that starts with the text "score" I want my app to ignore.
I tried:
routes.IgnoreRoute("score*.*/{*pathInfo}");
I also tried several other combinations of this syntax but can't quite get it right.
Here is what I have so far in my RouteConfig. It's pretty much the standard stuff.
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Order", action = "Add", id = UrlParameter.Optional }
);
}
}
You should place your score*.* as a regEx expression in IgnoreRoute:
routes.IgnoreRoute("{score}/{*pathInfo}", new { score = #"score*.*" });
For more general answers, you can use this pattern to ignore routes that you want:
Routes.IgnoreRoute("{*foo*}", new { foo = #"someregextoignorewhatyouwant"});
So for score.js and score.txt route you will add regEx that filters that routes.

No action was found on the controller that matches the request

Please excuse my ignorance in this area. I have read many threads and still cannot get my routing correct.
I have a ProductsController like this:
public class ProductsController : ApiController
{
[ActionName("GetListOfStudents")]
public static List<Structures.StudentInfo> GetListOfStudents(string Username, string Password)
{
List<Structures.StudentInfo> si = StudentFunctions.GetListOfStudents(Username, Password);
return si;
}
}
I have a console test program where I have defined the route:
config.Routes.MapHttpRoute(
name: "ApiByAction",
routeTemplate: "api/products/GetListOfStudents",
defaults: new { controller = "products", action = "GetListOfStudents" });
But when I run call
GET http://localhost:8080/api/Products/GetListOfStudents
I get the error message:
MessageDetail=No action was found on the controller 'Products' that matches the name 'GetListOfStudents'.
I have been pulling my hair out and cannot work out what the correct route should be.
Would any kind person care to help me out?
Ok- thanks for the help peeps!
This what I did to get it working:
Removed the "static" from the GetListOfStudents function.
Added the route below.
config.Routes.MapHttpRoute(
name: "ApiByAction",
routeTemplate: "api/products/GetListOfStudents/{username}/{password}",
defaults: new { controller = "products", action = "GetListOfStudents" }
);
Thanks everyone for your help!
When registering your global api access point, you should tell the config which route to use in the following manner:
config.Routes.MapHttpRoute(
name: "ApiByAction",
routeTemplate: "api/{controller}/{action}
defaults: new { controller = "products", action = "GetListOfStudents" });
In this sample you explicitly tell the controller it should only go to the "products" controller, you can make it generic without specifying the control or the action, just omit the defaults, like this:
config.Routes.MapHttpRoute(
name: "ApiByAction",
routeTemplate: "api/{controller}/{action}
That should do the job :)
Your GetListOfStudents action requires two parameters, username and password. Yet, the route definition contains neither specification in the route template where the values for those parameters should come from, nor specification for those parameter defaults in the defaults: parameter definition.
So when request comes in, routing is able to find your controller, but it is unable to find the action that it can call with the request and route context that it has because it has no information for the username and password parameters.
The most important is:
ASP.Net's mvc not only seek action by name, also it will check method's signature, only the method is non-static, name matches and parameters matches, the action will be executed.
for your case, there are two ways to correct it.
one way is declare default value, mvc will use default value when parametr not found.
public List<Structures.StudentInfo> GetListOfStudents(string Username = null, string Password = null)
{
List<Structures.StudentInfo> si = StudentFunctions.GetListOfStudents(Username, Password);
return si;
}
the second way is use override
public List<Structures.StudentInfo> GetListOfStudents()
{
return GetListOfStudents(null, null);
}
public List<Structures.StudentInfo> GetListOfStudents(string Username, string Password)
{
List<Structures.StudentInfo> si = StudentFunctions.GetListOfStudents(Username, Password);
return si;
}
I had this problem and solved it by including the verb as part of the action (i.e. GetThis, GetThat) and manually creating routes. I was attempting to create routes using attributes, but that did not work. This SO question may be the answer as to why the attributes aren't working, I haven't gotten that straightened out yet. As an additional note for anyone else having the same problem, when debugging it locally, IE was crashing when the "no action found" xml was returned. Once I gave up and switched to Chrome, the message detail was returned, and it was obvious that my controller at least was being found, it was just a matter of getting the action to work...
If you want to call GetListOfStudents method without parameter you must set default value for parameter. such as
GetListOfStudents(string Username=null, string Password=null)
Otherwise you must call method with Parameters.
GET http://localhost:8080/api/Products/GetListOfStudents/Username/Password
One issue could be the order of the route declarations in your WebApiConfig.cs file. Have a look here about the precedence of routes. If you have two routes with the same amount of parameters, you may need to reorder the routes, or -- depending on how specific the route is -- hardcode the controller or action name
When sending, encode the password with base64.
Then when you about to use it decode it.
byte[] numArray = Convert.FromBase64String(password);
string Pass = Encoding.UTF8.GetString(numArray);
List<Structures.StudentInfo> si = StudentFunctions.GetListOfStudents(Username, Pass);
Works fine for me.

Categories