Problems to load mvc Partial using Angular2 - asp.net-mvc

I'm trying to create a small app using MVC and Angular2.rc6 based in this excellent tutorial.
I get stuck to use a partial view as templateUrl.
api.flight
#Component({
selector: "mvc",
templateUrl: "/partial/flights" //C# mvc Partial flights.cshtml
})
When my app starts, I saw by the breaking point, the app loading Home/Index.cshtml and my Partial/flights.cshtml
When I click on the link to load Flights I get this Exception:
EXCEPTION: Uncaught (in promise): Error: Error in
/partial/flights:1:54 caused by: Maximum call stack size exceeded
but If I change my API.flight to use: template instance templateUrl. it works.
api.flight
#Component({
selector: "mvc",
template: "<h1>Works Well</h1>"
})
public class PartialController : Controller
{
public IActionResult Flights()
{
return PartialView();
}
public IActionResult Message() => PartialView();
}
I don't know if I'm missing something in my MVC routes, or if I make a mistake on angular2.

You can use .cshtml with angular2 component.
use template url like this-
templateUrl: "partial/flights"
partial is your controller name and flights will be your action name
And in MVC Controller, you can just simply return partial view like this-
public IActionResult flights() => PartialView();
NOTE: your action name is flights and partial view is flight.cshtml. Try to maintain same naming conventions.
See if this helps.

Its throwing error because your templateUrl is not correct, templateUrl should be valid Component Relative URL as below :
#Component({
selector: "mvc",
templateUrl: "/partial/flights.html"
})

Related

Is it possible to config multiple routes with ODATA

I've created a project containing both MVC and WebAPI.
There's a MVC controller named HomeController which containing only one action named Index.
Also, there's a API controller named ValuesController.
Everything works fine without OData, I can access to both http://localhost/Home/Index and http://localhost/api/Values successfully.
However, after I changed some code to support OData, I'm failed to access to http://localhost/Home/Index. Below is the related code:
//startup.cs
public void ConfigureServices(IServiceCollection services) {
services.AddDbContext<ProductsContext>(options =>
{
options.UseInMemoryDatabase("InMemoryDb");
});
//Adding OData middleware.
services.AddOData();
services.AddMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider provider){
if (env.IsDevelopment()){
app.UseDeveloperExceptionPage();
}
//Adding Model class to OData
var builder = new ODataConventionModelBuilder(provider);
builder.EntitySet<ValuesEntity>("Values");
builder.EntityType<ValuesEntity>().Filter(QueryOptionSetting.Allowed).OrderBy(QueryOptionSetting.Allowed);
//Enabling OData routing.
app.UseMvc(routebuilder =>
{
routebuilder.MapODataServiceRoute("odata", "api", builder.GetEdmModel());
routebuilder.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
As you can see, there're multiple routes, but the default route seems never get used.
I can still access to the http://localhost/api/Values, but If I access to the http://localhost/Home/Index, the page will show me the error:
An unhandled exception occurred while processing the request.
ArgumentNullException: Value cannot be null.
Parameter name: routeName
Microsoft.AspNet.OData.Extensions.HttpRequestExtensions.CreateRequestScope(HttpRequest request, string routeName)

ASP.NET MVC with angular routing url issue

I have problem with angular routing and ASP.NET MVC.
The problem is with URL.
MVC controller:
[RoutePrefix("BackOffice/Merchants")]
public class MerchantsController : Controller
{
[Route("Add")]
public ActionResult Add()
=> View("~/Views/BackOffice/Merchants/View.cshtml");
[Route("{id}/Edit")]
public ActionResult Edit(Guid id) // e08c5580-29e3-4429-9c76-b1464f0365ae
=> View("~/Views/BackOffice/Merchants/View.cshtml");
}
Angular app.js
var app = angular.module("backofficeMerchantsApp", ["ngRoute"]);
app.config(function($routeProvider) {
$routeProvider
.when("/",
{
template: "<h1>eee</h1>"
})
.when("/Add",
{
templateUrl: "add.html",
controller: "addController"
});
});
And there is problem:
When I enter:
.../BackOffice/Merchants/Add
The angular loads "/" page.
When I enter:
.../BackOffice/Merchants/Add#/Add
The angular loads "/Add" page.
I don't want it. What I have done wrong?
I want to:
When I enter:
.../BackOffice/Merchants
The angular loads "/" page.
When I enter:
.../BackOffice/Merchants/Add
The angular loads "/Add" page.
How to do it?
I was able to figure this out here: Angular Routing with ASP MVC
Hope this helps if you are still having a hard time.

In AngularJS routing, how templateUrl works without pointing to a .html file

I am trying to understand the AngularJS routing when it is used with ASP.net MVC. I am following this article to understand AngularJS routing. My query is specific to the usage of 'templateURL'. I understand that in pure AngularJS routing, templateUrl points to a specific '.html' page. But in the many example applications that I have seen in the internet for AngularJS and ASP.net MVC, I have seen that templateURL does not point to a specific .html, but a path of the view folder is given, not the .html file (or .cshtml file, which i know can be processed only by ASP.net MVC framework). For example from the article, following is the routing information given in the AngularJS javascript:
NbCapp.config(function ($routeProvider) {
$routeProvider
.when('/ondemand', {
controller: 'onDemandController',
templateUrl: 'ondemand/ondemand'
})
.when('/results', {
controller: 'resultsController',
templateUrl: 'results/results'
})
.otherwise({ redirectTo: '/results' });
});
As observed from the above, all the routing, points to a folder not a .html file. Could anyone please help me understand how this works.
I understand that in pure AngularJS routing, templateUrl points to a specific '.html' page.
Not necessarily. It doesn't matter what extension is or whether there is extension at all or not. The only thing that matters is Content-Type of the document fetched as template. So as long as it's text/html - it can be used as template. (Actually GET request for template will be issued and response processed as template (will be displayed on the page), so it doesn't even matter what server responds with Angular will just take responseText of the response data, but better if it is text/html).
In your example, templateUrl: 'results/results' might point to some dynamic framework resolved user-friendly path without any extensions, which responds with HTML content.
AngularJS does not necessarily have to point to an HTML page. What you have specified above is a combination of controller/action. When you call an action you get a processed CSHTML, VBHTML, or ASPX as an HTML response.
For example, specifying:
templateUrl: 'Account/LogOn'
will instantiate an AccountController and call LogOn action that will return PartialViewResult.
templateUrl does not require only .html template. Basically ui-route loads the content from given template url and accept that Content-Type : 'text/html'. Template loadin g is done by ajax.
So you are free to load any template with any extension but with valid path.
In Asp.net MVC we define custom routing in RouteConfig File. Suppose in RouteConfig we have declared custom route as follows:
routes.MapRoute("AngularTemplates", "almight/{name}", new { controller = "Home", action = "Template" });
and in app.js file, we have configured angular route as follow:-
var app = angular.module("BeautyParlorAppModule", ["ngRoute"]);
app.config(function ($routeProvider) {
debugger
$routeProvider
.when("/DetailView",
{
templateUrl: "almight/detailsView",
controller: "DetailviewController"
}
)
.when("/ListView",
{
templateUrl: "almight/_ListView",
controller: "ListViewController"
}
);
});
In HTML file we have action like:
<div class="row">
<div class="col-md-12">
<div class="nav">
<ul>
<li>Show ListView</li>
<li>Show DetailView</li>
</ul>
</div>
</div>
Upon clicking on link will locate home controller of MVC and call action Template with Name parameters _ListView or detailsView
public class HomeController : Controller
{
public ActionResult Index(string id)
{
return View();
}
public ActionResult Template(string name)
{
if (name == null || !Regex.IsMatch(name, #"^[-\w]+$"))
throw new ArgumentException("Illegal template name", name");
relativeViewPath=String.Format("~/Views/Home/{0}.cshtml",name);
return View(relativeViewPath);
}
public ActionResult About()
{
ViewBag.Message = "Your application description page.";
return View();
}
public ActionResult Contact()
{
ViewBag.Message = "Your contact page.";
return View();
}
}

AngularJs routing with Asp.Net Mvc

I'm trying to build a SPA with Asp.Net MVC. for this I'm using angularJs routing .
This is my project hierarchy.
My Layout.cshtl code
<html lang="en" ng-app="ProjectTrackingModule">
<head>
<script src="~/Scripts/jquery-2.1.0.min.js"></script>
<script src="~/Scripts/angular.min.js"></script>
<script src="~/Scripts/angular-route.min.js"></script>
<script src="~/Scripts/app.js"></script>
</head>
<body>
Home
Projects
<div ng‐view style="margin‐left: 10%; margin‐right: 10%;">
</div>
//... footer
</body>
</html>
My app.Js code is as follow:
var app = angular.module('ProjectTrackingModule', ['ngRoute', 'ui.bootstrap']);
app.config(function ($routeProvider) {
$routeProvider
.when("/Home", {
templateUrl: "/Views/Home/Home.cshtml",
controller:"HomeController"
})
.when("/Projects", {
templateUrl: "/Views/ProjectManagement/ProjectDetails.cshtml",
controller: "ProjectsController"
})
.otherwise({redirectTo:"/Home"})
});
I want to load my Home.Cshtml partial view inside ng-view. But when I run my application, It only showing Home partial view.
also when I click on Project, then it should render ProjectDetails.cshtml inside ng-view.
code inside ProjectDetails.cshtml
<div ng-controller="ProjectsController">
<h2>ProjectDetails</h2>
</div>
I think you have some misonceptions about Angularjs routing concepts.
MVC Routing :
ASP.NET routing enables you to use URLs that do not have to map to specific files in a Web site. Because the URL does not have to map to a file, you can use URLs that are descriptive of the user's action and therefore are more easily understood by users.
Angular Routing :
Angular.js routing using MVC framework does not use MVC routing.
Comparable parts are:
Model ===== ng-module
controller ===== ng-controller
view ===== ng-view
So you can't call the MVC Controller in your angularjs route config. Does this make sense?
Also please think about some of the differences between cshtml and html.
Angular routing and MVC routing are totally different because:
Angular routing is use client side
MVC routing is used server side
The above texts are for your understanding only.
I think this discussion will help you :
How to use ASP.NET MVC and AngularJS routing?
Update :
The href is wrong in Anchor tag.
Its should be href="#/Home", not href="#Home"
So please change your code
Home
Projects
Lets understand the routing in angular first. lets say your url says
www.example.com/Home/Index -- this points to your MVC HomeController and Index ActionMethod. Now what mvc does, it returns you the first View only.
say you have an anchor Load the New View. Clicking this will result in a new Url www.example.com/Home/Index#/angular-route. This url will still hit the same MVC HomeController and ActionMethod.
But you have an additional route in angular
`var app = angular.module('ProjectTrackingModule', ['ngRoute', 'ui.bootstrap']);
app.config(function ($routeProvider) {
$routeProvider
.when("/angular-route", {
templateUrl: "/Html/GetHtml?type=angular-route",
controller:"AngularController"
})
.otherwise({redirectTo:"/Home"})
});`
Here in the code section templateUrl: "/Html/GetHtml?type=angular-route",
Html is MVC Controller and GetHtml is ActionMethod. This ActionMethod returns you the new view that you want according to the angular route, that's why we are sending a parameter type too to help us decide.
controller:"AngularController" says that angular will call its controller after the page is returned from you mvc controller. It's Angular's Controller and it has nothing to do with your MVC controller.
you declare angular controller like this:
app.controller('AngularController',function($scope){
alert("my js controller is called");
});
Hope this helps you to find a solution.
Have a simple example can apply to your project. Example our MVC application has four pages as Home, Contact, About and User, we want to create a angularjs template for each pages, so how we do routing for it? how to make angularjs controller for it?
Basic code as following:
Routing:
$routeProvider
.when('/', { // For Home Page
templateUrl: '/AngularTemplates/Home.html',
controller: 'HomeController'
})
.when('/Home/Contact', { // For Contact page
templateUrl: '/AngularTemplates/Contact.html',
controller: 'ContactController'
})
.when('/Home/About', { // For About page
templateUrl: '/AngularTemplates/About.html',
controller: 'AboutController'
})
.when('/Home/User/:userid', { // For User page with userid parameter
templateUrl: '/AngularTemplates/User.html',
controller: 'UserController'
})
.otherwise({ // This is when any route not matched => error
controller: 'ErrorController'
})
}]);
Controller:
var app = angular.module('MyApp'); app.controller('UserController', ['$scope', '$routeParams', function ($scope, $routeParams) {
$scope.Message = "This is User Page with query string id value = " + $routeParams.userid;}]); ...
Full article with download code for it at Angularjs routing asp.net mvc example
You cannot directly point on the .cshtml file but you can point to a templateUrl that points to an MVC route.
Considering you are using the default MVC route {controller}/{action}/{id?}, for example:
var app = angular.module('ProjectTrackingModule', ['ngRoute', 'ui.bootstrap']);
app.config(function ($routeProvider) {
$routeProvider
.when("/Home", {
templateUrl: "/Home/Home", //points to an mvc route controller=Home, action=Home
controller:"HomeController"
})
.otherwise({redirectTo:"/Home"})
});
But in order for it to work the MVC Action should be in the controller also.
public class HomeController : Controller
{
[HttpGet]
public ActionResult Home()
{
return View();
}
}
also your anchor tags points to an incorrect href, it should have the hashbang (#)
Home
Projects
Simple way to do it would be like follows:
MyAngularApp.js
var myAngularApp = angular.module('MyAngularApp', ['ngRoute']);
myAngularApp.config(function ($routeProvider) {
$routeProvider
.when("/myprojects", {
templateUrl: "MyAspMvcCtrl/GetTemplate?id=myprojects",
controller:"MyAngularController"
})
...
.otherwise({redirectTo:"/myprojects"})
});
myAngularApp.controller("MyAngularController", function ($scope) {
...
// Do something
$scope.mydata = {
id = 1234,
msg = "Hello"
};
});
ASP.Net MVC Controller
public class MyAspMvcCtrlController : Controller
{
[HttpGet]
public ActionResult GetTemplate(string id)
{
switch (id.ToLower())
{
case "myprojects":
return PartialView("~/Views/ProjectManagement/ProjectDetails.cshtml");
default:
throw new Exception("Unknown template request");
}
}
}
Layout.cshtml
<html ng-app="myAngularApp">
...
<body>
...
<div ...>
...
My Projects
...
</div>
<div ng-view></div>
...
</body>
</html>
ProjectDetails.cshtml
<div ...>
<h3>ID: {{mydata.id}}</h3>
<p>Message: {{mydata.msg}}</p>
</div>
AngularJs Routing Does not working with cshtml files !!
if you want to use angularjs routing with mvc view (cshtml) file use both routing:
angular routing + mvc routing
your routing code should be like this:
.when("/Home", {
templateUrl: "/Home/Home",
controller:"HomeController"
});
where First Home is Controller Name
and Second Home is The Action Name at the Mvc Controller.

MVC application throws an error "Resource cannot be found"

I am new to MVC. I created an empty mvc application. Later added a view, a controller and a model for the view. After adding these three parts into the application, i tried running the application. But, i got "resource cannot be found" error from the browser. I cannot figure out the reason behind this.
Is there any settings to be modified to make it run properly? I did not change any settings.
Can anyone help me out of this?
Thanks
Manikandan
Add class config the default route and call it from global.asax
And of course add Home controller with action Index
public static 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 }
);
}
}
If all you've done is as you described, then the most likely cause for this is that you've used a Visual Studio template that doesn't include some scripts that are referenced in the auto-generated views you created.
Try opening the view that has this error (the view that you added) and remove its Scripts.Render directives, then run your app again and see if it goes away.
If it does go away using the above, then the problem is these missing scripts. In that case, you may either choose not to have them in your app or install them using nuget.
You probably didn't request the correct url in your browser or you didn't name your controller correctly.
Let's suppose that you wanted to add a HomeController.
Here are the steps:
Create a new ASP.NET MVC Empty Application
Add ~/Controllers/HomeController.cs
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
}
Add ~/Views/Home/Index.cshtml:
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>Index</title>
</head>
<body>
<div>
</div>
</body>
</html>
Run the application and navigate to /Home/Index

Resources