views:

320

answers:

2

I'd like to be able to generate URLs from a RouteCollection without having access to the HttpContext. Looking at the way RouteCollection is implemented, all methods require access to a RequestContext in order to get the virtual path.

I've worked around this by mocking the HttpContext but this adds an awkward dependency on RhinoMocks and is not a reasonable solution. Do I have other options for generating Urls outside of context?

A: 

Sorry, but get used to mocking in the MVC framework. As soon as you get into testing, you're going to need it. There's so much there: HttpContext, Session, Server - all things that leak into your controller. If you want to generate the path, you either need to talk to the HttpContext (in MVC, this is actually HttpContextBase, so you can write your own concrete implementation I guess), or you need to mock it.

Jarrett Meyer
I'm not opposed to mocking for testing situations. However, I'm not doing this in a test. I'm generating emails via an asynchronous service. Since it's asynchronous there isn't access to an HttpRequest.
bromanko
Presumably an action is kicking off the process that generates emails. Try making the Routing call from within the action (when you have access to a RequestContext), then pass the result to whatever process generates the emails.
Levi
There are cases where emails are generated without the web trigerring them. For instance, daily emails or reminder emails.
bromanko
In these cases, I have set up specialty routes in my RouteData and hard-coded the routes in my emails. That way, I reference http://www.mysite.com/reset_password, and know that it's going to get routed correctly, no matter how that email got generated.
Jarrett Meyer
+1  A: 

A great question, indeed. Routing itself does have some dependencies on being called from a running ASP.NET application, such as getting the application root URL as well as any cookieless forms or session cookies that also go in the URL. While creating mock objects is a theoretical solution, it's certainly not recommended for used at runtime.

My recommendation is to not use routing at all for this situation and to hard code the URLs into the emails. Links in an email have to have fully qualified URLs (hostname + path) and routing can't even generate the hostname for the URL, so that's something that you'd already have to hardcode.

Eilon