Please I need help with this ASP.NET MVC 5 error in my code
The string parameter for viewing user details seems not to be available to the method even when it is there in the url and so the method returns a
HTTP Error 400.0 - Bad Request
Here is my RouteConfig.cs
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Residents",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Residents", action = "Details", id ="UserId"}
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
And this is the method:
// GET: Residents/Details/5
//[ActionName("Resident-details")]
public ActionResult Details(string username)
{
if (string.IsNullOrWhiteSpace(username))
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
ApplicationUser user = db.Users.Where(u => u.UserName.Equals(username, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
if (user == null)
{
return HttpNotFound();
}
ViewBag.user = user;
return View();
}
This is the resulting url
http://localhost:59686/Residents/Details/8b422e1d-12cf-42c2-8606-32123b3dc577
but it returns a bad request.
Even when I do
return Content(username)
early in the method, it returns nothing. Nothing is displayed indicating that the parameter is not visible to the method.
Please I will appreciate a solution to this problem
Thanks
Your route configuration is incorrect. Your method does not have parameter named id, but you are still defining it in your route configuration.
In order to fix the issue change your Residents route like this:
routes.MapRoute(
name: "Residents",
// only apply route to Residents/Details/your-user-name
// make sure to use parameter name {username}, like in your method
url: "Residents/Details/{username}",
defaults: new { controller = "Residents", action = "Details"}
So default model binding of MVC expects an int parameter to map your url to action method parameters.
alternatively you can use following url:
http://host/Controller/Details?username=8b422e1d-12cf-42c2-8606-32123b3dc577
or another option is try submitting data using POST method which will contain the username value.
Related
I'm using ASP.NET MVC 5
I'm having issues with both routes and parameters.
I have this function in my ControllerBase
[HttpGet]
[Route("~/obtenerAngulos/{Conex_AT}/{Conex_BT}")]
public JsonResult obtenerAngulos(string Conex_AT, string Conex_BT)
{
return Json(
new
{
AT = Conex_AT,
BT = Conex_BT
}
, JsonRequestBehavior.AllowGet);
}
And I start having problems receiving the second parameter Conex_BT the Url.Action() returns this route http://localhost:53645/Base/obtenerAngulos?Conex_AT=Y&Conex_BT=y the problem, is Conex_BT is always null
Then I try to work with route and add the Data Anotation for it [Route("~/obtenerAngulos/{Conex_AT}/{Conex_BT}")] but with Url.Action() I keep getting the same route as before.
Even if I try to write it manually like http://localhost:53645/Base/obtenerAngulos/AA/BB I get
HTTP Error 404.0 - Not Found
I mention both problems because I'm pretty sure they are relationated.
Here is the route configuration
RouteConfig.cs
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 }
);
}
Make sure you have enabled attribute routing on the route collection.
//enable attribute routes
routes.MapMvcAttributeRoutes();
//convention-based routes
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
This now means that the following should match obtenerAngulos/y/x
public class ControllerBase: Controller {
//Matches obtenerAngulos/y/x
[HttpGet]
[Route("~/obtenerAngulos/{Conex_AT}/{Conex_BT}")]
public JsonResult obtenerAngulos(string Conex_AT, string Conex_BT) {
//...
}
}
The tilde (~) on the method attribute is used to override any route prefixes if needed.
Routes are matched in the route table in the same order they are added. In your example you had convention based routes registered before attribute routes. Once a route is matched it no longer looks for other matches.
Reference Attribute Routing in ASP.NET MVC 5
I wrote a very simple web app in Flask and am porting it to ASP.NET Framework. All the functionality is in JavaScript and HTMl, so the framework should just act as scaffolding. I've got almost everything ported over, except for what seems to be a routing issue. My site expects a string token variable to be appended to the URL, like so: www.mysite.com/token-string. For development, the URL is localhost:*****/string-token, with my Index.cshtml page being displayed as default.
When I pass the URL without the token it works fine and my index page loads. However I get a 404 when I try it with the token. I'm assuming it's identifying the token as a route and is trying to navigate to it? I'm not sure how to fix it. Here are the important parts of my code:
HomeController.cs:
public class HomeController : Controller
{
public ActionResult Index(string token)
{
return View();
}
}
RouteConfig.cs:
NB: I've not changed this, not sure what to do with it.
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 = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
It's quite important that the token is passed in the way it is, rather than as a ? query parameter or anything like that. Additionally, the C# index view doesn't really need to do anything with the token - it gets extracted by the JavaScript.
Any advice is most welcome. Thanks.
Each segment (i.e. {controller}) in the route is a variable, and in the default route makes them all optional. Therefore, your default route is matching the request www.mysite.com/token-string.
What you need to do is insert a route that has a constraint to only match URLs with your token. Assuming your token is a GUID, you could use a regex route constraint as follows:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "TokenRoute",
url: "{token}",
defaults: new { controller = "Home", action = "Index" },
constraints: new { token = #"^[0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12}$" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
If your token is not a GUID, you could either use a different regex or implement IRouteConstraint to ensure the route only matches your tokens. The logic you use could be as simple as a == statement (as shown) or more complex (such as a database lookup).
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "TokenRoute",
url: "{token}",
defaults: new { controller = "Home", action = "Index" },
constraints: new { token = new TokenConstraint() }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
public class TokenConstraint : IRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
if ((string)values[parameterName] == "MyToken")
{
return true;
}
return false;
}
}
Note that you should use the route value key {token} in the url: parameter to match the action method parameter name token.
public ActionResult Index(string token)
{
return View();
}
I guess you could try changing the default route to include token instead of id as shown below.
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{token}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
The default Route pattern which you have expects the parameter with name as 'id'
Either add (or modify the default route) like below route pattern
routes.MapRoute(
name: "AnotherRoute", //your desired route name
url: "{controller}/{action}/{token-string}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
I have the following route table:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "UserRoute",
url: "{username}",
defaults: new { controller = "User", action = "Index" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
so, when we have url like : http://mysite/abcde it calls UserController, action Index, if we have url like : http://mysite/dashboard/Index it calls DashboardController, action Index. Ok. But when I try to call the following:
return RedirectToAction("Index", "Dashboard");
It calls UserController, action Index with username parameter equals "Dashboard". Why and how to solve?
Your routing is correct (at least for the URLs you provided). But you are not calling the redirect correctly.
When you generate an outgoing route, it doesn't match a URL, it matches the route values that are passed. Your UserRoute contains 3 route values:
username
Controller
Action
So, in order to generate a URL (or redirect) based on this route, you need to pass all 3 parameters.
return RedirectToAction("Index", "Dashboard", new { username = "Fred" });
That said, MVC will automatically reuse route values if they are in the current request. So, if your route already has a username value (for example, you are already at the URL /Fred), it will be able to match the route without specifying the route value explicitly.
return RedirectToAction("Index", "Dashboard");
I am trying to pass 3 parameters, one int, and 2 datetime to a controller with no luck. I have created custom Routes, but no matter what I do it never connects.
In My View I have
#Html.ActionLink("Check Availability", "Check", new { id = item.RoomID, AD = ArrivalDate.Date.ToString("dd-MM-yyyy"), DD = DepartureDate.Date.ToString("dd-MM-yyyy") }, null)
In my Controller I have
[RoutePrefix("RoomInfoes")]
[Route("Check/{ID},{AD},{DD}")]
[HttpPost]
public ActionResult Check(int? id, string AD, string DD) {
I have tried numerous arrangements of routes and views, but never can connect.
The code above returns a 404 with
Requested URL: /RoomInfoes/Check/1,06-11-2014,06-11-2014
Thanks
Before you use attribute routing make sure you have it enabled:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes(); // add this line in your route config
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
then decorate your action like this:
[Route("RoomInfoes/Check/{ID},{AD},{DD}")]
public ActionResult Test(int? id, string AD, string DD)
The RoutePrefix has been removed because it can be used only on class declaration (the code will even doesn't compile). I removed the HttpPost attribute because I assumed that you want make a GET instead of POST.
then to generate a link pointing to this action you can simply write:
#Html.ActionLink("test", "Test", "Home", new { id = 5, AD="58", DD = "58" }, null)
the result will be:
test (the commas in your url will be url encoded)
Do also have the Check Action method for serving HttpGet requests? If not, you will get 404 error.
Have you also done the routes.MapRoute in the RouteConfig.cs? This is required to render the correct URL with #Html.ActionLink helper method.
Try adding below code in RouteConfig.cs, if not already exists.
routes.MapRoute(
name: "RoomInfoes",
url: "Check/{ID},{AD},{DD}",
defaults: new
{
controller = "RoomInfoes",
action = "Check",
ID = UrlParameter.Optional,
AD = UrlParameter.Optional,
DD = UrlParameter.Optional
}
);
You don't Need Route and the RoutePrefix attribute on the Action method.
I have a very simple normal route and I can't seem to get it to work. I'm kind of clueless what I'm missing.
My routing is:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
My Controller is called AccountController and it has this method:
public virtual ApplicationUser EditUser(String userId)
I post this URL and I get a userid that is null
/Account/EditUser/Patrick
What am I missing?
Your route has a parameter called "id", whereas your method has a parameter called "userId". These need to match.
So either create a route, like:
routes.MapRoute(
name: "EditUser",
url: "Account/EditUser/{userId}",
defaults: new { controller = "Account", action = "EditUser"});
Or change your method to be:
public virtual ApplicationUser EditUser(string id);
Note that if you choose the first option, you need to put that call before the existing default one, because any URL you enter will match against the first route which matches it.