So I have an app that uses C# MVC and AngularJS 1.5. I am using angular-ui-router for frontend routing. I'm having problem with routing cause I think the code <div ui-view></div> doesn't work inside /Shared/_Layout.cshtml. Also when I navigate through other pages the _Layout.cshtml gets rendered twice.
Here's my route config:
routes.MapRoute(
name: "Default",
url: "{*url}",
defaults: new { controller = "Home", action = "Index" }
);
Then my _Layout.cshtml contains all the skeleton html needed like the styles and scripts import also including the <div ui-view></div>
Then here's my main route in Angular:
$stateProvider.state('main', {
url: '/',
views: {
'': {
templateUrl: '/Home/Home'
},
'sidenav': {
templateUrl: '/Partials/SideNav',
}
}
})
Related
I guess I don't completely understand how urls work with C# projects, in the sense that I don't know how to specify a url to go through the controller and not just return a aspx page.
Say I am trying to get to my project's Index page through a Controller named "ScholarshipController.cs". I would think to hit the Index method/action in this controller, my url would be as follows (my app's name is "TuitionAssistance" fyi):
http://localhost/TuitionAssistance/Scholarship/Index
However, running this url just returns the aspx page named "Index.aspx" located in the "Scholarship" view file without hitting the Controller. Why is this happening, and how do I get it to go through the controller so the Index page, when loaded, will have the appropriate information loaded onto it?
Sorry if this is a dumb question. Any insight would be appreciated. Thanks!
Route.config:
using System.Web.Mvc;
using System.Web.Routing;
namespace ScholarshipTuitionAssistance
{
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
/* Scholarship */
/* Scholarship */
//routes.MapRoute("TuitionAssistance",
// "tuition/{name}",
// new { controller = "TuitionAssistance", action = "Index", name = "" });
routes.MapRoute(
name: "TuitionAssistance",
url: "{controller}/{action}/{employee_number}",
defaults: new { controller = "Home", action = "TuitionAssistance", employee_number = UrlParameter.Optional }
);
routes.MapRoute(
name: "Scholarship",
url: "{controller}/{action}/{employee_number}",
defaults: new { controller = "Home", action = "Scholarship", employee_number = UrlParameter.Optional }
);
routes.MapRoute(
name: "Details",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Scholarship", action = "Details", id = UrlParameter.Optional }
);
}
}
}
Your route (URL) cannot match anything that actually exists on the filesystem. In your example here, you apparently have a file, [document root]\Scholarship\Index.aspx. As a result, a request for Scholarship/Index will return that file, instead of invoking the ASP.NET MVC machinery to load a controller action.
In MVC ASP.NET, think of those types of links as a way to call your methods in your controller. When that link is accessed, your controller does a bunch of junk and then returns an ActionResult (or other things). This ActionResult, for the sake of this explanation, is the markup that is written in the corresponding view file. Controller - >index() will return the view called index under views - > controller. If you want to pass information to your view, you will pass a model that has all of your information in it to the view from your index controller (return View(MyFancyModel)). The view will have a razor line at the top such as: #model The.Namespace.Wherever.my.model.is
The scaffolded controllers and views in Visual Studio for the index page specifically, only pass a list of the items in the corresponding database.
I'm currently using HashRouter and it works really well. However I would like to be able to use the # on sub routes as well for linking to paragraphs. For example /details#Summary. As a benefit I will also get cleaner URLs and if needed I can get some SEO.
Works and gives correct results on refresh/direct link.
<HashRouter>
<App />
</HashRouter>
Works but gives 404 on refresh/direct link.
<BrowserRouter>
<App />
</BrowserRouter>
I understand that the problem here is my routing in .Net and I need to change it. What do I need to do? I have a default route but it does not get hit.
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
First remove the standard routes.MapRoute that is shown above and then add this:
routes.MapRoute("Client", "{*anything}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });
Now any route will render your default action.
Optional:
If you have a controller with attribute routing, example:
[RoutePrefix("Home")]
public HomeController : Controller {
//GET Home/Index
[HttpGet]
[Route("Index")]
public ActionResult Index() {
return View();
}
}
You also need to add:
routes.MapMvcAttributeRoutes();
The thing is that when you change that, asp.net keeps trying to match a route from for details.
What you need to do is create a route that matches all paths, so that it returns the default one, eg: home/index
This is the route I use:
routes.MapRoute(
"Default",
"{*url}",
new { controller = "Home", action = "Index" });
That will give control to the browser to math the paths after '/'
I have built a standard MVC application with controllers and views and the following routes:-
routes.MapRoute
(
name: "PageNumber",
url: "{controller}/{action}/page-{pageNumber}",
defaults: new { controller = "Home", action = "PageNumber" }
);
routes.MapRoute
(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Account", action = "Login", id = UrlParameter.Optional }
);
Because this a back-end system, there will be a basic HTML website on the front of this. It means I need to route my site into a subfolder, so that the URL's look like this:-
SubFolder/Controller/Action/{id}
How can I do this, without changing all of my hard-coded links to include this sub-folder. I can't use MVC Areas for this, so was wondering if there was a way of changing the routing to automatically pre-pend the SubFolder bit of the URL?
Thanks!
You could make a new route:
routes.MapRoute(
name: "Subfolder",
url: "Subfolder/{controller}/{action}/{id}",
defaults: new { controller = "Account", action = "Login", id = UrlParameter.Optional }
);
However you should not be hard coding links, if you have future plans to replace the basic HTML page you could use #Html.ActionLink to generate the anchor tags for you.
I'm lost..
For days now, i have tried to get it to work.. I made a MVC site code first with EF. then i've scaffolded controllers and API (tried ALOT thins)
my routeConfig:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Events", action = "Index", id = UrlParameter.Optional }
);
my WbApiConfig:
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
What should my Controllers actions return? json? views?
my ng-app is in my /Home/Index (which uses layout, and layout has ng app on html)
and at last, my ngApp
app.config(['$routeProvider', function ($routeProvider, $locationProvider) {
$routeProvider
// route for the home page
.when('/', {
templateUrl: 'Home/Index',
controller: 'mainController'
})
.when('/Home/About', {
templateUrl: '/Home/About',
controller: 'programsCtrl'
});
}]);
So.. the furthest I've got is a 404 or angular crashing chrome by loading infinitly.
And with the code above, i get the angular load more than one crash.
I just want my angular to load my views inside the ng-view and leave the layout on always..
ANY help or pointer appreciated :)
I recommend you to use UI router, You create a one controller name 'HomeController' inherited from _layout. Your index view of Home contains this div
<div ui-view></div>
You app.js file looks like, don't forget to add ui-router js in layout
var app = angular.module('app', ['ngRoute', 'ui.router']);
app.config(['$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider) {
// For any unmatched url, redirect to /state1
$urlRouterProvider.otherwise("/Home");
// Now set up the states
$stateProvider
.state('Home', {
url: "/Home",
controller: "mainController",
templateUrl: "your html pages" // like '/script/home/templates/home.html'
}).state('About', {
url: "/Home/About",
controller: "programsCtrl",
templateUrl: "your html pages" // like '/script/home/templates/about.html'
});
}]);
The way I go about this is by setting the default for MVC to home/index and placing the <ng-view></ng-view> in the home/index view. This should be the only content in that view, remove everything else.
Now, on your _layout, make sure you have:
<html ng-app="app"> at the top of the file and ensure that you have the relevant scripts loaded ie:
#Scripts.Render("~/bundles/angularjs")
#Scripts.Render("~/bundles/app")
So that angular is available.
Keep this for #RenderBody()
<div class="body-content">
#RenderBody()
</div>
Your MVC methods return ActionResult (return View()) and your ApiController methods return JSON
I am having trouble configuring my routing. My routeconfig is as follow:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}",
defaults: new { controller = "Somepage", action = "Index", id = UrlParameter.Optional }
);
now I have two controllers Sompage and Somepage2 and two views folder Somepage and Somepage2.
In my layout.cshtml, I have links to Somepage and Somepage2. Links to Somepage are working fine, however links to Somepage2 do not render. The link in layout file is
#Html.ActionLink("some page on somepage2", "somepageonsomepage2", "Somepage2", new { target = "_blank" })
When I click this link it tries to take me to localhost/Somepage/somepageonsomepage2
when I want to go localhost/Somepage2/somepageonsomepage2
I am not sure where I am going wrong.
You need to use the correct overload of ActionLink that specifies your controller. By default an action link's controller will be view's controller. So if you have controller HomeController and view Index in folder Home, an action link's default controller will be HomeController
#Html.ActionLink("some page on somepage2", "somepageonsomepage2", "Somepage2", null, new { target = "_blank" })