从应用程序调用Web API

7

我已经在ASP.NET页面上通过按钮单击调用了Web API,如下所示。虽然我在某处读到它不是异步的(因为在client.PostAsJsonAsync(url, sd).Result;中使用了.Result),可能会创建死锁,但这完全可以正常工作。

请建议更新此代码的最佳方法。

private void CallApi(SurveyData sd)
{

    using (var client = new HttpClient())
    {                

        string url = ConfigurationManager.AppSettings.Get("url");
        client.DefaultRequestHeaders.Accept.Clear();

        var response = client.PostAsJsonAsync(url, sd).Result;

        if (response.IsSuccessStatusCode) 
        { 
            Response.Write("Success");
        }
        else
        {
            Response.Write(response.StatusCode + " : Message - " + response.ReasonPhrase);
        }
    }
}

是的,这行代码 var response = client.PostAsJsonAsync(url, sd).Result; 必须等待响应。 您可以在WebAPI中使用异步控制器选项。 - Saadi
我不确定,但如果您将 CallApi 方法设置为 async 并在使用该方法时使用 await,会怎么样呢? - Raghuveer
2
如果不是MVC,可以将该方法设为异步方法,然后等待client.PostAsJsonAsync。虽然通常(据我理解)将void方法标记为异步方法是不好的做法。 - Tim
问题在于我需要从按钮点击事件中调用上述方法,而该事件本身不是异步方法,因此我无法将此方法设置为异步。 - Jigar Shah
我记得很久以前在这里问过同样的问题。根据之前与此相关的人们给出的答案,这并不重要,因为每个请求都会创建自己的线程(请求-响应)。但是在其他博客中,许多人并不同意这一点。所以我想保险起见,我选择了异步选项,因为我正在传输一个序列化文档,大小在1MB到5MB之间。 - Maximus Decimus
3个回答

1
如果您不想使用异步,则可以使用WebClient而不是HttpClient。
WebClient client = new WebClient();
string response = client.UploadString(RequestUrl, "POST", data);

0

你可以将该方法重写为一个async方法(在这种情况下,我建议提供一个返回类型为string):

private async Task<string> CallApi(SurveyData sd)
{

    string result = String.Empty;

    using (var client = new HttpClient())
    {

        string url = ConfigurationManager.AppSettings["url"];
        client.DefaultRequestHeaders.Accept.Clear();

        var response = await client.PostAsJsonAsync(url, sd);

        if (response.IsSuccessStatusCode)
        {
            result = "Success";
        }
        else
        {
            result = response.StatusCode + " : Message - " + response.ReasonPhrase;
        }
    }

    return result;
}

然后你也可以await这个调用的结果:

Response.Write(await CallApi(sd));

虽然调用需要在另一个async方法内部进行。否则,您将不得不执行Response.Write(CallApi(sd).Result);,但我不知道您是否会看到显着的性能提升。


一个 async 方法不能返回一个 string,它必须返回一个 Task<string>。请在你的答案中修复返回类型。 - Federico Dipuma
@FedericoDipuma - 没错。谢谢你指出来 :) - Tim

0

你可以尝试使用这个方法

public async Task<HttpResponseMessage> GetHttpClientResult<T>(string baseUrl, string url, T requestParam, bool isExternalLink = false,
          string acceptMediaVerb = "application/json", HttpMethod requestMethod = null)
        {
            try
            {
                HttpClient client = new HttpClient();
                HttpResponseMessage response = new HttpResponseMessage();
                if (!isExternalLink)
                {
                    client.BaseAddress = new Uri(baseUrl);
                }
                if (!string.IsNullOrEmpty(acceptMediaVerb))
                {
                    if (acceptMediaVerb == "application/json")
                    {
                        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                        if (requestMethod == HttpMethod.Get || requestMethod == null)
                        {
                            response = client.GetAsync(url).Result;
                        }
                        else if (requestMethod == HttpMethod.Post)
                        {
                            response = await client.PostAsJsonAsync(url, requestParam);
                        }
                    }
                }
                var context = new HttpContextWrapper(HttpContext.Current);
                HttpRequestBase request = context.Request;
                return response;
            }
            catch
            {
                return new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest);
            }
        }

这是一个通用的方法,旨在处理具有基本 URL 配置的 API 方法,该配置可以在您的应用程序本身或任何外部 web 请求中进行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接