60 votes

Application ASP.NET MVC 4 appelant une WebAPI distante

J'ai créé quelques applications ASP.NET MVC dans le passé, mais je n'ai jamais utilisé de WebAPIs auparavant. Je me demande comment je pourrais créer une application MVC 4 simple qui fait des choses simples CRUD via WebAPI au lieu d'un contrôleur MVC normal. L'astuce est que l'interface WebAPI doit être une solution distincte (et, en fait, pourrait très bien se trouver sur un serveur/domaine différent).

Comment faire ? Que me manque-t-il ? Faut-il simplement configurer des routes pour pointer vers le serveur de la WebAPI ? Tous les exemples que j'ai trouvés montrant comment utiliser des interfaces WebAPI à l'aide d'une application MVC semblent supposer que l'interface WebAPI est intégrée à l'application MVC ou, du moins, qu'elle se trouve sur le même serveur.

Oh, et pour clarifier, je ne parle pas des appels Ajax utilisant jQuery... Je veux dire que le contrôleur de l'application MVC devrait utiliser la WebAPI pour obtenir/entrer des données.

82voto

tugberk Points 16203

Vous devez utiliser le nouveau HttpClient pour consommer vos API HTTP. Je peux en outre vous conseiller de rendre vos appels entièrement asynchrones. Comme les actions du contrôleur ASP.NET MVC supportent le modèle de programmation asynchrone basé sur les tâches, c'est assez puissant et facile.

Voici un exemple excessivement simplifié. Le code suivant est la classe d'aide pour un exemple de requête :

public class CarRESTService {

    readonly string uri = "http://localhost:2236/api/cars";

    public async Task<List<Car>> GetCarsAsync() {

        using (HttpClient httpClient = new HttpClient()) {

            return JsonConvert.DeserializeObject<List<Car>>(
                await httpClient.GetStringAsync(uri)    
            );
        }
    }
}

Ensuite, je peux le consommer à travers mon contrôleur MVC de manière asynchrone comme ci-dessous :

public class HomeController : Controller {

    private CarRESTService service = new CarRESTService();

    public async Task<ActionResult> Index() {

        return View("index",
            await service.GetCarsAsync()
        );
    }
}

Vous pouvez consulter l'article ci-dessous pour voir les effets des opérations d'E/S asynchrones avec ASP.NET MVC :

Mon point de vue sur la programmation asynchrone basée sur les tâches dans les applications Web C# 5.0 et ASP.NET MVC

18voto

Glenn Arndt Points 178

Merci à tous pour les réponses. @tugberk m'a mis sur la bonne voie, je pense. Cela a fonctionné pour moi...

Pour mon aide de CarsRESTService :

public class CarsRESTService
{
    readonly string baseUri = "http://localhost:9661/api/cars/";

    public List<Car> GetCars()
    {
        string uri = baseUri;
        using (HttpClient httpClient = new HttpClient())
        {
            Task<String> response = httpClient.GetStringAsync(uri);
            return JsonConvert.DeserializeObjectAsync<List<Car>>(response.Result).Result;
        }
    }

    public Car GetCarById(int id)
    {
        string uri = baseUri + id;
        using (HttpClient httpClient = new HttpClient())
        {
            Task<String> response = httpClient.GetStringAsync(uri);
            return JsonConvert.DeserializeObjectAsync<Car>(response.Result).Result;
        }
    }
}

Et ensuite pour CarsController.cs :

public class CarsController : Controller
{
    private CarsRESTService carsService = new CarsRESTService();

    //
    // GET: /Cars/

    public ActionResult Index()
    {
        return View(carsService.GetCars());
    }

    //
    // GET: /Cars/Details/5

    public ActionResult Details(int id = 0)
    {
        Car car = carsService.GetCarById(id);

        if (car == null)
        {
            return HttpNotFound();
        }
        return View(car);
    }
}

10voto

peco Points 113

Vous pouvez utiliser WCF pour consommer le service. Comme ceci :

[ServiceContract]
public interface IDogService
{
    [OperationContract]
    [WebGet(UriTemplate = "/api/dog")]
    IEnumerable<Dog> List();
}

public class DogServiceClient : ClientBase<IDogService>, IDogService
{
    public DogServiceClient(string endpointConfigurationName) : base(endpointConfigurationName)
    {
    }

    public IEnumerable<Dog> List()
    {
        return Channel.List();
    }
}

Et ensuite vous pouvez le consommer dans votre contrôleur :

    public class HomeController : Controller
    {
        public HomeController()
        {
        }

        public ActionResult List()
        {
            var service = new DogServiceClient("YourEndpoint");
            var dogs = service.List();
            return View(dogs);
        }
    }

Et dans votre web.config vous placez la configuration pour votre endpoint :

  <system.serviceModel>
<client>
  <endpoint address="http://localhost/DogService" binding="webHttpBinding"
    bindingConfiguration="" behaviorConfiguration="DogServiceConfig" contract="IDogService"
    name="YourEndpoint" />
</client>
<behaviors>
  <endpointBehaviors>
    <behavior name="DogServiceConfig">
      <webHttp/>
    </behavior>
  </endpointBehaviors>
</behaviors>

1voto

Cuong Le Points 29324

Dans ce cas, vous pouvez utiliser HttpClient pour consommer l'API Web à partir de votre contrôleur.

1voto

Onur TOPAL Points 1377

http://restsharp.org/ est la réponse à vos questions. Je l'utilise actuellement dans une application qui a une structure similaire.

Mais de manière plus générale, l'utilisation de l'interface WebAPI consiste simplement à afficher et à demander des données, et c'est à vous de décider comment les traiter. Vous pouvez même utiliser des WebRequest et JavascriptSerializer standard.

A la vôtre.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X