如何在应用程序加载时只在ASP.net MVC中运行一次方法而不从Application_Start()调用它

时间:2015-09-04 07:22:10

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

我有一个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中设置。 提前致谢。

2 个答案:

答案 0 :(得分:0)

我不确定我是否真的理解你在尝试做什么的顺序,但是你可以看看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,因为它只在app start上运行。

Asp.Net MVC OnSessionStart event

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

答案 1 :(得分:-1)

是否必须同步?

为什么不从App_Start异步调用IP检测方法并继续加载索引页。

如果由于某种原因无法使用Async,请使用后台线程!

如果您使用的是Azure(不确定AWS是否有类似的东西),您可以使用启动任务。

https://msdn.microsoft.com/en-us/library/azure/hh180155.aspx