如何使用AngularJS和MVC5(ASP.NET Identity)加载部分登录和注册视图
How to load partial login and registration views with AngularJS and MVC5 (ASP.NET Identity)
我正在尝试使用MVC5、ASP.NET Identity和Angular构建一个具有登录/注册功能的SPA。我对网络开发和几乎所有的网络技术都很陌生。在大量阅读HTML、JavaScript、CSS和Angular之后,我决定一个好的起点是Visual Studio中的单页应用程序模板。尽管这个模板已经为我提供了完整的登录和注册功能,但它使用Knockout进行数据绑定和视图路由。我需要使用AngularJS来完成此操作。到目前为止,我已经使用$http
Angular服务调用了AccountController中的API方法。我按如下方式登录:
var config = {
method: 'POST',
url: http://localhost:52091/token,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: 'grant_type=password&username=' + username + '&password=' + password,
};
var userData = {
isAuthenticated: false,
username: '',
bearerToken: '',
expirationDate: null,
};
function setHttpAuthHeader() {
$http.defaults.headers.common.Authorization = 'Bearer ' + userData.bearerToken;
}
$http(config)
.success(function (data) {
userData.isAuthenticated = true;
userData.username = data.userName;
userData.bearerToken = data.access_token;
userData.expirationDate = new Date(data['.expires']);
$http.defaults.headers.common.Authorization = 'Bearer ' + userData.bearerToken;
if (typeof successCallback === 'function') {
successCallback();
}
})
.error(function (data) {
if (typeof failedCallback === 'function') {
if (data.error_description) {
failedCallback(data.error_description);
} else {
failedCallback('Unable to contact server; please, try again later.');
}
}
});
首先,我不能100%确定为什么这是有效的,以及它是否是正确的登录方式,但它似乎是有效的。这里的任何解释都将不胜感激,但这不是这个问题的主要目的。其次,我调用register方法如下:
// Registration
service.register = function (username, password, confirmPassword, successCallback, failedCallback) {
var config = {
method: 'POST',
url: 'api/account/register',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: 'username=' + username + '&password=' + password + '&confirmPassword=' + confirmPassword,
};
var userData = {
isAuthenticated: false,
username: '',
bearerToken: '',
expirationDate: null,
};
function setHttpAuthHeader() {
$http.defaults.headers.common.Authorization = 'Bearer ' + userData.bearerToken;
}
$http(config)
.success(function (data) {
userData.isAuthenticated = true;
userData.username = data.userName;
userData.bearerToken = data.access_token;
userData.expirationDate = new Date(data['.expires']);
$http.defaults.headers.common.Authorization = 'Bearer ' + userData.bearerToken;
if (typeof successCallback === 'function') {
successCallback();
}
})
// Handle errors properly
.error(function (data) {
if (typeof failedCallback === 'function') {
if (data.error_description) {
failedCallback(data.error_description);
} else {
failedCallback('Unable to contact server; please, try again later.');
}
}
});
}
这会调用AccountController上的Register方法:
// POST api/Account/Register
[AllowAnonymous]
[Route("Register")]
public async Task<IHttpActionResult> Register(RegisterBindingModel model)
{
if (!ModelState.IsValid) {
return BadRequest(ModelState);
}
IdentityUser user = new IdentityUser {
UserName = model.UserName
};
IdentityResult result = await UserManager.CreateAsync(user, model.Password);
IHttpActionResult errorResult = GetErrorResult(result);
if (errorResult != null) {
return errorResult;
}
return Ok();
}
这一切都很好。我可以注册一个新用户并登录。现在,我想在我的"登录"answers"注册"视图之间配置两个路由,以便在它们之间切换,并在必要时加载正确的视图,即Login.cshtml视图将有一个"注册"链接,单击该链接时,应加载register.chtml视图,反之亦然。我在app.js:.中定义了一个新的路由,尝试了这个方法
angular.module('Authentication', []);
angular.module('Home', []);
angular.module('BasicHttpAuthExample', [
'Authentication',
'Home',
'ngRoute',
'ngCookies'
])
.config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {
$routeProvider
.when('/register', {
controller: 'RegisterController',
templateUrl: 'Home/Register',
})
.when('/login', {
controller: 'LoginController',
templateUrl: 'Home/Login',
});
}])
如果我有一个带有2个ActionResult方法的HomeController,这就行了。一个用于注册,一个用于登录。只是,当我创建一个新的单页应用程序时,项目似乎不是这样设置的。它给我的只是一个空的家庭控制器。Register方法存在于Account API控制器中,并且任何地方都没有Login方法。_Register和_Login视图都是局部视图。这给我带来了完全的困惑,因为我仍然习惯于控制器中的每个ActionResult方法,该方法具有链接到它的相应视图
有人知道我如何用Angular加载局部视图吗?
不确定您是否已经弄清楚了,但有一种方法可以通过angular加载局部视图。以下答案需要注意。它使用Ui路由器(而不是ngRoute)进行角度路由。注意:如果您想对以下内容进行更多解释,请提问。
创建一个仅为部分视图提供服务的控制器,并在路由配置中为其添加路由。
以下代码进入routeconfig.cs(在默认路线之前)
//Partial view route
routes.MapRoute(
name: "PartialViews",
url: "PartialView/{action}/{id}",
defaults: new { controller = "PartialView", action = "GetView", id = UrlParameter.Optional }
);
//Default route
routes.MapRoute(
name: "AllElse",
url: "{*url}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
这是控制器代码,将为您的部分视图(登录、注册等)提供服务。
public class PartialViewController : Controller
{
[AllowAnonymous]
public ActionResult GetView(string View)
{
return PartialView(View);
}
}
以下是如何从angular调用它(使用ui路由器,它是angular的路由库,可以代替ngRoute使用)。
$stateProvider
.state('app', {
url: '/app',
templateUrl: 'home/app',
controller: 'AppController'
})
.state('login', {
url: '/login',
templateUrl: 'partialview/getview?view=login',
controller: 'LoginController'
})
.state('register', {
url: '/register',
templateUrl: 'partialview/getview?view=register',
controller: 'RegisterController'
});
主控制器如下所示:
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Title = "Home Page";
return View();
}
[Authorize]
public ActionResult App()
{
return PartialView();
}
}
那么Index视图(home/Index.cs.html)是什么样子的呢?见下文:
<div ui-view> </div>
非常感谢roshankar。这非常有效。我只是想提一下我没有使用UI路由器,这个方法仍然有效。我使用$routeProvider
而不是$stateProvider
:按如下方式设置路线
$routeProvider
.when('/', {
controller: 'LoginController',
templateUrl: 'partials/getview?view=login',
})
.when('/login', {
controller: 'LoginController',
templateUrl: 'partials/getview?view=login',
})
.when('/register', {
controller: 'RegisterController',
templateUrl: 'partials/getview?view=register',
})
.when('/orders', {
controller: 'HomeController',
templateUrl: 'Home/Orders',
})
.otherwise({ redirectTo: '/login' });
这就是我现在用来配置路线的方法。然而,如果有人对我在roshankar发布这个答案之前是如何让它工作的感兴趣,下面是我如何让它只使用html文件的。Taiser Joudeh的这篇帖子帮我弄清楚了这一点,这是最值得称赞的。
使用html方法,配置我的路由如下所示:
$routeProvider
.when('/', {
controller: 'LoginController',
templateUrl: '/views/login.html',
})
.when('/login', {
controller: 'LoginController',
templateUrl: '/views/login.html',
})
.when('/register', {
controller: 'RegisterController',
templateUrl: '/views/register.html',
})
.when('/orders', {
controller: 'HomeController',
templateUrl: '/views/orders.html',
})
.otherwise({ redirectTo: '/login' });
如果您不需要使用MVC,那么这将非常有效。
- BrowserId登录请求在文档加载时被调用
- (Ajax)在不重新加载内容的情况下登录页面url
- 在页面加载之前检查登录和重定向
- 登录同一页面,检查SESSION而不重新加载
- Facebook示例JS登录未加载
- 如何在 http:// 页面中加载登录 https:// 页面
- 用户登录时重新加载
- ajax登录表单,重新加载到表单而不是页面上
- 数据don't登录流星后加载
- Ajax在登录表单中显示错误,而不重新加载页面
- 在页面加载时,在登录表单字段中设置光标
- 登录页面加载为部分页面而非完整页面
- XMLHttpRequest 无法在 Ionic 登录到 odoo 服务器时加载 http://localhost:80
- 如何在 3 次登录尝试后重新加载页面并出现 401 未经授权的访问错误?在 asp.net
- 成功登录谷歌后加载页面
- 使用 PhantomJS 登录并加载网站,无需硬编码时间
- 如果用户未登录,如何使用 Jquery AJAX 加载内部日志记录页
- 我可以阻止我的 HTML 页面加载,直到我的 Facebook 登录状态脚本运行之后
- 在加载其他任何内容之前检查用户是否已登录
- 如何使用AngularJS和MVC5(ASP.NET Identity)加载部分登录和注册视图