![](/img/trans.png)
[英]How to structure Knockout JS for this scenario (Using ASP.NET MVC)
[英]How to hide role based section in knockout component using asp.net MVC
什么是阻止用户在淘汰组件中看到管理员链接等内容的最佳方法?
如果用户有权查看这些链接,我不想发出客户端请求,因为它会在客户端上公开此部分。
我能弄清楚的唯一方法是使用视图来表示组件模板,然后在呈现HTML之前检查用户是否在服务器端是正确的。
但是,还有另一种比这更清洁的方式,还是正确的方法?
我在AngularJS Apps上面临着类似的挑战。
我喜欢在Model或ViewBag
传递登录状态和角色,而不是执行额外的服务请求。
为简单起见,我们假设我们正在使用ViewBag
。
1)在Action Method中 ,设置
ViewBag.loggedIn = User.Identity.IsAuthenticated;
ViewBag.userId = User.Identity.GetUserId();
var identity = (System.Security.Claims.ClaimsIdentity)User.Identity;
ViewBag.roles = identity.Claims
.Where(c => c.Type == ClaimTypes.Role)
.Select(c => c.Value);
2)在JS文件中 ,使用绑定和函数全局定义UserModel
,以检查用户是否具有正确的角色名称:
var UserModel = function () {
var self = this;
self.isLoggedIn = ko.observable("");
self.userId = ko.observable("");
self.roles = ko.observableArray([]);
// function to check if role passed is in array
self.hasRole = function (roleName) {
for (i = 0; 1 < self.roles.length ; i++ ) {
if (self.roles[i] == roleName)
return true
}
return false;
}
};
var UserData = new UserModel();
在.cshtml中查看:
3)绑定角色并登录数据
<script type="text/javascript">
UserData.isLoggedIn("@ViewBag.isLoggedIn");
UserData.userId("@ViewBag.userId");
UserData.roles(@Html.Raw(Json.Encode(ViewBag.roles));
</script>
4)如果Role
正确则显示部分:
<div data-bind="visible: UserData.hasRole("Admin")>
....
</div>
剃刀方式:
而不是使用Knockout隐藏组件,而是有C#/ Razor方式
- >嵌套if子句
@((List<String>) ViewBag.roles.contains("Admin"))
{
...
}
Razor条件优于Knockout的优点是当服务器创建页面时组件不会呈现,不会留下客户端看到的痕迹
- > _Layout
条件部分
@if ((List<String>) ViewBag.roles.contains("Admin"))
{
@RenderSection("Admin Section")
}
比简单的Razor Condition更清洁,并在整个应用程序中自动应用
- >部分与儿童行动
调用(Action, Controller, Parameter)
:
@Html.Action("AdminConsole", "Admin", new { Role = "Admin"})
public ActionResult AdminComponent(string Role)
{
If (List<String>) ViewBag.roles.contains("Admin")
return PartialView(
return View(products);
}
所有方法中最干净的。 可以在一个部分组合以获得更大的便利。
您如何选择隐藏管理组件取决于您的需求。 Razor / C#方法更方便,更安全。
另一方面,如果您有兴趣为用户提供SPA体验,那么C#
和服务器方法就会失败。 您是否允许用户进行身份验证而不刷新页面? 如果是这样,管理员可以验证并从匿名用户更改为管理员。
如果您对刷新屏幕以显示更改的内容感到满意,那么C#/Razor
就是您的方法。 如果您的首要任务是为用户提供“响应体验”,那么您需要实现Knockout解决方案。
如果您无法将标记公开给客户端,那么执行此操作的唯一方法是在生成标记之前在服务器上。 正如您所指出的,这将在视图渲染中完成。
在您的情况下,使用部分视图来保存您的KO组件是合适的,并提供您需要的功能,同时允许您重用组件标记。
这是我过去使用的方法,它非常干净地工作:
<script type="text/javascript">
ko.components.register("foo", {
viewModel: FooComponentViewModel,
template: { element: "component-foo" }
});
</script>
...
<foo params="IsAdmin: @(User.IsInRole("Admin") ? 'true' : 'false')"></foo>
...
@Html.Partial("Components/_Foo")
如有必要,甚至可以通过MVC视图模型将附加上下文传递给局部视图。
<template id="component-foo">
@if(@User.IsInRole("Admin"))
{
// something you DO care about the client seeing
}
...
</template>
@if(@User.IsInRole("Admin"))
{
<script type="text/javascript">
// Some JS code to hide from non admins for this component
</script>
}
function FooComponentViewModel(params) {
var self = this;
self.AdminDoSomething = function () {
if (!params.IsAdmin) {
return;
}
// something you DO NOT care about the client seeing...
};
}
我知道在提供您所寻求的要求的同时,没有更清洁的方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.