我有一个MVC项目,有三个角色:用户,客户经理和管理员。
管理员拥有自己的MVC区域,他们可以完全控制用户和客户经理。我正在尝试实现允许管理员以任何用户或帐户管理员的身份查看网站的功能。
在网站的管理区域中,我有一个用户和客户经理列表的视图。该列表包含每个记录的“以用户身份查看网站”按钮。
我之前从未做过这样的事情,但ViewAs
控制器操作当前已设置为使用所选用户的信息创建会话,如下所示:
ViewBag.SiteSession = Session["SiteSession"] = new SiteSession()
{
ID = user.ID,
AccountID = user.AccountID,
DisplayName = user.DisplayName,
IsManager = user.IsAdmin,
IsAdmin = false
};
与此操作相关的视图将模型定义为string
,除了使用模型作为src
属性的iframe之外别无其他,如下所示:
@model string
<iframe src="@Model" >
</iframe>
我要做的是渲染此iframe中请求的网站的任何部分。当管理员点击“以用户身份查看”时,我想直接转到主页。该URL是通过此调用生成的:
Url.Action("Index", "Home", new { Area = "" }));
区域设置为空,以避免呈现管理区域的主页。
目前,这不起作用。我不知道从哪里开始,减去我已经拥有的东西。
我正在寻找任何建议。非常感谢所有帮助,因为这似乎不是一件容易的事。
如果您不知道如何提供帮助,如果您能将此问题转发给可能的人,我们将不胜感激。
再次,先谢谢。
答案 0 :(得分:2)
我过去做过这种方式的方式是使用实际用户和有效用户的概念。大多数显示操作使用有效用户来生成其内容。通常我将其实现为“模拟”而不是“预览”,因此用户实际上是以用户身份导航网站而不是在单独的窗口中显示。在这种情况下,我只需在当前会话中设置两者。需要管理员权限的事情(比如切换到/模拟)显然会使用真实用户。
如果您想进行预览,那么我会考虑在每个请求上使用参数来设置有效用户。代码需要理解将此参数添加到所有链接,以便您可以在iframe
中导航而不会弄乱原始界面中的导航。
至于从网址中删除区域,我认为你所拥有的(设置为空字符串)应该有效。如果它无法正常工作,您可能需要尝试使用小写area
,Url.Action("Index", "Home", new { area = "" })
。我很确定在引擎盖下创建的RouteValueDictionary
使用不区分大小写的密钥比较,所以它应该没关系。
答案 1 :(得分:0)
对于此任务,我最终创建了一个单独的控制器ViewAsController
,该控制器具有控制器范围的[Authorize]
属性,该属性仅允许具有Admin角色的用户访问其操作。
在Start
操作中,会创建一个包含所选用户信息的Session
对象,如下所示:
[HttpGet]
public ActionResult Start(int id)
{
var user = db.Users
.First(u => u.ID == id);
Session["SiteSession"] = new SiteSession()
{
//Session data...
};
return PartialView("_IFrame");
}
此操作返回一个部分视图,我最终在jQuery UI模式对话框窗口中显示。
以下是该部分视图的代码:
@{
ViewBag.SiteSession = (SiteSession)Session["SiteSession"];
}
<h2>Viewing Site As @ViewBag.SiteSession.DisplayName</h2>
<div>
<iframe src="@Url.Action("Index", "Home", new { Area = "" })"></iframe>
</div>
正如您所看到的,它非常裸露,而这正是它所需要的。 <iframe>
充当浏览器中的浏览器,允许管理员用户完全访问所选用户的任何操作。
为了细节,这里是创建对话框并打开它的jQuery:
$(function () {
$("#viewAsDialog").dialog({
modal: true,
autoOpen: false,
resizable: true,
draggable: true,
closeOnEscape: false,
height: $(window).height() * .9,
width: 1000,
closeText: '',
close: function () {
$.post("@Url.Action("End", "ViewAs", new { Area = "Admin" })")
.success(function (result) {
});
}
});
});
function viewAs(result) {
$("#viewAsDialog").html(result);
$("#viewAsDialog").dialog("open");
}
您可以在此处看到对话框在文档就绪时初始化,并且在成功完成检索部分视图的AJAX调用之前不会打开。
管理员关闭对话框后,服务器会调用End
控制器中的ViewAs
操作,从而破坏会话:
[HttpPost]
public ActionResult End()
{
Session["SiteSession"] = null;
return new HttpStatusCodeResult(System.Net.HttpStatusCode.OK);
}