从服务调用的MVC UrlHelper [英] MVC UrlHelper called from Service

查看:149
本文介绍了从服务调用的MVC UrlHelper的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个静态类,该类发送包含指向我网站某些页面的链接的电子邮件.该链接是通过以下代码动态生成的:

I have a static class that sends emails with links to certain pages of my site. That link is getting dynamically generated with this code:

UrlHelper urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);
string url = urlHelper.Action("Details", "Product", new { id = ticketId }, "http");

问题是我现在还拥有一项服务,该服务会定期将创建日期与当前日期进行比较,并自动发送这些邮件.代码当然崩溃了,并说HttpContext.Current为空(因为它不是请求).

The problem is I now also have a service that periodically compares the creation date with the current date and sends those mails automatically. The code crashes of course and says HttpContext.Current is null (because it ain't a request).

我尝试了一些类似的事情:

I tried some things like that:

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;
    }
}

但是当我第二次需要UrlHelper的RequestContext时,Action崩溃并显示Null Reference Exception.

But when I need RequestContext the second time for the UrlHelper.Action crashes saying Null Reference Exception.

通过服务调用邮件方法时,我无法以某种方式保存/记住/传递UrlHelper或HttpContext来进行访问.

I failed to somehow save/remember/pass the UrlHelper or the HttpContext to have access when calling the mail method over my service.

推荐答案

感谢您的所有帮助.在我的情况下,预定义URL是没有选择的.我或多或少地找到了解决我问题的方法.我知道它可能不是最漂亮的代码,但是它工作得很好,而且似乎没有人有更好的代码,所以请不要投反对票.

Thanks for all your help. Predefining the URL was no option in my case. I found more or less a solution for my problem. I know it might not be the most beautiful code but it works quite well and noone seems to have a better one, so no downvotes please.

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方法来调用FirstRequestInitialisation类.这绝不是问题,因为上下文是在Application_BeginRequest中已知的(与Application_Start不同).初始化方法要注意,线程仍只被调用一次并具有锁,因此它永远不会崩溃. 我取消了我的服务,因为我无法真正与之通信,而是决定从中创建一个线程.在此初始化方法中,我以主机为参数调用类构造函数EscalationThread.在此构造函数中,我创建并启动一直运行的线程.

Explaination what happens: On each and every request the FirstRequestInitialisation class gets called with the method Initialise with the context as parameter. This is never a problem because the context is known in a Application_BeginRequest (not like in Application_Start). The Initialise Method takes care that still the Thread is just called once and has a lock so that it will never crash. I eliminated my Service because I can't really communicate with it and instead I decided to make a Thread out of it. In this Initialise Method I call a class constructor EscalationThread with the host as parameter. In this constructor I create and start the thread that just keeps running.

我仍然没有HttpContext,也不能使用UrlHelper,但是我有主机,可以执行以下操作:string urlInMail = this.host + string.Format("/{0}/{1}/{2}", "Product", "Details", product.Id);

I still don't have HttpContext and can't use the UrlHelper BUT I have the host and can do stuff like: string urlInMail = this.host + string.Format("/{0}/{1}/{2}", "Product", "Details", product.Id);

这篇关于从服务调用的MVC UrlHelper的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆