0

localhost에서 Visual Studio 2012를 사용하여 ASP.NET 웹 API 서비스에 연결하는 방법을 배우고 있습니다.웹 API GetAsync가 로컬 호스트에서 작동하지 않습니다.

namespace ProductStore.Controllers 
{ 
public class ProductsController : ApiController 
{ 
    static readonly IProductRepository repository = new ProductRepository(); 

    public IEnumerable<Product> GetAllProducts() 
    { 
     return repository.GetAll(); 
    } 

    public Product GetProduct(int id) 
    { 
     Product item = repository.Get(id); 
     if (item == null) 
     { 
      throw new HttpResponseException(HttpStatusCode.NotFound); 
     } 
     return item; 
    } 

    public IEnumerable<Product> GetProductsByCategory(string category) 
    { 
     return repository.GetAll().Where(
      p => string.Equals(p.Category, category, StringComparison.OrdinalIgnoreCase)); 
    } 

    public HttpResponseMessage PostProduct(Product item) 
    { 
     item = repository.Add(item); 
     var response = Request.CreateResponse<Product>(HttpStatusCode.Created, item); 

     string uri = Url.Link("DefaultApi", new { id = item.Id }); 
     response.Headers.Location = new Uri(uri); 
     return response; 
    } 

    public void PutProduct(int id, Product product) 
    { 
     product.Id = id; 
     if (!repository.Update(product)) 
     { 
      throw new HttpResponseException(HttpStatusCode.NotFound); 
     } 
    } 

    public void DeleteProduct(int id) 
    { 
     repository.Remove(id); 
    } 
} 
} 

나는 다음과 같은 코드를 사용하여이 웹 API에 연결을 시도하고있다 :

static async Task RunAsyncGet() 
{ 
    try 
    { 
     using (var client = new HttpClient()) 
     { 
      client.BaseAddress = new Uri("http://localhost:9000/"); 
      client.DefaultRequestHeaders.Accept.Clear(); 
      client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 

      // HTTP GET 
      HttpResponseMessage response = await client.GetAsync("/api/product/1"); 
      if (response.IsSuccessStatusCode) 
      { 
       Product product = await response.Content.ReadAsAsync<Product>(); 
       Console.WriteLine("{0}\t${1}\t{2}", product.Name, product.Price, product.Category); 
      } 
     } 
    } 
    catch (Exception ex) 
    {   
     throw; 
    } 
} 

나는이 (가)의 App.config에 다음과 같은 한 (여기

샘플 웹 API 컨트롤러입니다 이 온라인을 찾았습니다.) :

<system.net> 
<defaultProxy enabled="false" useDefaultCredentials="false"> 
    <proxy/> 
    <bypasslist/> 
    <module/> 
</defaultProxy> 
</system.net> 

이 줄을 실행하면 응용 프로그램이 실행을 중지합니다.

HttpResponseMessage response = await client.GetAsync("api/products/1"); 

무엇이 원인입니까? 가능한 몇 가지 문제가 있습니다

System.Net.Http.HttpRequestException was caught HResult=-2146233088 Message=An error occurred while sending the request. Source=mscorlib StackTrace: 
     at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
     at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
     at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() 
     at ProductStoreClientFormsApplication.Form1.<RunAsyncGet>d__0.MoveNext() in h:\Learning\WEB API\ProductStoreClientFormsApplication\ProductStoreClientFormsApplication\Form1.cs:line 33 InnerException: System.Net.WebException 
     HResult=-2146233079 
     Message=The underlying connection was closed: Unable to connect to the remote server. 
     Source=System 
     StackTrace: 
      at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult) 
      at System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar) 
     InnerException: System.Net.Sockets.SocketException 
      HResult=-2147467259 
      Message=An invalid argument was supplied 
      Source=System 
      ErrorCode=10022 
      NativeErrorCode=10022 
      StackTrace: 
       at System.Net.Sockets.Socket..ctor(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType) 
       at System.Net.ServicePoint.GetConnection(PooledStream PooledStream, Object owner, Boolean async, IPAddress& address, Socket& abortSocket, Socket& abortSocket6) 
       at System.Net.PooledStream.Activate(Object owningObject, Boolean async, GeneralAsyncDelegate asyncCallback) 
       at System.Net.Connection.CompleteStartConnection(Boolean async, HttpWebRequest httpWebRequest) 
      InnerException: 
+0

방금 ​​갈 때 무슨 일이 발생합니까? 브라우저에서'http : // localhost : 9000/api/product/1'? –

+0

http : // localhost : 9000/api/products/1은 올바른 정보를 반환합니다. – user2985419

+0

은 "/ api/product/1"입니다.네가 여분의 "/"를 가지고있는 것처럼 나에게 보인다. 보십시오 "api/products/1"편집 : 방금 메인 블록에 귀하의 uri가 아래에 다른 것으로 나타났습니다. – failedprogramming

답변

0

: 사전

편집 여기

에서

덕분에 오류입니다.

나는 가장 가능성있는 원인이 클라이언트 코드에 있다고 생각합니다. 나는 당신이 더 이상 전화 스택을 의심, 귀하의 코드 Wait 또는 Resultasync 메서드에서 반환 된 작업을 호출합니다. 내 블로그에서 설명하는대로 이것은 cause a deadlock입니다. 해결책은 Task.Wait 또는 Task<T>.Result의 모든 호출을 await으로 바꾸고 async을 자연스럽게 성장시키는 것입니다.

그렇지 않은 경우 확인해야 할 또 다른 사항이 있습니다 (실제로 위의 단락이 문제를 해결하는 경우에도 확인하는 것이 좋습니다). 서버 측에서 ASP.NET 응용 프로그램이 .NET 4.5 httpRuntime.targetFramework set to 4.5 in its web.config 인 것을 목표로하고 있는지 확인하십시오.

+0

스티븐, 내 편집 좀 봐 주시겠습니까? – user2985419

+0

그건 아주 이상한 오류입니다. 다른 컴퓨터에서 사용해보십시오. [WinSock 손상] (http://support.microsoft.com/kb/811259/en-us)을보고있을 수 있습니다. –

1

난 당신이 Calling a Web API From a .NET Client in ASP.NET Web API 2 (C#)

내가 같은 일을 할 필요가에서 콘솔 응용 프로그램 샘플을 사용하지만, Windows 응용 프로그램에서 것을보고 나는이 일을하여 해결했다. 내 Click 이벤트에서 (그리고 함수 호출을 사용하여 동일해야 함) .Wait()를 사용하지 마십시오. 마크 이벤트/비동기 수정과 기능과 await를

private async void btnSave_Click(object sender, EventArgs e) 
{ 
     await RunAsyncGet(); 
} 

변경 정적에서 개인에 RunAsync 방법을 사용하여 비동기 메서드를 호출합니다.

private async Task RunAsyncGet() 
    { 
     using (var client = new HttpClient()) 
     { 
      client.BaseAddress = new Uri("http://localhost:56286/"); 
      client.DefaultRequestHeaders.Accept.Clear(); 
      client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 

      // HTTP GET 
      HttpResponseMessage response = await client.GetAsync("/api/product/1"); 
      if (response.IsSuccessStatusCode) 
      { 
       Product product= await response.Content.ReadAsAsync<Product>(); 
       SomeLabel.Text = product.Username; 

      } 
     } 
    } 

응용 프로그램이 정지하지 않아도 호출이 실행되고 완료됩니다. RunAsync 메서드를 private로 변경하면 응용 프로그램의 모든 컨트롤에 액세스 할 수 있고 HTTPClient의 응답을 사용하여 메시지를 표시하거나 레이블이나 Grid 등을 업데이트 할 수 있습니다.

관련 문제