title: Is there a way to generate Urls with WebAPI?
body: <p><strong>POST EDITED BELOW</strong></p>
  
  <p>We can't figure out why <code>UrlHelper</code> is returning null strings when used from the WebApi controller's context.</p>
  
  <p>We've done the neccesary debugging but we can't find out why this happens, the RouteData has the routes in it but it doesn't seem to be working.</p>
  
  <p>For the most part, we use a RenderViewToString function, which loads views that consist of calls to <code>Url.RouteUrl(routeName)</code>.</p>
  
  <p>Something that's been tried is creating a custom UrlHelper (but to no avail) and debugging with either UrlHelper's (MVC / HTTP).</p>
  
  <p>Attribute routing is used everywhere with route names.</p>
  
  <p>Example usage code:</p>
  
  <pre><code>    public class WebApiController : BaseApiController
      {
          [HttpPost]
          [ResponseType(typeof(string))]
          [Route("cart/get/checkout", Name = "api.cart.get.checkout")]
          public IHttpActionResult GetCheckOutShoppingCart([FromBody] string data)
          {
                 return Ok(RenderViewToString("CartController", "_CheckOutCartPartial", new ShoppingCartModel(Auth.IsAuthenticated ? Auth.GetCustomer().DefaultShippingInfo.CountryId : 148)
                 {
                     AddInsurance = false,
                     InsuredShipping = insuredShipping,
                     CurrentDeliveryMethodId = deliveryMethodId,
                     CurrentPaymentMethodId = paymentMethodId
                 }));
          }
     }
  </code></pre>
  
  <p>BaseApiController class:</p>
  
  <pre><code> public class BaseApiController : ApiController
      {
          public static string RenderViewToString(string controllerName, string viewName)
          {
              return RenderViewToString(controllerName, viewName, new Dictionary&lt;string, object&gt;());
          }
  
          public static string RenderViewToString(string controllerName, string viewName, object model)
          {
              using (var writer = new StringWriter())
              {
                  var routeData = new RouteData();
                  routeData.Values.Add("controller", controllerName);
                  var fakeControllerContext =
                      new ControllerContext(
                          new HttpContextWrapper(new HttpContext(new HttpRequest(null, "http://google.com", null),
                              new HttpResponse(null))), routeData, new FakeController());
                  var razorViewEngine = new RazorViewEngine();
                  var razorViewResult = razorViewEngine.FindView(fakeControllerContext, viewName, "", false);
                  var viewContext = new ViewContext(fakeControllerContext, razorViewResult.View,
                      new ViewDataDictionary(model), new TempDataDictionary(), writer);
                  razorViewResult.View.Render(viewContext, writer);
                  return writer.ToString();
              }
          }
  
          public static string RenderViewToString(string controllerName, string viewName, Dictionary&lt;string, Object&gt; data)
          {
              using (var writer = new StringWriter())
              {
                  var viewData = new ViewDataDictionary();
                  foreach (var kv in data)
                  {
                      viewData[kv.Key] = kv.Value;
                  }
  
                  var routeData = new RouteData();
                  routeData.Values.Add("controller", controllerName);
                  var fakeControllerContext =
                      new ControllerContext(
                          new HttpContextWrapper(new HttpContext(new HttpRequest(null, "http://google.com", null),
                              new HttpResponse(null))), routeData, new FakeController());
                  var razorViewEngine = new RazorViewEngine();
                  var razorViewResult = razorViewEngine.FindView(fakeControllerContext, viewName, "", false);
                  var viewContext = new ViewContext(fakeControllerContext, razorViewResult.View, viewData,
                      new TempDataDictionary(), writer);
                  razorViewResult.View.Render(viewContext, writer);
                  return writer.ToString();
              }
          }
  
          private class FakeController : ControllerBase
          {
              protected override void ExecuteCore()
              {
              }
          }
      }
  </code></pre>
  
  <p><strong>EDIT</strong></p>
  
  <p>We've put together a class that should in theory work, but it doesn't.
  The RouteData has both the MVC and API routes in the collection.</p>
  
  <pre><code> public static class Url
      {
          public static bool IsWebApiRequest()
          {
              return
                  HttpContext.Current.Request.RequestContext.HttpContext.CurrentHandler is
                      System.Web.Http.WebHost.HttpControllerHandler;
          }
  
          public static string RouteUrl(string routeName, object routeValues = null)
          {
              var url = String.Empty;
              try
              {
                  if (IsWebApiRequest())
                  {
                      var helper = new System.Web.Http.Routing.UrlHelper();
                      url = helper.Link(routeName, routeValues);             
                  }
                  else
                  {
                      var helper = new System.Web.Mvc.UrlHelper();
                      url = helper.RouteUrl(routeName, routeValues);              
                  }
  
                  return url;
              }
              catch
              {
                  return url;
              }
          }
  
          public static string HttpRouteUrl(string routeName, object routeValues = null)
          {
              var url = String.Empty;
              try
              {
                  if (IsWebApiRequest())
                  {
                      var helper = new System.Web.Http.Routing.UrlHelper();
                      url = helper.Link(routeName, routeValues);
                  }
                  else
                  {
                      var helper = new System.Web.Mvc.UrlHelper();
                      url = helper.HttpRouteUrl(routeName, routeValues);
                  }
  
                  return url;
              }
              catch
              {
                  return url;
              }
          }
      }
  </code></pre>