¿Cómo crear una URL de API web ASP.NET?

120

En ASP.NET MVC, tenemos @Url.Actionacciones. ¿Hay algo similar como @Url.Apique se enrutaría a / api / controller?

Shane Courtrille
fuente

Respuestas:

139

El ApiController tiene una propiedad llamada Url que es de tipo System.Web.Http.Routing.UrlHelper que le permite construir URL para controladores api.

Ejemplo:

public class ValuesController : ApiController
{
    // GET /api/values
    public IEnumerable<string> Get()
    {
        // returns /api/values/123
        string url = Url.Route("DefaultApi", new { controller = "values", id = "123" });
        return new string[] { "value1", "value2" };
    }

    // GET /api/values/5
    public string Get(int id)
    {
        return "value";
    }

    ...
}

Este UrlHelper no existe ni en sus vistas ni en los controladores estándar.


ACTUALIZAR:

Y para hacer el enrutamiento fuera de un ApiController, puede hacer lo siguiente:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        string url = Url.RouteUrl(
            "DefaultApi", 
            new { httproute = "", controller = "values", id = "123" }
        );
        return View();
    }
}

o dentro de una vista:

<script type="text/javascript">
    var url = '@Url.RouteUrl("DefaultApi", new { httproute = "", controller = "values", id = "123" })';
    $.ajax({
       url: url,
       type: 'GET',
       success: function(result) {
           // ...
       }
    });
</script>

Observe el httproute = ""token de ruta que es importante.

Obviamente, esto supone que se llama DefaultApia su ruta Api en su método RegisterRoutes en Global.asax:

routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);
Darin Dimitrov
fuente
Eso ... realmente no me ayuda mucho ya que necesito mi Vista para poder generar Urls de una manera segura. Si hay una licencia de Go Live, ¿cuál es la forma 'Go Live' de crear URL en la Vista?
Shane Courtrille
Más importante aún, esto no funcionará si está utilizando ASP.Net Development Server, ya que cambia los puertos todo el tiempo, por lo que ni siquiera puede modificar la URL en la vista.
Shane Courtrille
@ShaneCourtrille, actualicé mi respuesta para ilustrar cómo podría usar lo normal System.Web.Mvc.UrlHelperpara generar rutas Api fuera de un HttpControllerContext.
Darin Dimitrov
¡Muchas gracias! Estaba tratando de usar RouteUrl pero no sabía sobre el requisito de parámetro httproute.
Shane Courtrille
2
Entiendo el propósito de la muestra; Estoy diciendo que sería una muestra más útil si agregara una línea de código ViewBag porque estaría demostrando que este valor es lo que estamos tratando de obtener en un escenario probable y no solo ejecutando un código arbitrario. Una vez más, no habría comentado si no hubiera perdido un par de minutos sin darme cuenta de lo que me perdí antes de finalmente reconocer que la línea de código en particular era la relevante.
Jon Davis
43

Funciona con la forma más simple de, Url.Actionpor lo tanto, no tiene que hacer referencia a ningún nombre de enrutamiento:

Url.Action("ActionName", "ControllerName", new { httproute = "DefaultApi" })

Es posible que desee agregar un area = ""si la URL es necesaria dentro de un área. (Los controladores de API están fuera de las áreas de forma predeterminada). Estoy usando MVC 4.

Gábor Imre
fuente
7
El UrlHelper en Web Api es msdn.microsoft.com/en-us/library/… , no tiene un método de acción.
Yuriy Faktorovich
8
@YuriyFaktorovich Esta publicación implica que Url.Actionse está utilizando desde una Vista. Urles de tipo System.Web.Mvc.UrlHelpery no se asigna a WebApirutas. Esta es la razón por lo que necesita el parámetro adicional: new { httproute = "" }.
Jesse
3
Agregué httproute""pero no es mapeo = /
Maslow
Tuve que agregar el enlace con un área en blanco y htmlAttributes nulos, @Html.ActionLink("link", "Get", "Servers", new { id = r.idServer, area = "", httproute = "" }, null) pero eso funcionó perfectamente
Christopher G. Lewis
2
Esto funciona perfectamente desde una vista, sin embargo, no estoy seguro de por qué genera el nombre de la acción como una cadena de consulta como: / api / dashboard? Action = getdata. Esperaba esto: / api / dashboard / getdata
umutesen
7

¿Quiere poder generar enlaces de forma segura, sin cadenas codificadas (nombres de controlador)?

¡Hay un nuget para eso! (y está escrito por Mark Seeman)

https://github.com/ploeh/Hyprlinkr

Funciona así:

Rutas, como de costumbre:

name: "API Default",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }

Obtener una URL:

var linker = new RouteLinker(request);
var uri = linker.GetUri<FooController>(r => r.GetById(1337));

Resultado:

http://localhost/api/foo/1337
Cristian Diaconescu
fuente
3

Aquí está el método KISS para responder la pregunta:

Si este es el código que usaría para crear una URL de controlador MVC

@Url.Action("Edit", "MyController")

Para obtener una URL para la versión API del controlador (suponiendo que use el mismo nombre de controlador) puede usar

@Url.Action("Edit", "api/MyController")

Todo lo que hace el método Url.Action es agregar la ruta raíz de la aplicación, con el nombre del controlador, seguido del nombre de la acción (a menos que sea "Index", en cuyo caso no se agrega. Si el objeto de valores de ruta tiene un id propiedad, el valor también se agrega a la URL.

James Bunch
fuente
¡Gracias! Me faltaba el api/antes de mi nombre de controlador.
Daniel Congrove