MVC UrlHelper called from Service

两盒软妹~` 提交于 2019-12-23 03:25:15

问题


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");

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

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

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


回答1:


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.

In global.asax.cs I added this class:

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

And I added this:

void Application_BeginRequest(Object source, EventArgs e)
{
    FirstRequestInitialisation.Initialise(((HttpApplication)source).Context);
}

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.

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



来源:https://stackoverflow.com/questions/18151014/mvc-urlhelper-called-from-service

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!