Web API GetAsync无法在localhost上运行

时间:2014-04-14 04:05:42

标签: c# asp.net-web-api get dotnet-httpclient asp.net-apicontroller

我正在学习如何使用我的localhost上的Visual Studio 2012连接到ASP.NET Web API服务。

以下是示例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);
    }
}
}

我正在尝试使用以下代码连接到此Web 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中有以下内容(我在网上找到了这个):

<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:

2 个答案:

答案 0 :(得分:1)

我发现您正在使用Calling a Web API From a .NET Client in ASP.NET Web API 2 (C#)

中的控制台应用程序示例

我需要做同样的事情,但在Windows应用程序中我通过做两件事来解决它。在我的Click事件中(并且使用对函数的调用应该是相同的)不要使用.Wait()。使用Async修饰符标记事件/函数,并使用await

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

将RunAsync方法从static更改为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;

            }
        }
    }

呼叫将在没有应用程序静止的情况下运行并完成。将RunAsync方法更改为private后,您将可以访问应用程序上的所有控件,并使用来自HTTPClient的响应,例如显示消息/或更新标签或网格等。

答案 1 :(得分:0)

有几个可能的问题。

我认为最可能的原因是在您的客户端代码中;我怀疑你进一步调用堆栈,你的代码正在调用从Wait方法返回的任务Resultasync。这将cause a deadlock,正如我在博客中描述的那样。解决方案是将Task.WaitTask<T>.Result的所有来电替换为await,并允许async自然增长。

如果不是这样的话,还有另外一件事要检查(实际上,即使上面的段落解决了这个问题,检查这个也是个好主意)。在服务器端,确保ASP.NET应用程序的目标是.NET 4.5 具有httpRuntime.targetFramework set to 4.5 in its web.config