从服务调用MVC UrlHelper
本文关键字:UrlHelper MVC 调用 服务 | 更新日期: 2023-09-27 18:27:07
我有一个静态类,它发送带有指向我的网站某些页面链接的电子邮件。这个链接是用这个代码动态生成的:
UrlHelper urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);
string url = urlHelper.Action("Details", "Product", new { id = ticketId }, "http");
问题是,我现在还有一个服务,它定期比较创建日期和当前日期,并自动发送这些邮件。代码当然崩溃了,并说HttpContext.Current
为null(因为它不是一个请求)。
我试过一些类似的东西:
private static System.Web.Routing.RequestContext requestContext;
private static System.Web.Routing.RequestContext RequestContext {
get
{
if(requestContext == null)
requestContext = HttpContext.Current.Request.RequestContext;
return requestContext;
}
}
但当我第二次需要RequestContext来处理UrlHelper.Action时,会崩溃,并显示Null引用异常。
在通过服务调用邮件方法时,我未能以某种方式保存/记住/传递UrlHelper或HttpContext以获得访问权限。
感谢您的帮助。在我的情况下,预定义URL是没有选择的。我或多或少找到了解决问题的办法。我知道这可能不是最漂亮的代码,但它运行得很好,似乎没有人有更好的代码,所以请不要投反对票。
在global.asax.cs中,我添加了这个类:
class FirstRequestInitialisation
{
private static string host = null;
private static Object s_lock = new Object();
// Initialise only on the first request
public static void Initialise(HttpContext context)
{
if (string.IsNullOrEmpty(host))
{ //host isn't set so this is first request
lock (s_lock)
{ //no race condition
if (string.IsNullOrEmpty(host))
{
Uri uri = HttpContext.Current.Request.Url;
host = uri.Scheme + Uri.SchemeDelimiter + uri.Host + ":" + uri.Port;
//open EscalationThread class constructor that starts anonymous thread that keeps running.
//Constructor saves host into a property to remember and use it.
EscalationThread et = new EscalationThread(host);
}
}
}
}
}
我添加了这个:
void Application_BeginRequest(Object source, EventArgs e)
{
FirstRequestInitialisation.Initialise(((HttpApplication)source).Context);
}
解释发生了什么:对于每个请求,都会使用Initialize方法调用FirstRequestInitialization类,并将上下文作为参数。这从来都不是问题,因为上下文在Application_BeginRequest中是已知的(不像Application_Start中那样)。Initialize方法注意线程仍然只被调用一次,并且有一个锁,这样它就永远不会崩溃。我取消了我的服务,因为我不能真正与它通信,相反,我决定用它创建一个线程。在这个Initialize方法中,我调用了一个类构造函数EscalationThread,并将主机作为参数。在这个构造函数中,我创建并启动了保持运行的线程。
我仍然没有HttpContext,也不能使用UrlHelper,但我有主机,可以做一些事情,比如:string urlInMail = this.host + string.Format("/{0}/{1}/{2}", "Product", "Details", product.Id);