2012-11-02 11 views
54

以前はいくつかのASP.NET MVCアプリケーションを作成しましたが、WebAPIを使用したことはありません。私は、単純なMVC 4アプリを作ることができるのだろうかと思っています。これは、通常のMVCコントローラーではなく、WebAPIを使って簡単なCRUDを行うものです。そのトリックは、WebAPIが別の解決策でなければならないということです(実際、別のサーバー/ドメイン上にある可能性もあります)。ASP.NET MVC 4アプリケーションリモートWebAPIを呼び出す

どうすればよいですか?私は何が欠けていますか? WebAPIのサーバーを指すルートを設定するだけですか? MVAPアプリケーションを使用してWebAPIを消費する方法を示した例は、WebAPIがMVCアプリケーションに「焼き付けられた」とみなされているか、少なくとも同じサーバーにあると見なされます。

ああ、明確にするために、私はjQueryを使ってAjaxの呼び出しを話しているわけではありません...私は、MVCアプリケーションのコントローラがWebAPIを使ってデータを取得/

答えて

74

HTTP APIを使用するには、新しいHttpClientを使用する必要があります。さらに私はあなたの呼び出しを完全に非同期にすることをアドバイスできます。 ASP.NET MVCコントローラアクションはタスクベースの非同期プログラミングモデルをサポートしているので、非常に強力で簡単です。

これはあまり単純化された例です。あなたは下のポストを見ていることができ

public class HomeController : Controller { 

    private CarRESTService service = new CarRESTService(); 

    public async Task<ActionResult> Index() { 

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

:私は以下のように非同期的に私のMVCコントローラを介してそれを消費することができ、その後

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

:次のコードは、サンプルの要求のためのヘルパークラスでありますASP.NET MVCでの非同期I/O操作の効果を参照してください。

My Take on Task-based Asynchronous Programming in C# 5.0 and ASP.NET MVC Web Applications

+1

+1私はそれを私のウェブアプリケーションのそれとまったく同じです –

+0

これはすばらしく見えますが、私は非同期/待っているものを全く動かすことができません。 IDEはこれらのキーワードが気に入らない。 .NET 4.0を使用しており、NuGetを使用してWeb APIクライアントライブラリをインストールしました。 –

+2

@ GlennArndtあなたがいくつかのアクションを取らない限り、.NET 4.0ではasync/awaitを使用できません。このブログの記事をご覧ください:http://blogs.msdn.com/b/bclteam/archive/2012/10/22/using-async-await-without-net-framework-4-5.aspx非同期コントローラのアクションを活用できます非同期ではなく、キーワードを待っていますが、それは面倒です。 – tugberk

1

http://restsharp.org/は、あなたの質問に対する答えです。私は現在、同様の構造を持つアプリケーションでこれを使用しています。

より一般的にWebAPIを使用するのは、投稿するだけで、データのリクエスト方法は処理する方法までです。標準WebRequestとJavascriptSerializerを使用することもできます。

乾杯。

+3

「WebRequest」と「JavascriptSerializer」は、スタック内の旧式のAPIになりました。新しい 'HttpClient'が行く方法です。 [Microsoft.AspNet.WebApi.Client](http://nuget.org/packages/Microsoft.AspNet.WebApi.Client)NuGetパッケージをインストールすると、OOTBフォーマットサポートも提供され、JSONのシリアル化とデシリアライズがJson.NETを使用します。 – tugberk

1

この場合、HttpClientを使用してコントローラからWeb APIを使用できます。

10

あなたがサービスを利用するためにWCFを使用することができます。

[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(); 
    } 
} 

そして、あなたのコントローラでそれを消費することができます:

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

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

そして、あなたのweb.configファイルで、あなたのエンドポイントの設定を置く:

<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> 
</system.serviceModel> 
+0

私は実際にwcfを使用して実装を非表示にしていますインタフェースの背後にあるサービスを呼び出す詳細。非常に良いチップ。 – Martin

+0

私はASP.netの外部サイトとMVC interal only Web APIを持っています。どうすれば同じことができますか?外部サイトから内部専用Web APIを呼び出しますか? http://stackoverflow.com/questions/43002283/how-to-allow-internal-mvc-web-api-from-external-site-outside-the-network – Si8

15

みんなありがとうこれと同様に応答のために。 @tugberkは正しい道を私に導いた、と私は思う。これは私のCarsRESTServiceヘルパーのために...私のため

を働いた:CarsControllerため

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

そしてを。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); 
    } 
} 
+0

文字列補間(これ以降新しいC#6機能が追加されました) "string uri = baseUri + id;"ではなく、string.builderを使用すると、読みやすく、リソースの使用量がやや少なくなります:) – Rexxo

関連する問題