Is there a way to generate URLs using WebAPI?

BELOW REPORT

We cannot understand why it UrlHelperreturns null strings when using the WebApi controller from the context.

We did the required debugging, but we can’t understand why this is happening, RouteData has routes, but it does not seem to work.

For the most part, we use the RenderViewToString function, which loads views consisting of calls Url.RouteUrl(routeName).

Something that has been tried is creating a custom UrlHelper (but to no avail) and debugging using UrlHelper (MVC / HTTP).

Attribute routing is used everywhere with route names.

Example usage 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
               }));
        }
   }

BaseApiController Class:

 public class BaseApiController : ApiController
    {
        public static string RenderViewToString(string controllerName, string viewName)
        {
            return RenderViewToString(controllerName, viewName, new Dictionary<string, object>());
        }

        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<string, Object> 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()
            {
            }
        }
    }

EDIT

, , . RouteData MVC, API- .

 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;
            }
        }
    }
+4
4

UrlHelper, RouteTable URL- .

public static class Link
{
    public static string RouteUrl(string routeName, object routeValues = null)
    {
        var url = String.Empty;
        try
        {
            var route = (Route)RouteTable.Routes[routeName];
            if (route == null)
                return url;

            url = "~/".AbsoluteUrl() + route.Url;
            url = url.Replace("{culture}", System.Threading.Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName.ToLower());

            if (routeValues == null) 
                return url;

            var values =  routeValues.GetType().GetProperties();
            Array.ForEach(values, pi => url = Regex.Replace(url, "{" + pi.Name + "}", pi.GetValue(routeValues, null).ToString()));

            return url;
        }
        catch
        {
            var newUrl = RouteUrl("403");
            if(newUrl == String.Empty)
                throw;

            return newUrl;
        }
    }

    public static string HttpRouteUrl(string routeName, object routeValues = null)
    {
       return RouteUrl(routeName, routeValues);
    }
}
+3

Uri.Link( , )

var uri = Url.Link("api.cart.get.checkout", new { id = 1 });

, .

+1

WebApi - MVC. , .

UrlHelper ( MVC) MVC WebApi.

, .: - (

+1

, , Url.RouteUrl(string routeName, object routeValues = null) Url.HttpRouteUrl(string routeName, object routeValues = null) MVC layout.cshtml.

, Url.IsWebApiRequest() false, layout.cshtml MVC, WebAPI. URL- MVC WebAPI.

Url , RouteUrl URL- WebAPI, HttpRouteUrl MVC-url, , , URL- .

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
        {
            var helper = new System.Web.Http.Routing.UrlHelper();
            return helper.Link(routeName, routeValues);             
        }
        catch
        {
            return url;
        }
    }

    public static string HttpRouteUrl(string routeName, object routeValues = null)
    {
        var url = String.Empty;
        try
        {
            var helper = new System.Web.Mvc.UrlHelper();
            return helper.HttpRouteUrl(routeName, routeValues);
        }
        catch
        {
            return url;
        }
    }
}
+1
source

Source: https://habr.com/ru/post/1615707/


All Articles