How do I get ASP.NET to route a controller properly? - c#

I have this in my controller:
public ActionResult Details(int? id)
{
if(id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Sales saleRecord = new Sales();
var result = saleRecord.GetSalesOrderHeader((int)id);
return View(result);
}
However if I browse to /ControllerName/Details/5 I get this error:
"Server Error in '/' Application. - The view 'details' or its master was not found or no view engine supports the searched locations."
The strange thing is that if I use ASP.NET Scaffolding to generate a view, the Details part of that works fine. It's basically the same code I have above as well.
Here's my RouteConfig.cs, if that's relevant:
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 }
);
}
}
So why is that the scaffolding controller works fine, without having anything specific added to RouteConfig, yet my controller Details method is not working?

There should be more detail in error that what locations have been searched. Did you put break point in controller and checked if its being hit?
try
return View((object)result);
instead of
return View(result)
cause its calling overload View(string viewName)
If this doesn't work, try to specify viewName explicitly like this:
return View("ViewName", name);
Additionally, check your folder structure. MVC looks for views (like Index) under the views folder but they also have to be under a folder named after their controller (except partial views).

Related

ASP MVC 5 Route Mapping

Insides my views folder I have a 'User' folder, this does not contain a corresponding view, but contains sub folders which will contain a view.
Example:
User
Create
create.cshtml
Edit
edit.cshtml
I then have one controller, currently only with one action for create:
public ActionResult Create() {
return View("Create/Create");
}
So to hit that action I go to user/create, and that returns the view fine.
The problem comes from when I am trying to link to that view in an <a> tag using Url.RouteUrl. It errors and says:
A route named 'user/create' could not be found in the route collection
But to me, it matches the default route in the route config: controller/action.
Here is my RouteConfig:
public static void RegisterRoutes(RouteCollection routes) {
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// Turn on attribute routing in the controllers
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new {
controller = "Home", action = "Index", id = UrlParameter.Optional
}
);
}
So why do I need to define a custom route for it?
You don't need to define a custom route for it, but you need to follow the convention for your folders. Put the create.cshtml and edit.cshtml views directly inside the User folder, and delete the Create and Edit subfolders, you don't need them.
Now, in the controller, you can simply use:
public ActionResult Create() {
return View();
}
It knows what to look for and where to find it, so it will pick your User/create.cshtml view successfully. However, we usually pass a model to our views. In such a view like the Create, the model is used to build all the controls (textboxes, labels, etc):
public ActionResult Create() {
var model = new UserViewMode();
return View(model);
}

returnUrl redirecting to wrong page

For some reason my application keeps trying to find the Home Controller when redirecting back to the returnUrl (through the AccountController Login Action) even though I've changed my HomeController to be called DashboardController as well as having changed my RouteConfig.cs
namespace application
{
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 = "Dashboard", action = "Index", id = UrlParameter.Optional }
);
}
}
}
When my application starts it automatically is redirected to the Account/Login view due to an [Authorize] attribute in the controllers. But when I hand type in Account/Login into my Url the returnUrl becomes equal to "/" in the GET action, and upon signing in I receive a 404 error for missing page since it can't find HomeController Index View (which is actually DashboardController Index View).
What else do I need to change so that my application no longer searches for a Home Controller?
The solution to my problem was that the Account Controller RedirectToLocal action was redirecting to the Home Controller Index Action so I had to change it to Dashboard Controller Index Action.
private ActionResult RedirectToLocal(string returnUrl)
{
if (Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
return RedirectToAction("Index", "Dashboard");
}
That controller action will typically look for the file Index.cshtml in the "~/Views/Dashboard" folder. If you did not rename the "~/Views/Home" folder to "~/Views/Dashboard", the controller will be looking in the wrong place for the file and will not be able to find it, therefore producing the 404 error.

Asp.net MVC Routing w/ string parameter

I'm learning asp.net, and can't solve a rather simple problem for a while.
Have the RouteConfig.cs file with the following content:
public class RouteConfig {
public static void RegisterRoutes(RouteCollection routes) {
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
And got the controller with the content:
...
[Route("image/show/{uuid}")]
public ActionResult Show(string uuid) {
return View(uuid);
}
...
And the result when I try to open this url
Thanks in advance for the response!
Its your following line creating issue
return View(uuid);
This line taking the ViewResult View(string viewName) overload of controller. It is considering the uuid variable you passed-in as a viewname and tries to find the view file by that name.
As a workaround you can change that line to
return View((object)uuid);
This will take correct overload ViewResult View(object model)
or store the uuid in viewbag and return the view as
return View();
off course, you still need Show.cshtml file in your View/Image directory.
The error says that it cannot find the cshtml file in Views/Images/sdfsd.cshtml.
Add that file and it should work

Trying to access Index of MVC controller, Exception

So.. i have a MVC webpage. I have defined a Controller
public class NinjaController : Controller
{
// GET: Ninja
public ActionResult Index()
{
return View();
}
}
The my routes are set up like this:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
routes.MapRoute("Default", "{controller}/{action}/{id}", new
{
controller = "Login",
action = "Login",
id = UrlParameter.Optional
});
}
}
And i have a Folder in the Views folder that is named Ninja and an Index.cshtml file in there that looks like this:
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
Very simple... This is a business application with lots of different settings and configurations... If i do the exact same thing in a new solution it works just fine...
However when i try to access (http://localhost:1235/Ninja) view i get the following error:
{"A public action method 'Login' was not found on controller 'Stimline.Xplorer.Web.Controllers.NinjaController'."}
To me it seems like there should be something confusing the routing function.. but i have no idea where this logic could be placed... anyone have any suggestions?
Interesting fact: If i change the name of the method from Index() to OhYea() and create a corresponding view everything works as expected....
Your routing configuration is saying that pretty much all routes should go to Login which is why your Ninja route doesn't work.
The recommended way of enforcing authentication against a particular route is to use the AuthorizeAttribute. To summarise, keep your default route
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Ninja", action = "Index", id = UrlParameter.Optional }
);
But restrict your NinjaController to authorized users only
[Authorize]
public class NinjaController : Controller
{
...
}

rout registration breaks when I change the url in global.asax

The following rout registration works for my asp.net MVC application
routes.MapRoute("TrackingChannels", "TrackingChannels/{action}",
new { controller = "TrackingChannels", action = "Index" });
When I change it to catch this url,
I get resource not found error
for localhost:85\dis\TrackingChannels
routes.MapRoute("TrackingChannels", "Dis/TrackingChannels/{action}",
new { controller = "TrackingChannels", action = "Index" });
How can I fix this?
Alright, I need to go out so I'll post this now as I don't know how long I'll be.
I setup a default MVC 3 project and changed the routing to match your case.
Global.asax:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"TrackingChannels",
"Dis/TrackingChannels/{action}",
new { controller = "TrackingChannels", action = "Index" }
);
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Added a TrackingChannelsController:
public class TrackingChannelsController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Test()
{
return View();
}
}
I deliberately added the Test action to see if /dis/trackingchannels/{action} would also work. Then I added a couple of views which resulted in the following project structure:
Finally, here's the results of specifying the URLs in the browser:
First with /dis/trackingchannels:
Second with /dis/trackingchannels/test:
The only thing I can say without seeing your project is to double check the URL is matching the correct route. To do that you can use Phil Haack's RouteDebugger.

Categories