Asp.net mvc 4 允许管理员使用iframe模拟用户

Asp.net mvc 4 允许管理员使用iframe模拟用户,asp.net-mvc-4,model-view-controller,iframe,admin,Asp.net Mvc 4,Model View Controller,Iframe,Admin,我有一个MVC项目,它有三个角色:用户、客户经理和管理员 管理员有自己的MVC区域,在那里他们可以完全控制用户和客户经理。我正在尝试实现允许管理员以任何用户或帐户管理员的身份查看站点的功能 在网站的管理区域,我有一个用户和客户经理列表的视图。该列表包含每个记录的“以用户身份查看站点”按钮 我以前从未做过类似的操作,但是ViewAsController操作当前设置为使用所选用户的信息创建会话,如下所示: ViewBag.SiteSession = Session["SiteSession"] =

我有一个MVC项目,它有三个角色:用户、客户经理和管理员

管理员有自己的MVC区域,在那里他们可以完全控制用户和客户经理。我正在尝试实现允许管理员以任何用户或帐户管理员的身份查看站点的功能

在网站的管理区域,我有一个用户和客户经理列表的视图。该列表包含每个记录的“以用户身份查看站点”按钮

我以前从未做过类似的操作,但是
ViewAs
Controller操作当前设置为使用所选用户的信息创建会话,如下所示:

ViewBag.SiteSession = Session["SiteSession"] = new SiteSession()
{
    ID = user.ID,
    AccountID = user.AccountID,
    DisplayName = user.DisplayName,
    IsManager = user.IsAdmin,
    IsAdmin = false
};
@model string
<iframe src="@Model" >

</iframe>
[HttpGet]
public ActionResult Start(int id)
{
    var user = db.Users
        .First(u => u.ID == id);

    Session["SiteSession"] = new SiteSession()
    {
        //Session data...
    };

    return PartialView("_IFrame");
}
与此操作相关的视图将模型定义为
字符串
,而只定义了一个iframe,模型作为
src
属性,如下所示:

ViewBag.SiteSession = Session["SiteSession"] = new SiteSession()
{
    ID = user.ID,
    AccountID = user.AccountID,
    DisplayName = user.DisplayName,
    IsManager = user.IsAdmin,
    IsAdmin = false
};
@model string
<iframe src="@Model" >

</iframe>
[HttpGet]
public ActionResult Start(int id)
{
    var user = db.Users
        .First(u => u.ID == id);

    Session["SiteSession"] = new SiteSession()
    {
        //Session data...
    };

    return PartialView("_IFrame");
}
该区域设置为“无”,以避免渲染管理区域的主页

目前,这不起作用。除了我已经拥有的,我甚至不知道从哪里开始

我在寻找任何建议。非常感谢所有的帮助,因为这似乎不是一项容易的任务

如果你不知道如何帮助别人,如果你能把这个问题告诉能帮上忙的人,我们将不胜感激


再次,提前感谢。

我过去做这件事的方式是使用实际用户和有效用户的概念。大多数显示操作使用有效用户生成其内容。通常,我将其实现为“模拟”,而不是“预览”,因此用户实际上是作为用户导航站点,而不是在单独的窗口中显示。在本例中,我只是在当前会话中设置了这两个参数。需要管理员权限的事情(如切换到/从模拟)显然使用的是真实用户

如果您想进行预览,那么我会考虑在每个请求上使用一个参数来设置有效用户。代码需要理解如何将此参数添加到所有链接,以便您可以在
iframe
中导航,而不会扰乱原始界面中的导航


至于从url中删除区域,我认为您所做的(设置为空字符串)应该可以工作。如果它不起作用,你可能想试试小写的
area
Url.Action(“Index”,“Home”,new{area=”“})
。我很确定在引擎盖下创建的
RouteValueDictionary
使用了不区分大小写的键比较,所以这不重要。

对于这个任务,我最终创建了一个单独的控制器,
ViewAsController
,它有一个控制器范围的
[Authorize]
属性,该属性仅允许具有管理员角色的用户访问其操作

开始
操作中,将创建一个包含所选用户信息的
会话
对象,如下所示:

ViewBag.SiteSession = Session["SiteSession"] = new SiteSession()
{
    ID = user.ID,
    AccountID = user.AccountID,
    DisplayName = user.DisplayName,
    IsManager = user.IsAdmin,
    IsAdmin = false
};
@model string
<iframe src="@Model" >

</iframe>
[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>
您可以在这里看到,该对话框是在documentready上初始化的,并且在检索部分视图的AJAX调用成功完成之前不会打开

管理员关闭对话框后,服务器在
ViewAs
控制器中调用
End
操作,销毁会话:

[HttpPost]
public ActionResult End()
{
    Session["SiteSession"] = null;

    return new HttpStatusCodeResult(System.Net.HttpStatusCode.OK);
}
我绝对不想“预览”,实际上我不确定你是从哪里推断出来的。我确实希望从本质上模拟用户。我称之为“预览”,因为您在iframe中单独显示,同时保持原始界面完整。也许我的术语是错误的,但我所说的模拟的意思是,您只需将原始界面更改为显示为模拟用户(停止模拟的能力是唯一的区别)。并行模拟似乎比较困难,因为在没有请求参数的情况下,服务器上无法区分来自iframe/封闭窗口的请求之间的差异。