【问题标题】:MVC Routes - How to get a URL?MVC 路由 - 如何获取 URL?
【发布时间】:2011-02-22 11:07:49
【问题描述】:

在我当前的项目中,我们有一个通知系统。当一个对象被添加到另一个对象集合中时,会向订阅了父对象的人发送一封电子邮件。这发生在对象层而不是视图或控制器中。

问题来了:

虽然我们可以在电子邮件中说明谁用什么信息创建了什么,但我们不能在电子邮件中嵌入指向这些对象的链接,因为在对象层中无法访问UrlHelper。要构造一个UrlHelper,您需要一个RequestContext,它在对象层上同样不存在。

问题:

我想创建一个帮助类来为我创建 url。如何在没有请求上下文的情况下创建一个可以生成这些 url 的对象?可能吗?

【问题讨论】:

  • 我目前正在研究解决方案,我将一个函数传递给生成 url 的对象。完成后,我将发布我的解决方案。感谢伟大的想法!

标签: c# asp.net-mvc url


【解决方案1】:

由于您不希望电子邮件中的相对 URL,您需要绝对电子邮件,因此问题更加复杂,因此您也需要对域进行硬编码,因为没有请求从中获取它。

另一个因素是电子邮件可能比当前的站点结构寿命长几个月或几年,因此您需要一种永久链接,因此需要一种将多个 URL 与单个操作(附加路由)相关联的方法。后一个问题也是 SEO 中您不想留下任何页面的一个因素。

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

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

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

【讨论】:

  • 我实际上已经解决了域问题。那部分很简单。
【解决方案2】:

我不知道有什么方法可以做到这一点,您至少必须有权访问这些路线才能制作自己的助手。除非您的业务对象知道已注册的路由,否则您无法摆脱一些硬编码。

以下是您可以如何限制 url 的硬编码...

在你的对象方法中包含所有相关位的 url 中的代码..

    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 之类的服务。

【讨论】:

    【解决方案3】:

    您可以使用方法定义接口,该方法获取创建 URL 所需的任何信息(对象 ID 或其他)并返回 URL。编写该接口的实现,使用 UrlHelper 完成这项工作,然后将其提供给您的对象层(最好使用 IoC 容器)。

    【讨论】:

      【解决方案4】:

      你可以使用:

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

      解析网址。不过还是不太好。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-02-22
        • 1970-01-01
        • 1970-01-01
        • 2011-07-02
        • 2018-05-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多