【问题标题】:Return URL and SessionTimeout not working properly using ASP .Net MVC 5?使用 ASP .Net MVC 5 返回 URL 和 SessionTimeout 不能正常工作?
【发布时间】:2016-07-12 12:36:52
【问题描述】:

我创建了一个类CheckSessionTimeOutAttribute,在这里我创建了一个方法,用于在会话超时时自动注销时返回 url。

当它在会话超时时自动注销时,它需要返回 url。当我编写正确的凭据时,它是登录控制器的返回视图。它不会是两个返回 url。

另一个问题是当会话超时并进入登录页面时,当我按下浏览器的返回时,它会进入上一页,这是不可能的。即使我注销时它也不起作用。

http://localhost:1563/?returnUrl=%2FElectricity

当我登录时它不会返回像http://localhost:1583/Electricity这样的网址

它去了http://localhost:1563/user

登录控制器:

public ActionResult Index()
        {
            ViewBag.Title = "Example.com | Login";
            return View();
        }

    [HttpPost]
            public ActionResult Index(FormCollection fc)
            {
                string username = fc["username"].ToString();
                string password = fc["password"].ToString();
                var query = (from u in db.tbl_user
                             where u.USERNAME == username && u.PASSWORD == password
                             select u).FirstOrDefault();
                if (query != null){
                    Session["username"] = username;
                    Session["login"] = true;
                   return RedirectToAction("Index","User");
                }
                return View("Index");
            }

类名CheckSessionTimeOutAttribute

[AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
    public class CheckSessionTimeOutAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (HttpContext.Current.Session["login"] == null)
            {
                FormsAuthentication.SignOut();
                filterContext.Result =
               new RedirectToRouteResult(new RouteValueDictionary
                 {
             { "action", "Index" },
            { "controller", "Login" },
            { "returnUrl", filterContext.HttpContext.Request.RawUrl}
                  });

                return;
            }
        }
    }

web.config:

<sessionState mode="InProc" timeout="1" cookieless="false"></sessionState>
    <authentication mode="Forms">
      <forms loginUrl="~/Login" timeout="1">
      </forms>
    </authentication>

【问题讨论】:

  • 显示您的登录控制器索引获取操作
  • @EhsanSajjad ,我添加了登录控制器的索引获取功能。
  • 请不要将 FormCollection 用于您的模型,使用 TempData 也不是最好的主意。我会尽快发布答案!

标签: c# asp.net asp.net-mvc asp.net-mvc-4


【解决方案1】:

@Manish,如下更改登录控制器。

    public ActionResult Index(string returnUrl = "")
    {
        ViewBag.Title = "Smartmultiservices.in | Login";
        if (!string.IsNullOrWhiteSpace(returnUrl))
        {
            TempData["returnUrl"] = returnUrl;
        }
        return View();
    }

    [HttpPost]
    public ActionResult Index(FormCollection fc)
    {
        string username = fc["username"].ToString();
        string password = fc["password"].ToString();
        var query = (from u in db.tbl_user
                     where u.USERNAME == username && u.PASSWORD == password
                     select u).FirstOrDefault();
        if (query != null)
        {
            Session["username"] = username;
            Session["login"] = true;
            if (TempData["returnUrl"] != null && !string.IsNullOrWhiteSpace(TempData["returnUrl"].ToString()))
                return Redirect(TempData["returnUrl"].ToString());
            else
                return RedirectToAction("Index", "User");
        }
        return View("Index");
    }

【讨论】:

  • 感谢@Wells,它正在工作。我在web.config 文件中提到了另一个问题。如果我设置了会话超时 15 但它会在几秒钟内自动会话超时。该怎么办 ?请帮帮我。
【解决方案2】:

由于您使用的是 MVC,我不建议使用 FormCollection 作为传递给控制器​​方法的模型。坚持使用 MVC 模式将有助于简化很多事情,尤其是当您的应用程序变得更加复杂时。因此,让我们从您的登录模型开始:

using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;

namespace YouProjectName.Models
{
    public class AccountLoginModel
    {
        [Required]
        public string Username { get; set; }

        [Required]
        [DataType(DataType.Password)]
        public string Password { get; set; }

        [HiddenInput(DisplayValue = false)]
        public string ReturnUrl { get; set; }
    }
}

您不必使用 [Required][DataType][HidenInput] 等属性来装饰模型属性,但我强烈建议您使用它们,因为我将向您展示几种不同的方式来渲染视图(也强烈建议添加 required 属性,这样您就不必在控制器中单独检查必填字段)。

话虽如此,让我们看看我们如何在控制器方法中处理模型:

[HttpGet]
public ActionResult Index(string returnUrl = "")
{
    return View(new AccountLoginModel {ReturnUrl = returnUrl});
}

[HttpPost]
public ActionResult Index(AccountLoginModel model)
{
    if (!ModelState.IsValid)
    {
        return View(model);
    }

    var query = (from u in db.tbl_user
                 where u.USERNAME == model.Username && u.PASSWORD == model.Password
                 select u).FirstOrDefault();
    if (query != null){
        Session["username"] = model.Username;
        Session["login"] = true;

       if (!string.IsNullOrWhiteSpace(model.ReturnUrl))
       {
            return Redirect(model.ReturnUrl);
       }

       return RedirectToAction("Index", "User");
    }

    ModelState.AddModelError("", "Username and/or Password is incorrect");
    return View(model);
}

[HttpGet] 版本的 Index 方法将模型的新实例传递给视图,同时还捕获传递给方法的 returnUrl 参数。在Index 方法的[HttpPost] 版本中,它首先检查ModelState.IsValid。模型上标记为[Required] 的所有属性都在此处验证。如果它无效,只需将模型返回到视图,错误消息就会显示给用户。最后检查model.ReturnUrl 是否为空。如果不是,则重定向到其中的值,如果不是,则重定向到 UserController。

有了视图,您有几个选择。如果你使用属性来装饰你的模型属性,你可以做一些简单的事情:

@model YouProjectName.Models.AccountLoginModel

@{ ViewBag.Title = "Example.com | Login"; }

@Html.ValidationSummary()

@using (Html.BeginForm())
{
    @Html.EditorForModel()
    <button type="submit">Submit</button>
}

通过调用@Html.EditorForModel(),剃刀视图将查看模型属性并根据应用于每个属性的属性呈现它们。不过,您不必这样做。您始终可以手动添加每个输入以保持对 HTML 元素布局的完全控制。像这样的东西(只是一个使用 Twitter 引导 css 的例子):

@model YouProjectName.Models.AccountLoginModel

@{ ViewBag.Title = "Example.com | Login"; }

@Html.ValidationSummary()

@using (Html.BeginForm("Index", "Login", FormMethod.Post))
{
    <div class="row">
        <div class="col-md-1">
            @Html.LabelFor(x => x.Username)
        </div>
        <div class="col-md-4">
            @Html.TextBoxFor(x => x.Username)
        </div>
    </div>
    <div class="row">
        <div class="col-md-1">
            @Html.LabelFor(x => x.Password)
        </div>
        <div class="col-md-4">
            @Html.PasswordFor(x => x.Password)
        </div>
    </div>
    @Html.HiddenFor(x => x.ReturnUrl)
    <button type="submit" class="btn btn-primary">Submit</button>
}

这里的重要部分是确保在表单中为 returnUrl 添加@Html.HiddenFor()。这样,返回 url 将与其余属性一起发回!

【讨论】:

  • 感谢@Bobby Caldwell 的宝贵时间,实际上我是新的 ASP MVC 模式,所以我对此一无所知。再次感谢给我一个好主意。我有另一个问题Session Timeout,我在上面的 web.config 文件中提到过。问题是如果我设置了会话超时 15 但它会在几秒钟内自动会话超时。如何以正确的方式设置会话超时?你能给我你的想法吗?
  • 这可能与您的自定义 CheckSessionTimeOutAttribute 有关。当用户会话过期时,MVC 会自动将 returnUrl 添加到 URL,因此删除 CheckSessionTimeOutAttribute 是安全的。尝试将超时设置为 2880。通过删除您的自定义超时属性来尝试一下,导航到 localhost:1583/Electricity 然后手动删除您的 cookie(删除 cookie 时搜索 localhost,这样您就不会删除所有 cookie!)然后刷新这页纸。它会自动为你添加returnUrl!
猜你喜欢
  • 2011-04-29
  • 2016-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-30
  • 1970-01-01
  • 2017-01-21
相关资源
最近更新 更多