0

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:
4
  • What happens when you just go to http://localhost:9000/api/product/1 in a browser? Commented Apr 14, 2014 at 4:28
  • localhost:9000/api/products/1 returns the correct information. Commented Apr 14, 2014 at 4:36
  • is "/api/product/1" correct though? Seems to me like you might have an extra "/". Try "api/products/1" Edit: I just noticed that your uri in main block is different from the one below. Commented Apr 14, 2014 at 5:24
  • @user2985419 did you find a solution for this? I'm running with the same thing exactly, the call to my localhost webApi causes the client.GetAsync to hang, just replacing the URL with an Azure hosted version of the called WebApi works fine! Commented Aug 27, 2016 at 18:21

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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.

1 Comment

That's a very strange error. Try it on a different machine; you may be looking at WinSock corruption.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.