2012-11-02 2 views
54

이전에 몇 가지 ASP.NET MVC 응용 프로그램을 만들었지 만 전에는 WebAPI를 사용한 적이 없습니다. 내가 어떻게 간단한 MVC 4 애플 리케이션 대신 WebAPI를 통해 일반 MVC 컨트롤러를 통해 간단한 CRUD 것들을 할 수있는 궁금하네요. 그 트릭은 WebAPI가 별도의 솔루션이어야한다는 것입니다 (실제로 다른 서버/도메인에있을 수 있습니다).ASP.NET MVC 4 응용 프로그램 원격 WebAPI 호출

어떻게하면됩니까? 내가 뭘 놓치고 있니? WebAPI의 서버를 가리키는 경로를 설정하는 것입니까? MVC 응용 프로그램을 사용하여 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 작업의 효과를 볼 : 당신은 서비스를 소비하는 WCF를 사용할 수 있습니다

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을 사용하여 웹 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 직렬화 및 deserialization을 수행합니다. Json.NET을 사용합니다. – tugberk

1

이 경우 HttpClient을 사용하여 컨트롤러에서 웹 API를 사용할 수 있습니다.

10

. 그래서 같이 :

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

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

을 그리고 당신의 Web.config에 당신은 당신의 엔드 포인트에 대한 구성을 배치 : 다음

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

그리고 당신은 당신의 컨트롤러를 소비 할 수

<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 전용 웹 API가 있습니다. 어떻게하면됩니까? 외부 사이트에서 내부 전용 웹 API를 호출 하시겠습니까? http://stackoverflow.com/questions/43002283/how-to-allow-internal-mvc-web-api-from-external-site-outside-the-network – Si8

15

모두 감사 응답. @ tugberk는 나를 올바른 길로 인도했다. 이것은 내 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; 
     } 
    } 
} 

와 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); 
    } 
} 
+0

문자열 보간 (새 C# 6 기능이 추가되었으므로 질문) 또는 "string uri = baseUri + id;"대신 string.builder를 사용하면 작업을 더 쉽게 읽고 리소스 사용량을 약간 줄일 수 있습니다 :) – Rexxo

관련 문제