.net core mvc routing and controllers - asp.net-core-mvc

So I am brand new to .net. I am learning .net core right now. I am trying to figure out routing. I can not seem to get the routing to look in any folder except Home and Shared. I have looked all over the internet and tried many things. There seems to be something I am missing. Here is what I got
app.UseMvc(routes =>
{
routes.MapRoute(
name: "test",
template: "Register/test",
defaults: new { controller = "Register", action = "test"}
);
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
I have a Register folder with a test.cshtml file in just to try t figure this routing out. And this is is in my HomeController.cs file
public IActionResult test()
{
return View();
}
on my _Layout page I have this link
<li><a asp-area="" asp-controller="Register" asp-action="test">Test</a></li>
It works fine when I put it in the home folder, but I want to keep things separate. I know there is something I am missing. I've poured through all kinds on articles online including Stack Overflow, and I just don't understand what I am missing. From what I read its suppose to be like the Parent folder/File/ then and id that may be attached to that like a user name I have tried other formats for the routing with no luck, this was just my most recent attempt. I just can't help but think I need some bit of code somewhere else.

From your question it looks like you have the following code in your HomeController.
public IActionResult test()
{
return View();
}
That actually belongs in your RegisterController because the route template you defined is an explicit capture with defaults to the "Register" controller and the "test" action.
The view called "test.cshtml" - which should be named as such because of the default convention - should reside in your \Views\Register folder, next door to \Views\Home.
There are a couple of reasons why this may have worked in some fashion. First, the view is discoverable for any controller if it's in shared. Without knowing more about the requests you tried, it's difficult to determine if routing kicked in on the first route or second, but if that method was truly on HomeController requests to /home/test would have worked.
It looks to me like you're exploring routing. That is great - I 100% encourage the experimentation - so long as you know that routing isn't necessarily the lowest hanging fruit to learn. It's also something that you shouldn't have to touch 93.7% of the time. For example, the route you have defined about wouldn't be required for the controller and action you're adding with RegisterController and test.
Cheers.

Related

Routing Conventions in Can.js

So I’m looking to make some routes within my super cool can.js application. Aiming for something like this…
#!claims ClaimsController - lists claims
#!claims/:id ClaimController - views a single claim
#!claims/new ClaimController - creates a new claim
#!claims/:id/pdf - do nothing, the ClaimController will handle it
#!admin AdminController - loads my Administrative panel with menu
#!admin/users - do nothing, the AdminController will handle it
#!admin/settings - do nothing, the AdminController will handle it
So how might we do this?
“claims route”: function() { load('ClaimsController'); },
“claims/:id route”: function() { load('ClaimController'); },
“admin”: function() { load(‘AdminController’); },
Cool beans, we’re off. So what if someone sends a link to someone like...
http://myapp#!claims/1/pdf
Nothing happens! Ok, well let’s add the route.
“claims/:id/pdf route”: function() { load('ClaimController'); },
Great. Now that link works. Here, the router’s job is only to load the controller. The controller will recognize that the pdf action is wanted, and show the correct view.
So pretend I’ve loaded up a claim claims/:id and I edit one or two things. Then I click the Print Preview button to view the PDF and change my route to claims/:id/pdf.
What should happen… the Claim Controller is watching the route and shows the pdf view.
What actually happens… the router sees the change, matches the claims/:id/pdf route we added, and reloads the Claim Controller, displaying a fresh version of the claim pulled from the server/cache, losing my changes.
To try and define the problem, I need the router to identify when the route changes, what controller the route belongs to, and if the controller is already loaded, ignore it. But this is hard!
claims //
claims/:id // different controllers!
claims/:id //
claims/:id/pdf // same controller!
We could just bind on the "controller" change. So defining routes like can.route(':controller') and binding on :controller.
{can.route} controller
// or
can.route.bind('controller', function() {...})
But clicking on a claim (changing from ClaimsController to ClaimController) won't trigger, as the first token claim is the same in both cases.
Is there a convention I can lean on? Should I be specifying every single route in the app and checking if the controller is loaded? Are my preferred route urls just not working?
The following is how I setup routing in complex CanJS applications. You can see an example of this here.
First, do not use can.Control routes. It's an anti-pattern and will be removed in 3.0 for something like the ideas in this issue.
Instead you setup a routing app module that imports and sets up modules by convention similar to this which is used here.
I will explain how to setup a routing app module in a moment. But first, it's important to understand how can.route is different from how you are probably used to thinking of routing. Its difference makes it difficult to understand at first, but once you get it; you'll hopefully see how powerful and perfect it is for client-side routing.
Instead of thinking of urls, think of can.route's data. What is in can.route.attr(). For example, your URLs seem to have data like:
page - the primary area someone is dealing with
subpage - an optional secondary area within the page
id - the id of a type
For example, admin/users might want can.route.attr() to return:
{page: "admin", subpage: "users"}
And, claims/5 might translate into:
{page: "claims", id: "5"}
When I start building an application, I only use urls that look like #!page=admin&subpage=users and ignore the pretty routing until later. I build an application around state first and foremost.
Once I have the mental picture of the can.route.attr() data that encapsulates my application's state, I build a routing app module that listens to changes in can.route and sets up the right controls or components. Yours might look like:
can.route.bind("change", throttle(function(){
if( can.route.attr("page") == "admin" ) {
load("AdminController")
} else if(can.route.attr("page") === "claims" && can.route.attr("id") {
load("ClaimController")
} else if ( ... ) {
...
} else {
// by convention, load a controller for whatever page is
load(can.capitalize(can.route.attr("page")+"Controller")
}
}) );
Finally, after setting all of that up, I make my pretty routes map to my expected can.route.attr() values:
can.route(":page"); // for #!claims, #!admin
can.route("claims/new", {page: "claims", subpage: "new"});
can.route("claims/:id", {page: "claims"});
can.route("admin/:subpage",{page: "admin"});
By doing it this way, you keep your routes independent of rest of the application. Everything simply listens to changes in can.route's attributes. All your routing rules are maintained in one place.

Laravel 4: Multiple Action in a Single Contnroller Not Working?

I am new to Laravel and am just stuck upon this thing. I have set a controller which contains multiple actions for application. It turns out that if I put a single action in a single controller class, it works quite well. But when I use multiple action. It gives that damn error "Whoops, looks like something went wrong."
So, exactly what am I doing wrong? below is my controller class:
<? php
class ProgController extends BaseController
{
public function showHome()
{
return View::make('home');
}
public function showLogin()
{
return ('you are not authorized to login yet');
}
public function showTravel()
{
return View::make('travel');
}
}
and here is the route.php file content:
Route::get('/', 'ProgController#showHome');
Route::get('/login', 'ProgController#showLogin');
Route::get('/travel', 'ProgController#showTravel');
the files are in their respective default folders. I am worried has it something to do with composer.json file or what? what am I doing wrong?
Turn on debugging in your app/config/app.php file. Make sure you have a home.blade.php or home.php file in app/views (same applies for travel.blade.php or travel.php).
Unless we can see a stack trace that's the best we can give you for now. Definitely turn on debugging for a dev environment.
Use server log, it'll tell you the exact error when you have 500 like this "Whoops, looks like something went wrong.". Most likely you have one component which is not configured right or missing class, missing model, or anything which Laravel can not capture in application level.

Routing document-relative static urls in MVC3

I'm integrating a JavaScript library into an ASP.NET MVC3 web app. The library assumes it will be installed next to the page that references it, and so it uses document-relative URLs to find its components.
For example, the default directory layout looks like
container-page.html
jslibrary/
library.js
images/
icon.png
extensions/
extension.js
extension-icon.png
However, I want to reference the library from the view in /Home/edit. I install the library in the default Scripts\jslibrary\ When I reference the library in the view in Views\Home\edit.cshtml, the library's document-relative links like
images/icon.png
end up as requests to
http://localhost/Home/images/icon.png
which results in a File Not Found (404) error. How do I construct a route to look for
{anyControllerName}/images/{anyRemainingPathInfo}
and serve up
http://localhost/Scripts/jslibrary/images/{anyRemainingPathInfo}
?
(full disclosure: I'm still on IIS 6 in Production, and not much chance of going to IIS7 any time soon, so if this is better done at the IIS level, please account for IIS6. Thanks!)
You could create a controller for handling you redirect logic - for example an "Images"controller. Register a global route in your Global.asax file, using the pattern (more on this type of pattern here:
routes.MapRoute(
"Images", // Route name
"{xyz}/{controller}/{path}", // URL with parameters
new {controller = "Images", action = "Index", path= UrlParameter.Optional} // Parameter defaults);
In your controller:
public ActionResult Index(string path)
{
//format path, parse request segments, or do other work needed to Id file to return...
return base.File(path, "image/jpeg"); //once you have the path pointing to the right place...
}
Not sure if this solution will work for you, wish I could come up with something more elegant. Best of Luck!
Short of rewriting the library and having it check for the appropriate directory the only solution I can think of is to include the views, library and supporting files in a directory structure that the library can access. This of course would break MVC's convention over configuration way of finding views, so you would have to write a custom override of the way Razor looks for views, which is not too complex to do, but you might be making life more difficult for yourself down the road depending on your application. Your call which is the lesser of the two evils :) (I'd go for fixing the library)
Make a help function
#functions{
public string AbsoluteUrl(string relativeContentPath)
{
Uri contextUri = HttpContext.Current.Request.Url;
var baseUri = string.Format("{0}://{1}{2}", contextUri.Scheme,
contextUri.Host, contextUri.Port == 80 ? string.Empty : ":" + contextUri.Port);
return string.Format("{0}{1}", baseUri, VirtualPathUtility.ToAbsolute(relativeContentPath));
}
}
Calling
#AbsoluteUrl("~/Images/myImage.jpg") <!-- gives the full path like: http://localhost:54334/Images/myImage.jpg -->
This example are from
https://dejanvasic.wordpress.com/2013/03/26/generating-full-content-url-in-mvc/

Weird behaviour of RedirectToAction

I'm developing portal in MVC 3. Have controller (MyController) with three methods Add (get and post verssion) and Index and part of add method looks like:
[HttpPost]
public virtual RedirectToRouteResult AddItem(Item item)
{
(...)
return RedirectToAction("Index");
}
Simple? Not fot me:)
Item is added properly and when redirecting comes url looks like:
MyController/Index
and not:
mySite/MyController/Index
and of course that is bad news. This situation happens only in one case in one place in the whole portal. What's wrong?
What you get as a return is a relative path, relative to your current path.
Problem solved-i had to change order of routemaps in global.asax -request was catched by wrong map.

'The resource cannot be found' - error for 1 specific controller asp.net mvc

I've been pulling my hair out on this one.
I have a controller: ChatController of which any route I try gives me a 'The resource cannot be found' error.
The route:
routes.MapRoute(
"chatPage",
"{lang}/chat/{action}",
new { lang = "th", controller = "Chat", action = "Index" }
);
The url: /th/chat
All my other routes (to other controllers) work fine.
I use routedebug.dll to see if my routes are set up correcty and the route is correct.
Even if I delete the whole ChatController, I still get the same error. That means it does find the route but doesn't even get to the controller (usually this will give an controller not found error or something similar)
I get this on development server and IIS.
Anyone?
* Update *
I got it working by changing the routevalue from {lang}/Chat to {lang}/chat and changed my controllername accordingly (ChatController => chatController), this works... for now. Still want to know what causes this.
make sure that previous routes don't match this case. comment all others routes and then try. in my computer it's works for me :)

Resources