繁体   English   中英

ASP.NET MVC:将数据从操作过滤器传递到视图

[英]ASP.NET MVC: Pass data from action filter to view

我创建了一个检查 HTTP 标头的操作结果,如果返回某个标头值,那么我想在会话变量中存储一个布尔值。 然后我希望在局部视图中使用该会话变量,以确定是否应该出现某些 HTML。

如何将会话变量从我的操作过滤器传递到我的局部视图?

动作过滤器(在 BaseController.cs 内):

public class AuthorizationFilterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        base.OnActionExecuting(filterContext);

        string url = "http://www.website.com";

        bool retry = false;
        int retries = 0;
        int maxRetries = 2;

        bool authorized = true;
        bool paymentReceived = true;

        do
        {
            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();


                // If not authorized, redirect to login page
                if (response.Headers["key"] == "1")
                {
                    authorized = false;
                    filterContext.HttpContext.Session["authorized"] = authorized;

                    filterContext.Result = new RedirectResult("https://www.website.com");
                }

                response.Close();
            }
            catch (WebException we)
            {
                System.Diagnostics.Debug.Write(we.Message + "\n");

                retry = true;
                retries++;
            }
        }
        while (retry == true && retries < maxRetries);
    }
}

部分视图(当前):

<ul class="navigation">
<li><a href="/">Nav 1</a></li>
<li><a href="/">Nav 2</a></li>

@if (Model.Authorized != null)
{
    if (Model.Authorized == true)
    {
        <li><a href="/">Nav 3</a></li>
    }  
}
</ul>

我最初只是尝试将 Session 变量直接从 BaseController 传递给局部视图,如下所示:

@if (Session["authorized"] == true)

但我一直从它那里得到一个NullReferenceException 然后我四处阅读,发现数据应该通过模型从控制器传递到视图,所以我做了如下的事情:

个人控制器:

public class ControllerModel : BaseControllerModel
{
    public bool Authorized { get; set; }
}

public ActionResult Authorized()
{
    ControllerModel model = new ControllerModel();
    model.Authorized = (bool)HttpContext.Session["authorized"];
    return View(model);
}

现在,Session 变量在那里,但它总是返回 false(我假设它只是返回默认值)。

在这一点上,我看到两个问题:

  1. 我在两个不同的位置、基本控制器和每个单独的控制器中创建一个单独的会话变量。 局部视图从单个控制器中提取数据,那么如何让局部视图从基本控制器中提取数据?

  2. 如果我应该首先将数据传递给模型,我是否应该在 BaseController 内部创建一个 action 方法并使用 BaseControllerModel(见下文)? 这听起来像是一个糟糕的主意,但我想以某种方式制作一个适用于所有控制器的通用方法,因为每个视图中都存在局部视图。

在基本控制器中:

public ActionResult Authorized()
{
    BaseControllerModel model = new BaseControllerModel();
    model.Authorized = (bool)HttpContext.Items["authorized"];
    return View(model);
}

在基本控制器模型中:

public bool Authorized { get; set; }

真正有效的选项)问题在于过滤器无权访问ViewDataViewBagTempData 但是,可以访问context.HttpContext.Items[]示例:

在过滤器中:

context.HttpContext.Items["MyObject"] = new MyObject

鉴于:

@{ MyObject obj = (MyObject)Context.Items["MyObject"]; }

可能像这样应用过滤器:

[AuthorizationFilter]
public ActionResult Authorized()
{
    ControllerModel model = new ControllerModel();
    model.Authorized = (bool)HttpContext.Session["authorized"];
    return View(model);
}

当授权为真时,您永远不会存储到会话中。

if (response.Headers["key"] == "1")
{
      authorized = false;
      filterContext.HttpContext.Session["authorized"] = authorized;

      filterContext.Result = new RedirectResult("https://www.website.com");
} else {
      filterContext.HttpContext.Session["authorized"] = authorized;
}               

我相信我找到了答案。 我的问题是我试图访问 Authorize() 方法中的会话变量,但由于我的部分视图包含在索引页面内,我应该将我的会话变量存储在 Index() 方法内。

所以我的两个更改是将 session 变量添加到每个控制器内的 index() 方法,并将授权过滤器添加到该方法以确保它被调用。

    [AuthorizationFilter]
    public ActionResult Index()
    {
        model.Authorized = (bool)HttpContext.Session["authorized"];
        return View(model);
    }

然后正如 B2K 所说,我还在我的操作过滤器中添加了一个 else 语句,以确保还存储了 true 值。

    else
    {
        filterContext.HttpContext.Session["authorized"] = authorized;
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM