如何将自定义属性中的消息返回到我的视图?

时间:2013-12-19 13:51:55

标签: asp.net-mvc razor custom-attributes asp.net-mvc-5

我在this帖子之后的登录操作上实施了限制机制。除了一件事,它按照我想要的方式工作。每当机制返回我的消息时,我都会被重定向到一个新的空白视图,其中包含我的消息。

是否可以,如果是这样,将此消息返回到我的登录控制器/视图,以便它可以显示在我的_LoginPage.cshtml中?

这是我的属性:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class ThrottleAttribute : ActionFilterAttribute
{
    public string Name { get; set; }
    public int Seconds { get; set; }
    public string Message { get; set; }
    public int AllowedRetries { get; set; }
    private int _loginAttempts = 1;

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        string key = string.Concat(Name, "-", filterContext.HttpContext.Request.UserHostAddress);
        bool allowExecute = false;
        _loginAttempts++;

        while (_loginAttempts <= AllowedRetries)
        {
            return;
        }

        if (HttpRuntime.Cache[key] == null)
        {
            HttpRuntime.Cache.Add(key,
                true, 
                null, 
                DateTime.Now.AddSeconds(Seconds),
                Cache.NoSlidingExpiration,
                CacheItemPriority.Low,
                null); 

            allowExecute = true;
        }

        if (!allowExecute)
        {
            if (String.IsNullOrEmpty(Message))
            {
                Message = "AllowedRetries Exceeded. You have to wait {n} seconds.";
            }

            filterContext.Result = new ContentResult
            {
                // TODO: Redirect message text to login-view
                Content = Message.Replace("{n}" , Seconds.ToString())
            }; 

            filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.Conflict;
        }
    }
}

的LoginController:

[Throttle(Name = "LoginThrottle", Seconds = 10, AllowedRetries = 3)]
[HttpPost]
public ActionResult Index(LoginViewModel model)
{
    ...login logic...

    return View(model);
}

更新

按照@ lin的建议,我得到了我想要的信息,但是我无法在我的视图中显示它。在我的cshtml文件中,我首先设置一个变量,然后在我的标记中进一步引用它:

@{
    var informationToUser = ViewBag.Information ?? "";
}
<div class="panel panel-primary>
    ...
    <p>@informationToUser</p>
</div>

仍然没有任何反应:(如下面的评论所述,我的网址现在看起来像这样:http://localhost:54508/?information=AllowedRetries%20Exceeded.%20You%20have%20to%20wait%2010%20seconds.

2 个答案:

答案 0 :(得分:1)

我不确定这是你想要的。但它应该工作。见下面的代码:

节流属性

  if (!allowExecute)
    {
        if (String.IsNullOrEmpty(Message))
        {     
            Message = "AllowedRetries Exceeded. You have to wait {n} seconds.";
        }
        filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.Conflict;

        var values = new RouteValueDictionary(new
        {
                action = "Login",
                controller = "Account",
                exceptiontext = Message.Replace("{n}", Seconds.ToString())
        });
        filterContext.Result = new RedirectToRouteResult(values);
    }

登录操作方法

  [HttpGet]
  public ActionResult Login(string returnUrl, string exceptiontext)
    {
        ViewBag.ReturnUrl = returnUrl;
        ViewBag.Exceptiontext = exceptiontext;
        return View();
    }

更新:您无需验证ViewBag是否为空。

登录视图

 //
<div class="panel panel-primary>
    <p>@ViewBag.Exceptiontext </p>
</div>
//

网址应如下:

http://localhost:58929/Account/Login?exceptiontext=AllowedRetries%20Exceeded.%20You%20have%20to%20wait%2010%20seconds.

答案 1 :(得分:0)

我开发了一个名为MvcFlash的OSS项目,该项目完全符合您的要求并处理您想要的许多内容。你可以通过NuGet安装它,它很容易上手。

PM > Install-Package MvcFlash.Web

在代码中使用它就像这样简单。

// In your attribute
Flash.Error("Ooops", "There was an exception", id: "Exception")

在您看来:

@Html.Flash()

您在属性中需要 id 的原因是因为该属性可能会执行多次,因此您在调用flash时会多次看到该消息。设置 ID 会使邮件唯一。

以下是一些更多信息。

https://github.com/khalidabuhakmeh/MvcFlash2