简体   繁体   中英

Web API GetAsync not working on localhost

I am learning how to connect to a ASP.NET Web API service using Visual Studio 2012 on my localhost.

Here is the sample Web API Controller:

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

I am trying to connect to this Web API with the following code:

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

I have the following in the App.config (I found this online):

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

When this line is executed, the application stops executing:

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

What would be causing this?

Thanks in advance

EDIT

Here is the error:

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:

I see that you are using the console application sample from Calling a Web API From a .NET Client in ASP.NET Web API 2 (C#)

I needed to do the same thing , but in a windows application and I solved it by doing 2 things. In my Click Event ( and should be the same using a call to a function ) do not use .Wait(). Mark the event/function with the Async modifier and call the async method using await

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

Change the RunAsync method from static to private .

  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;

            }
        }
    }

The call will run and complete without the application coming to a stand still. After changing the RunAsync method to private you will have access to all the controls on the application and you use the response from the HTTPClient for example showing a message / or updating a label or Grid etc.

There are a couple of possible problems.

I believe the most likely cause is in your client code; I suspect that further up you call stack, your code is calling Wait or Result on the task returned from an async method. This will cause a deadlock , as I describe on my blog. The solution is to replace all calls to Task.Wait or Task<T>.Result with await and allow async to grow naturally.

If that isn't the case, there is one other thing to check (actually, it's a good idea to check this even if the paragraph above solves the problem). On the server side, ensure that your ASP.NET app is targeting .NET 4.5 and has httpRuntime.targetFramework set to 4.5 in its web.config .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM