I am developing a mini SPA, using angular, inside my ASP.Net MVC 5 application. Basically I want to use this mini SPA for onboarding/registration workflow, and use ASP.Net MVC views and routes for other functionality.
For Onboarding mini SPA I have defined an MVC route:
routes.MapRoute(
name: "Onboarding",
url: "onboarding/{*catchall}",
defaults: new { controller = "Onboarding", action = "Create" }
);
The Angular configuration looks like:
(function () {
var app = angular.module('app', ['ngRoute']);
app.config(function ($routeProvider, $locationProvider) {
$routeProvider.caseInsensitiveMatch = true;
$routeProvider.when('/onboarding', { templateUrl: '/app/Views/CreateShop.html', controller: 'onboardingController' })
.when('/onboarding/add-product', { templateUrl: '/app/Views/AddProduct.html', controller: 'onboardingController' })
$locationProvider.html5Mode(true);
});}());
The Create.chtml uses acts as a container/entry point for this mini SPA.
<div ng-controller="onboardingController">
<div ng-view></div>
</div>
#section scripts {
#Scripts.Render("~/bundles/angularOnboarding")
}
PROBLEM: When I am inside the mini SPA my navigation links/routes break e.g. navigation to contact page or about page (MVC Views) doesn't work. Angular seems to handling all routing requests. Also, navigation from an anchor tag which navigates to some MVC route doesn't work.
Putting the url in the browser works.
How do I make this work for my hybrid scenario?
Would really appreciate any suggestions or solution, Thanks.
Related
I have a .net core 2.0 web api with the following get method:
[HttpGet]
public async Task<IEnumerable<Customer>> Get()
{
return await customerDataProvider.GetCustomers();
}
In the startup class i have the following in configuration:
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}");
});
when i run the application i get the results displayed as raw json in the browser.
I would like to add a view and to handle the results in that view meaning display them in a table and add some filtering and sorting options.
How can i achieve this? I saw different articles on how to add a view or a razor page to a project but none of them was similar to my case..
Thanks!
I'm very used to Ionic, and I recently started developping web apps with Angular2. I have an issue with the Router concept.
Let's say I want to make an app, with a login page, which redirects you to a dashboard with 3 tabs.
I Have a LoginPage component, which checks the login details and redirects to the app. How can I simply switch component in Angular 2 ?
I defined my route
const appRoutes: Routes = [
{ path: 'login', component: LoginPageComponent }
];
And on my app.component page, I juste have a button
<h1>
{{title}}
<!--<a routerLink="/login">Heroes</a>-->
<button (click)="login()">Change</button>
</h1>
trigerring this function :
login() {
this.router.navigate(['/login']);
}
When I click this button, my URL is changing : http://localhost:4200/login
But my view is still my view with the button, there is no "change" like in Ionic with a NavController.setRoot(NewComponent)
I don't want to display my content in a <router-outlet>, I'd like to have distincts pages with navigation between them. Is this possible in Angular2 ?
Thank in advance for your help
I am using angular js with Asp.net webforms. I want to retrieve data from database using angular js API. All I have seen on google or any tutorial , uses angular js API's with Asp.net MVC .
My question is: Can we use angular js API with Asp.net web Forms?
If yes, then method will be the same as in Asp.net MVC?
Further I know angular js is for SPA(single page app) and it has Models views and controllers.
Yes, you could.
But I really really don't recommend it. It might be extremely hard to ensure they are not stepping in each other toes, because they both work by enhancing the HTML.
My recommendation is that you start moving your business logic from the Web forms code behind into Service classes, so that you can expose the business logic via [WebMethods]. You could add the WebMethods to the pages but it would be way better if you could add a REST web service endpoint using WebAPI.
Think of an angular SPA as completely independent from the server technology, all you need for Angular to work with the server is an HTTP API, preferably one that returns JSON.
Hi you can use angular with web forms, and you can do single page application also by using $HTTP service in angular.
i have written one ajax call by using web form.
<script type="text/javascript" ><src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular.min.js"></script>
<script type="text/javascript">
var app = angular.module('MyApp', [])
app.controller('MyController', function ($scope, $http, $window) {
$scope.ButtonClick = function () {
var post = $http({
method: "POST",
url: "Default.aspx/GetCurrentTime",
dataType: 'json',
data: { name: $scope.Name },
headers: { "Content-Type": "application/json" }
});
post.success(function (data, status) {
$window.alert(data.d);
});
post.error(function (data, status) {
$window.alert(data.Message);
});
}
});
</script>
<div ng-app="MyApp" ng-controller="MyController">
Name:
<input type="text" ng-model="Name" />
<br />
<br />
<input type="button" value="Submit" ng-click="ButtonClick()" />
</div>
I have a question on how to configure the inbuilt login functionality URL in ASP.net MVC Angular template. The web api url for login is "Account/Login" .
I add an href in layout.cshtml file as shown below
<data-ng-class="{active : activeViewPath==='/contact'}">
<br>
< href='#/contact'>Contact</a></li>
<br>
< data-ng-class="{active : activeViewPath==='/Login'}">
<br>
< href='~/Account/Login'>Login</a></li>
Now when I click any link(demo) , the functional URL is :
://ayz.com/#/demo
When I click Login (works fine):
://ayz.com/Account/Login#/home
When I click demo again (Account/Login gets appended):
://ayz.com/Account/Login#/demo
How to correct this ?
$routeProvider
.when('/home', { templateUrl: '/home/main', controller: 'MainController' })
.when('/contact', { templateUrl: '/home/contact', controller: 'ContactController' })
.when('/about', { templateUrl: '/home/about', controller: 'AboutController' })
.when('/demo', { templateUrl: '/home/demo', controller: 'DemoController' })
.when('/product', { templateUrl: '/home/product', controller: 'ProductController' })
Make sure that ng-view /ng-route just changes the view that is a part of the angular only.!!
As you were already in: //ayz.com/Account/Login
//ayz.com/Account/Login#/home
When you click on demo, the view is just getting updated:
//ayz.com/Account/Login#/demo
Make sure, you use angular route for Account/Logon too.
Try getting the usage of hashbang too.!! Angular js uses that and just updates the part after that for ng-view.!!
Firstly when you were in demo: ayz.com/#/demo with no MVC routing.
And later on when you clicked on Accountlogin the url changed to ayz.com/Account/Logon/#home
and now when you clicked on demo, the last hasbang part of url "#/home" will just be changed to "#/demo" as you are now in Account/Login. And note that Angular routing works only for one ng-View in a single page.
I have an application that have four modules in the front end, I'm trying to use as much as possible AngularJs in the front end I'm using an empty website asp.net project to host all the files and the REST serviceStack, my project have kind of the following structure:
~/ (web.config, global.asax and all the out of the box structure for an asp.net website)
- App <- AngularJs
- Users <- js controllers and views (static html files)
- Companies
- BackEnd
- Public
Index.html
IndexCtrl.js
App.js
- Content
- Js
I use angularjs service calls and the backend I'm using REST with servicestack.
the question is how can I restrict the access only to authenticated users to those static html files? let's say the ones that are inside inside Companies, Backend and users for example
Hi After doing some research this is the solution that worked for me:
Install razor markdown from nuget
Change the file structure to match the default behavior RM [Razor Markdown] to /views
Modify the web config following the approach described in this service stack example
Change all the static htmls files to .cshtml files, this by default creates the same route without the extension like /views/{Pagename} without the extension, I'm just using this approach to get the authorization logic simpler to implement (at least for me)
Update the service method with an authorize attribute you can find out more in this page
to illustrate a lit of bit more this is my route definition in so far:
'use strict';
angular.module('myApp', ['myApp.directives', 'myApp.services']).config(
['$routeProvider', function($routeProvider) {
$routeProvider.when('/Dashboard', {
controller: 'dashboardCtrl',
templateUrl: 'Views/dashboard'
}).when('/Payments', {
controller: 'paymentsCtrl',
templateUrl: 'Views/payments'
}).
when('/Login', {
controller: 'loginCtrl',
templateUrl: 'Views/login'
});
}]
);
Notice that the references are pointed now to the razor paths.
this is a small menu I've done in angular
<div class="container">
<div class="navbar" ng-controller="indexCtrl">
<div class="navbar-inner">
<a class="brand" href="#/">header menu</a>
<ul class="nav">
<li ng-class="{active: routeIs('/Dashboard')}">Dashboard</li>
<li ng-class="{active: routeIs('/Login')}">Login</li>
<li ng-class="{active: routeIs('/Payments')}">payments</li>
</ul>
</div>
</div>
<ng-view></ng-view>
</div>
let's say that the payments page is restricted, so every time I click on a the page I get a 401 unauthorized message.
Service host:
public override void Configure(Container container)
{
Plugins.Add(new AuthFeature(() => new AuthUserSession(), new IAuthProvider[] {
new FacebookAuthProvider(appSettings),
new TwitterAuthProvider(appSettings),
new BasicAuthProvider(appSettings),
new GoogleOpenIdOAuthProvider(appSettings),
new CredentialsAuthProvider()
})); //I'm going to support social auth as well.
Plugins.Add(new RegistrationFeature());
Routes.Add<UserRequest>("/Api/User/{Id}");
Routes.Add<LoginRequest>("/Api/User/login","POST");
Routes.Add<PaymentRequest>("/views/Payments");
}
I hope that helps
Create a CatchAllHander method to check for restricted routes and, for those static files that require authentication, return the ForbiddenFileHander if not authenticated, otherwise return null. Given an isAuthenticated method and restrictedDirs is defined somewhere - maybe your app or web config file, it can be as simple as:
appHost.CatchAllHandlers.Add((httpMethod, pathInfo, filePath) => {
if ( restrictedDirs.ContainsKey(pathInfo) && !isAuthenticated())
return new ForbiddenHttpHandler();
return null;
});
Why not use Forms Authentication? Simply add a few < location > tags to your web.config to allow/disallow different sections, you can even do it based on roles.