ASP.NET MVC “Кэширование пончика” и TempData

Кажется, что Java не может обрабатывать слишком большое число, например, int или long, поэтому обрабатываете как string и используете свойство length для обработки и разбора на int или long.

Примечание: если длина строки слишком велика, чем может поддерживать целое или длинное, используйте функцию возврата или любую функцию обратного вызова.

Диапазон переменных Java: -

enter image description here

5
задан Jeff Atwood 4 November 2009 в 13:49
поделиться

1 ответ

Я нашел решение:

Основная идея находится в сохранении копии TempData в Кэше и получении его по каждому запросу. Решением является комбинация пользовательского TempDataProvider и простого http модуля. Плюс существует несколько помощников и статических классов.

Вот код:

CustomTempDataProvider:

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Caching;
using System.Web.Mvc;

public class CustomTempDataProvider : SessionStateTempDataProvider, IHttpModule
{
    public void Init(HttpApplication application)
    {
        application.BeginRequest += new EventHandler(application_BeginRequest);
    }

    void application_BeginRequest(object sender, EventArgs e)
    {
        var httpContext = HttpContext.Current;
        var tempData = httpContext.Cache[TempDataKey] ?? new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
        httpContext.Items.Add("TempData", tempData);
        httpContext.Cache.Remove(TempDataKey);
    }

    public override void SaveTempData(ControllerContext controllerContext,
        IDictionary<string, object> values)
    {
        HttpContext.Current.Cache.Insert(TempDataKey, values, null, DateTime.Now.AddMinutes(5), Cache.NoSlidingExpiration, CacheItemPriority.NotRemovable, null);
        base.SaveTempData(controllerContext, values);
    }

    public static string TempDataKey
    {
        get
        {
            string sessionID = "0";
            var httpContext = HttpContext.Current;
            if(httpContext.Session != null)
            {
                sessionID = httpContext.Session.SessionID;
            }
            else if (httpContext.Request.Cookies["ASP.NET_SessionId"] != null)
            {
                sessionID = httpContext.Request.Cookies["ASP.NET_SessionId"].Value;
            }
            return "TempData-For-Session-" + sessionID;
        }
    }

    public void Dispose()
    {
    }
}

Зарегистрируйте его в web.config:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.web>
        <httpModules>
            <add name="CustomTempDataProvider" type="CustomTempDataProvider" />
        </httpModules>
    </system.web>
    <system.webServer>
        <modules>
            <remove name="CustomTempDataProvider" />
            <add name="CustomTempDataProvider" type="CustomTempDataProvider" />
        </modules>
    </system.webServer>
</configuration>

CustomControllerFactory:

using System.Web.Routing;
using System.Web.Mvc;

public class CustomControllerFactory : DefaultControllerFactory
{
    public override IController CreateController(
        RequestContext requestContext, string controllerName)
    {
        var controller = (Controller)base.CreateController(requestContext, controllerName);
        controller.TempDataProvider = new CustomTempDataProvider();
        return controller;
    }
}

зарегистрируйте его в Global.asax:

protected void Application_Start()
{
    RegisterRoutes(RouteTable.Routes);

    ControllerBuilder.Current.SetControllerFactory(typeof(CustomControllerFactory));
}

Статический класс для доступа к TempData:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

public static class CustomTempData
{
    public static object Get(string key)
    {
        var tempData = HttpContext.Current.Items["TempData"] as IDictionary<string, object>;
        var item = tempData.FirstOrDefault(x => x.Key == key).Value ?? String.Empty;
        return item;
    }
}

Помощник для замены посткэша:

using System;
using System.Web;
using System.Web.Mvc;

public static class Html
{
    public delegate object MvcResponseSubstitutionCallback(HttpContextBase context);

    public static object MvcResponseSubstitute(this HtmlHelper html, MvcResponseSubstitutionCallback callback)
    {
        html.ViewContext.HttpContext.Response.WriteSubstitution(
            context =>
                HttpUtility.HtmlEncode(
                    (callback(new HttpContextWrapper(context)) ?? String.Empty).ToString()
                )
            );

        return null;
    }
}

Теперь это работает успешно:

<h3><%= Html.MvcResponseSubstitute(context => CustomTempData.Get("message")) %></h3>

Если Вы понимаете русский язык, считайте это

Надеюсь, это поможет

5
ответ дан 14 December 2019 в 19:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: