2010-05-21 114 views
1

在我目前的项目中,我们有一个通知系统。当一个对象被添加到另一个对象集合中时,电子邮件被发送给那些被父对象所子集的对象。这发生在对象层而不是视图或控制器中。MVC路由 - 如何获取URL?

这里的问题:

虽然我们不能说谁什么跟什么信息在电子邮件中,我们不能嵌入链接到邮件的对象创建的,因为对象层中有一个UrlHelper进不去。要构建一个UrlHelper,您需要一个RequestContext,它在对象层上也不存在。

问:

我想打一个辅助类来创建网址的我。我如何创建一个没有请求上下文就会生成这些url的对象?可能吗?

+0

我目前正在研究asolution,我将一个函数传递给生成url的对象。完成后,我会发布我的解决方案。 感谢伟大的想法! – 2010-05-21 20:04:22

回答

0

您可以定义与需要的任何信息,需要创建一个URL(对象ID或其他),并返回一个URL的方法的接口。编写一个使用UrlHelper执行此工作的接口的实现,然后将其提供给对象层(理想情况下使用IoC容器)。

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进行硬编码,而不是对真实页面的不断发展的控制器操作。

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

的问题是事实,你不希望在电子邮件中的相对URL复合,你想要一个绝对的电子邮件,所以你需要硬编码的域名也因为没有发出请求,抓住它。

另一个因素是,电子邮件可以在几个月或几年内超过当前网站结构,因此您需要一种永久链接,从而将多个网址与单个操作(附加路线)相关联。后一个问题也是SEO中的一个因素,您不想留下任何页面。

现在,您的控制器上的静态方法UrlToActionX(params)坐在方法ActionX旁边似乎是最简单的解决方法。它所做的只是在强类型参数的id上使用适当的string.Format(...)来生成永久Url。在用户对象的前端或域中添加一个静态域(因为您知道他们访问您的网站时访问哪个域),并且您有电子邮件链接。

这并不理想,但至少您现在只有一个地方来维护Url的生成。

恕我直言:当涉及到不断变化的网站的永久链接有时候最好依靠“配置超过约定”。 :-)

+0

我已经确定了域问题。这部分很容易。 – 2010-05-21 20:02:54

0

你可以使用:

VirtualPathUtility.ToAbsolute(string.Format("~/r/Event?eventId={0}", id)) 

解析URL。尽管如此,仍然不好。