ASP.NET MVC: 如何创建可用的UrlHelper实例?

17

我正在使用quartz.net在asp.net mvc应用程序中安排定期事件。

计划的作业应该调用一个服务层脚本,该脚本需要一个UrlHelper实例(用于基于正确路由创建链接(通过urlHelper.Action(..)),这些链接包含服务发送的电子邮件)。

我不想在电子邮件中硬编码链接-它们应该使用urlhelper解析。

这个工作:

public class EvaluateRequestsJob : Quartz.IJob
{
    public void Execute(JobExecutionContext context)
    {
        //  where to get a usable urlHelper instance?
        ServiceFactory.GetRequestService(urlHelper).RunEvaluation();
    }
}
请注意,此代码不在MVC管道中运行。当前没有正在服务的请求,代码将在Quartz计划程序定义的时间运行。

我该如何获得一个可在指定位置使用的UrlHelper实例?

如果无法构建UrlHelper,则我看到的另一个选项是通过执行HTTP请求使作业“自调用”控制器操作 - 在执行操作时,我当然会有一个可用的UrlHelper实例 - 但这似乎有点hacky。


1
哇,这个帖子上的负面投票真是飞快啊 :) - Kelsey
可能是因为问题似乎太琐碎了,所以人们倾向于给出琐碎或无关的答案,或者该问题需要至少对不太知名的框架(quartz)有基本的了解。 - Marek
这个Quartz调度器是否使用类似Jeff在以下帖子中介绍的方法:http://blog.stackoverflow.com/2008/07/easy-background-tasks-in-aspnet/? - Kelsey
到目前为止,大多数答案存在的问题是它们假设石英任务将在用户请求中运行,而实际上不会这样。像HttpContext.Current这样的东西就不能正常工作。这个问题类似于缓存过期事件(它们也不作为用户请求的一部分运行)。 - Duncan
可能是在ASP.NET MVC中在模型中调用UrlHelper的重复问题。 - Sheridan
4个回答

7

可以尝试按照这个答案中的方法,为UrlHelper创建一个新的HttpContext:


与此同时,我使用了不同的方法,但这个似乎可以工作,即使它有点繁琐。感谢您找到答案 :) - Marek
@Marek - 你是怎么解决你的问题的?我也遇到了类似的问题,我需要HttpContext来渲染视图,因为我使用该视图在quartz完成后发送电子邮件。 - chobo2
@chobo - 我最终创建了一个外部应用程序,执行周期性的 HTTP 请求,并在控制器操作中实现了逻辑。 - Marek
这不应该是一种可接受的回答。手动创建HttpContext并考虑到您现在需要使用硬编码的url。我想使用UrlHelper获取主机,这可以是动态的。因此,这种方式行不通。 - liqSTAR

2

编辑:很抱歉,我完全误读了问题。

看起来你的调度程序(我不知道它是如何工作的)是一个单独的进程,你想要UrlHelper帮助在你的MVC应用程序中生成有效的URL?

你可以尝试在你的MVC应用程序中编写一个处理程序,该处理程序将在你的应用程序上下文中运行,为你构建URL并返回它。然后你可以从你的调度程序中调用这个处理程序,根据传递的参数获取任何你需要的URL。这样,你的调度程序只需要知道你的MVC应用程序的查询URL在哪里,然后可以要求它为你执行Url映射。

希望这个答案更好一些。如果我完全错了,请让我知道……本来想删除我的回复,但想再试一次。


谢谢,只有一个“硬编码”的众所周知的URL提供所需的路由映射的想法很有趣 - 即使它等同于调用将通过HTTP请求触发评估服务的操作。现在取消我的反对票 :) - Marek
是的,我想不到其他方法来解决这个问题,因为你的MVC应用程序确实是唯一可以访问所需上下文的东西。这是一个有趣的问题,我一直在使用配置文件中的硬编码URL来解决它,其中我留下{0}参数以根据ID进行替换。从未喜欢过这个解决方案,所以我很想看看是否有更好的方法来解决它。 - Kelsey
请注意,此代码仍在MVC应用程序中运行 - 但不提供任何请求。如果我能捕获任何请求并将UrlHelper实例存储到已知位置,问题就可以解决(是的,这听起来很糟糕)。 - Marek
这个答案听起来足够合理。如果在计时器到期时,你只需调用自己应用程序上的某个URL,该URL将构建并返回你正在寻找的已构建URL。 - p.campbell

0

使用UrlHelper.Action方法时,请记得指定协议参数,这将生成绝对URL。例如:

url.Action("Action", "Controller", null, "http")

或者

url.Action("Action", "Controller", null, request.Url.Scheme)

-2

你需要一个RequestContext来创建一个UrlHelper。在我的HtmlHelper扩展方法中,我是这样做的:

public static string ScriptUrl(this HtmlHelper html, string script)
{
    var url = new UrlHelper(html.ViewContext.RequestContext);
    ...
}

如何获取RequestContext取决于您的应用程序。


请问我该如何在我所发布的示例中获取HttpContext?问题似乎与我的原始问题相同 - 我不在MVC请求处理管道内,调度作业是由Quartz调度程序调用的。 - Marek
在MVC管道之外,我不确定。你可能需要手动设置路由等内容,因为框架不会为你完成任何操作。这可能是可行的,但听起来并不值得麻烦。 - Gabe Moothart

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接