【问题标题】:Web API GetAsync not working on localhostWeb API GetAsync 在本地主机上不起作用
【发布时间】:2014-04-14 04:05:41
【问题描述】:

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

这是示例 Web API 控制器:

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:

【问题讨论】:

  • 当您在浏览器中转到http://localhost:9000/api/product/1 时会发生什么?
  • localhost:9000/api/products/1 返回正确的信息。
  • “/api/product/1”是否正确?在我看来,你可能有一个额外的“/”。尝试“api/products/1” 编辑:我刚刚注意到主块中的 uri 与下面的不同。
  • @user2985419 你找到解决方案了吗?我正在使用完全相同的东西运行,对我的本地主机 webApi 的调用会导致 client.GetAsync 挂起,只需将 URL 替换为被调用 WebApi 的 Azure 托管版本就可以了!

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


【解决方案1】:

我看到您正在使用来自Calling a Web API From a .NET Client in ASP.NET Web API 2 (C#) 的控制台应用程序示例

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

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 方法更改为私有后,您将可以访问应用程序上的所有控件,并使用来自 HTTPClient 的响应,例如显示消息/或更新标签或网格等。

【讨论】:

    【解决方案2】:

    有几个可能的问题。

    我认为最可能的原因在于您的客户端代码;我怀疑您调用堆栈的更进一步,您的代码正在从async 方法返回的任务上调用WaitResult。正如我在博客中所描述的那样,这将是 cause a deadlock。解决方案是将所有对Task.WaitTask&lt;T&gt;.Result 的调用替换为await,并让async 自然增长。

    如果不是这种情况,还有另一件事需要检查(实际上,即使上面的段落解决了问题,也最好检查一下)。在服务器端,确保您的 ASP.NET 应用程序面向 .NET 4.5并且具有httpRuntime.targetFramework set to 4.5 in its web.config

    【讨论】:

    • 这是一个非常奇怪的错误。在另一台机器上尝试;你可能在看WinSock corruption
    猜你喜欢
    • 2017-02-13
    • 2015-02-25
    • 2011-02-15
    • 2015-03-19
    • 2018-01-02
    • 2017-07-22
    • 2016-12-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多