所以我有一个带服务器端身份验证的基本Web应用程序。然后有一个用于UI的前端角度框架,由指令和角度服务工厂驱动。
这个角度框架需要了解当前页面请求。
等
这是每个请求的常见数据。
我试图找出向前端角度框架提供服务器端信息的最佳方法。
起初我以为我会把它放在HTTP标头中,但你无法在javascript中访问HTTP标头而不需要额外的ajax请求,然后将整个应用程序从最初的ajax请求链接起来。
在初始页面请求的响应过程中,数据是已知的,因此我想提供该响应。
我知道我可以用头标中的隐藏字段来做到这一点,但这对我来说似乎非常黑客,而且我理想地想要回避它。
我唯一能想到的是使用全局动作过滤器,并尝试将javascript注入响应以初始化框架上下文。
E.g。我可以将手动角度引导代码移动到动态服务器端代码,我将其注入响应的末尾(最后运行的脚本)并动态生成angular.module(...)。run函数然后注入我的全局页面以这种方式将数据导入$ rootScope。
编辑:我还可以在初始响应中使用cookie,当脚本运行时,它会存在。
有没有更好的方法可以做到这一点,或者MVC-6中的新功能可以解决这个问题?
答案 0 :(得分:0)
我在MVC 6 om ASP.Net Core 1.0中创建了一个全局操作过滤器,它在执行任何操作后运行,但在处理该操作的视图之前运行。我使用它来构建一个匿名对象,包含我想要服务到前端JS Api的所有数据。
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ihq.moth.common.Filters
{
public class ApiInjectFilter : IActionFilter
{
public void OnActionExecuted(ActionExecutedContext context)
{
///This Code is used to setup json data in a the ViewData Dictionary used by the client side script API, like knowing who the current user is, if they are authenticated, what permissions they have etc (of course the permissions are only used for cosmetic nice haves, permissions are double checked server side).
var isAuthenticated = context.HttpContext.User != null && context.HttpContext.User.Identity != null && context.HttpContext.User.Identity.IsAuthenticated;
var initData = new
{
isAuthenticated = isAuthenticated
//TODO Add User Later
};
var json = JsonConvert.SerializeObject(initData);
var controller = context.Controller as Controller;
controller.ViewData["APP_API_INIT_JS"] = json;
}
public void OnActionExecuting(ActionExecutingContext context)
{
}
}
}
//Configure Services
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc(options => {
options.Filters.Add(typeof(common.Filters.ApiInjectFilter), 0); //My Filter is added here with order 0 (first)
});
.......
}
在每个控制器操作请求(驱动我的整个应用程序,传统MVC获取等)上,这个APIFilter将运行并将javascript InitData(基本上是一个javascript对象(raw,而不是json))添加到ViewEngine&#39 ; s ViewData Dictioary。这将使其在任何视图的上下文中可用。
@{
Layout = null;
var initJsCode = this.ViewData["APP_API_INIT_JS"]; //this is the javascript generated in the Global Action Filter further above that runs after every action, and will contain Page Request Object data in javascript that every page shares (like authentication data and service end point urls etc.
}
<script>
var moth = moth || (function () {
return new function () {
this.getInitData = function () {
return @Html.Raw(initJsCode);
}
}
})();
</script>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - Meower Of The Hour</title>
<link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
</head>
<body>
<div id="mainWrapper" class="container-fluid">
@{ Html.RenderPartial("Navbar");}
@RenderBody()
</div>
<environment names="Development">
<script src="~/js/jquery.js"></script>
<script src="~/js/angular.js"></script>
<script src="~/js/angular-messages.js"></script>
<script src="~/js/bootstrap.js"></script>
@Html.Partial("_InitJSData") //load my namespace with the getInitData method in it
<script asp-src-include="~/js/app.js"></script>
<script asp-src-include="~/js/services/*.js"></script>
<script asp-src-include="~/js/directives/*.js"></script>
<script asp-src-include="~/js/controllers/*.js"></script>
<script src="~/js/appLast.js"></script>
</environment>
<environment names="Production">
@Html.Partial("_InitJSData") //load my namespace with the getInitData method in it
<script src="~/js/scripts.min.js" asp-append-version="true"></script>
</environment>
</body>
</html>
(function(){
var app = angular.module('moth', [])
.run(['$rootScope', function ($rootScope) {
$rootScope.appData = moth.getInitData(); //moth.getInitData is from the partial view above that was made dynamically and will be different for every request.
}]);
})();
这是我做到这一点的最佳方式,但是在页面加载后没有使用cookie或需要ajax请求才能获得它。请记住,当我完成后,将会有更多来自getInitData的数据。它将包含特定于每个请求的API所使用的基于上下文的信息。