Como criar um URL de API da Web do ASP.NET?

120

No ASP.NET MVC, temos @Url.Actionpara ações. Existe algo semelhante ao @Url.Apique encaminharia para / api / controller?

Shane Courtrille
fonte

Respostas:

139

O ApiController possui uma propriedade chamada Url, do tipo System.Web.Http.Routing.UrlHelper, que permite a construção de URLs para controladores de API.

Exemplo:

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";
    }

    ...
}

Esse UrlHelper não existe nem na sua exibição nem nos controladores padrão.


ATUALIZAR:

E para fazer o roteamento fora de um ApiController, você pode fazer o seguinte:

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

ou dentro de uma 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 o httproute = ""token de rota que é importante.

Obviamente, isso pressupõe que sua rota da API seja chamada DefaultApino seu método RegisterRoutes em Global.asax:

routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);
Darin Dimitrov
fonte
Isso .. realmente não me ajuda muito, pois preciso que meu View seja capaz de gerar URLs de uma maneira segura. Se houver uma licença do Go Live, qual é a maneira 'Go Live' de criar URLs no View?
Shane Courtrille
O mais importante é que isso não funcionará se você estiver usando o ASP.Net Development Server, pois ele muda de porta o tempo todo, para que você não consiga nem usar o URL da visualização.
Shane Courtrille
@ShaneCourtrille, atualizei minha resposta para ilustrar como você pode usar o normal System.Web.Mvc.UrlHelperpara gerar rotas Api fora de um HttpControllerContext.
Darin Dimitrov
Muito obrigado! Eu estava tentando usar o RouteUrl, mas não sabia sobre o requisito de parametrização enableproute.
Shane Courtrille
2
Eu entendo o objetivo da amostra; Estou dizendo que seria um exemplo mais útil se você inserisse uma linha do código do ViewBag, porque estaria demonstrando que esse valor é o que estávamos tentando obter em um cenário provável e não apenas executando algum código arbitrário. Novamente, eu não teria comentado se não tivesse perdido alguns minutos sem perceber o que perdi antes de finalmente reconhecer que a linha de código específica era a relevante.
Jon Davis
43

Funciona com a forma mais simples, Url.Actionportanto você não precisa fazer referência a nenhum nome de roteamento:

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

Você pode adicionar um area = ""se o URL for necessário em uma Área. (Por padrão, os controladores da API estão fora do Areas). Estou usando o MVC 4.

Gábor Imre
fonte
7
O UrlHelper na API da Web é msdn.microsoft.com/en-us/library/… , não possui um método de ação.
Yuriy Faktorovich
8
@YuriyFaktorovich Esta publicação indica que Url.Actionestá sendo usada em uma Visualização. Urlé do tipo System.Web.Mvc.UrlHelpere não é mapeado para WebApirotas. É por isso que você precisa do parâmetro extra: new { httproute = "" }.
Jesse
3
Eu adicionei, httproute""mas não está mapeando = /
Maslow
Eu tive que adicionar o link com uma área em branco e nulos htmlAttributes @Html.ActionLink("link", "Get", "Servers", new { id = r.idServer, area = "", httproute = "" }, null) mas que funcionou perfeitamente
Christopher G. Lewis
2
Isso funciona perfeitamente de uma exibição, no entanto, não sei por que ela gera o nome da ação como uma string de consulta como: / api / dashboard? Action = getdata. Eu estava esperando isso: / api / dashboard / getdata
umutesen 8/16
7

Deseja gerar links de maneira segura, sem seqüências codificadas (nomes de controladores)?

Há uma pepita para isso! (e é escrito por Mark Seeman)

https://github.com/ploeh/Hyprlinkr

Funciona assim:

Rotas, como sempre:

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

Obtenha um URL:

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

Resultado:

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

Aqui está o método KISS para responder à pergunta:

Se esse for o código que você usaria para criar uma URL do controlador MVC

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

Para obter um URL para a versão da API do controlador (assumindo que você use o mesmo nome do controlador), você pode usar

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

Tudo o que o método Url.Action está fazendo é anexar o caminho raiz do aplicativo, com o nome do controlador, seguido pelo nome da ação (a menos que seja "Índice", nesse caso, não será anexado. Se o objeto de valores de rota tiver um ID Na propriedade, o valor também é anexado ao URL.

James Bunch
fonte
Obrigado! Estava faltando o api/nome do meu controlador antes.
Daniel Congrove