在我目前的项目中,我们有一个通知系统。将oject添加到另一个对象集合时,会向发送给父对象的那些人发送一封电子邮件。这发生在对象层而不是视图或控制器中。
问题在于:
虽然我们可以说谁在电子邮件中创建了什么信息,但是我们无法在电子邮件中嵌入这些对象的链接,因为在对象层中无法访问UrlHelper
。要构建UrlHelper
,您需要RequestContext
,这在对象图层上也不存在。
问题:
我想创建一个帮助类来为我创建url。如何在没有请求上下文的情况下创建将生成这些URL的对象?可能吗?
答案 0 :(得分:2)
由于您不希望在电子邮件中使用相对URL,因此您需要绝对电子邮件,因此您需要对域进行硬编码,因为没有请求从中获取它,这一问题更加复杂。
另一个因素是,电子邮件可以比数月或数年更长时间,因此您需要一种固定链接,因此可以将多个Url与单个操作(其他路由)相关联。后一个问题也是SEO的一个因素,你不想留下任何页面。
现在,位于方法UrlToActionX(params)
旁边的控制器ActionX
上的静态方法似乎是最简单的解决方法。它所做的就是在强类型参数的id上生成永久Url的相应string.Format(...)。在正面添加静态域,或从用户对象添加域(因为您知道他们访问您的网站时访问了哪个域)并且您有电子邮件链接。
这不是理想的,但至少你现在只有一个地方可以维持Url一代。
恕我直言:当涉及到不断变化的网站的永久链接时,最好依靠“超过惯例的配置”。: - )
答案 1 :(得分:1)
我不知道如何做到这一点,你必须至少可以访问这些路线来制作自己的帮手。除非您的业务对象知道已注册的路由,否则您无法远离做一些硬编码。
以下是您如何限制网址的硬编码...
在对象的方法中包含所有相关位的网址中的代码..
class Event
{
public void SendEmail()
{
var url = string.Format("http://myurl.com/r/Event?eventId={0}", EventId);
//send emails...
}
}
请注意网址的/r/Event
段。这将是RController
的映射,它将负责获取任意组成的链接并发送301 Permanent Redirect
并通过路由引擎使用当前路由创建真实URL。这样,您只需对实用程序控制器URL进行硬编码,而不是对真实页面不断发展的控制器操作进行编码。
class RController : Controller
{
public ActionResult Event(int eventId)
{
Response.StatusCode = (int)HttpStatusCode.MovedPermanently;
Response.RedirectLocation = Url.Action("Details", "Event", new { eventId = eventId });
return null;
}
public ActionResult Register(int eventId)
{
Response.StatusCode = (int)HttpStatusCode.MovedPermanently;
Response.RedirectLocation = Url.Action("Register", "Event", new { eventId = eventId });
return null;
}
}
它只是比硬编码一堆您可能决定稍后重命名的不同控制器/操作感觉好一点。把它想象成你自己的小TinyUrl服务。
答案 2 :(得分:0)
您可以使用一种方法定义一个接口,该方法可以获取创建URL(对象ID或其他)所需的任何信息并返回一个URL。编写使用UrlHelper完成此工作的接口的实现,然后将其提供给对象层(理想情况下使用IoC容器)。
答案 3 :(得分:0)
您可以使用:
VirtualPathUtility.ToAbsolute(string.Format("~/r/Event?eventId={0}", id))
解析网址。虽然还不好看。