[英]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.