【问题标题】:How to run a method in ASP.net MVC only once when application Load Without calling it from Application_Start()如何在应用程序加载时仅在 ASP.net MVC 中运行一次方法而不从 Application_Start() 调用它
【发布时间】:2015-11-30 06:35:27
【问题描述】:

我有一个 ASP.Net MVC Web 应用程序,在这个应用程序中我有 IP 检测工作,IP 检测方法大约需要 30 秒才能获得 IP,这很好。但是我只有 30 秒的时间来运行索引页面以及 IP 检测。意味着如果我调用 IP 检测,那么将没有时间加载索引。我正在从 Application_Start() 调用 IP 检测方法。但是当它运行时主页没有时间加载。 我想在自动加载应用程序后调用IP检测方法。如何可能请帮助。

我的IP检测方法为:

public void GetCityByIP()
        {
            abcEntities db = new abcEntities();
            string IPDetect = string.Empty;
            string APIKeyDetect = "Set API key";
            string city = "";
            string cityName = string.Empty;

            if (HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != null)
            {
                IPDetect = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString();
            }
            else if (HttpContext.Current.Request.UserHostAddress.Length != 0)
            {
                IPDetect = "192.206.151.131";
            }
            string urlDetect = string.Format("http://api.ipinfodb.com/v3/ip-city/?key={0}&ip={1}&format=json", APIKeyDetect, IPDetect);
            try
            {
                using (WebClient client = new WebClient())
                {
                    string json = client.DownloadString(urlDetect);
                    Location location = new JavaScriptSerializer().Deserialize<Location>(json);
                    List<Location> locations = new List<Location>();
                    locations.Add(location);
                    city = location.CityName;
                }
            }
            catch (WebException e)
            {
                city = "Toronto";
            }
            var getCityID = db.Macities.Where(c => c.CityName.Contains(city)).ToList();

            if ((getCityID != null) && (getCityID.Count > 0))
            {
                cityName = getCityID.FirstOrDefault().CityName;
            }
            else
            {
                getCityID = db.Macities.Where(c => c.CityName.Contains("Toronto")).ToList();
                cityName = getCityID.FirstOrDefault().CityName;
            }
            HttpContext.Current.Response.Cookies["CityName"].Value = cityName;
        }

我想设置 cookie 并将其用作整个应用程序中检测到的 IP 城市。我从 Start 方法中将其调用为:

 protected void Application_Start()
    {

        GetCityByIP();
    }

IP 检测方法也在全局文件中。我在数据库中有有限的城市,所以这就是为什么我使用数据库并匹配数据库城市中的城市(如果存在)然后 IP 方法设置在 cookie 中检测到的城市,其他明智的默认城市将在 cookie 中设置。 提前致谢。

【问题讨论】:

  • 您需要每个应用程序一次还是每个访问者一次?
  • 那么你有一个不同的问题。弄清楚为什么这需要 30 秒。你不能让用户等待。

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


【解决方案1】:

我不确定我是否真的了解您尝试执行操作的顺序,但您可以看看 Owin 和 Startup。

http://www.asp.net/aspnet/overview/owin-and-katana/owin-startup-class-detection

配置:

<appSettings>  
  <add key="owin:appStartup" value="StartupDemo.Startup" />
</appSettings>

代码:

using System;
using System.Threading.Tasks;
using Microsoft.Owin;
using Owin;
using System.IO;

[assembly: OwinStartup(typeof(StartupDemo.Startup))]

namespace StartupDemo
{
   public class Startup
   {
      public void Configuration(IAppBuilder app)
      {
         app.Use((context, next) =>
         {
            TextWriter output = context.Get<TextWriter>("host.TraceOutput");
            return next().ContinueWith(result =>
            {
               output.WriteLine("Scheme {0} : Method {1} : Path {2} : MS {3}",
               context.Request.Scheme, context.Request.Method, context.Request.Path, getTime());
            });
         });

         app.Run(async context =>
         {
            await context.Response.WriteAsync(getTime() + " My First OWIN App");
         });
      }

      string getTime()
      {
         return DateTime.Now.Millisecond.ToString();
      }
   }
}

您也可以使用 Task.Run 来异步运行它。

    return TaskEx.Run(() =>
    {

            try
            {
                // Do some time-consuming task.
            }
            catch (Exception ex)
            {
                // Log error.
            }

    });

问题更新后编辑:

因为它应该只为每个访问者运行一次,所以将它放在 Session Start 比 Application Start 更合理。如上所述,请勿使用 Owin,因为它仅在应用启动时运行。

Asp.Net MVC OnSessionStart event

void Session_Start(object sender, EventArgs e) {
  // your code here, it will be executed upon session start
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-09
    • 2010-11-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-14
    相关资源
    最近更新 更多