【问题标题】:Webapi call from mvc application来自 mvc 应用程序的 Webapi 调用
【发布时间】:2017-01-09 12:51:16
【问题描述】:

我在同一个解决方案中创建了两个项目,一个用于 mvc 应用程序,另一个用于 web api。

当我从 PostMan 或任何 HttpClient 调用我的 web api 方法时,我能够按预期接收响应。

但是,当我在 MVC 应用程序中调用相同的方法时,应用程序会继续运行而没有收到任何响应。 Visual Studio 不会记录或显示任何特定异常。

我已经复制了我用作参考的代码。任何帮助将不胜感激。

public class UserFacade
{
    HttpClient _client;
    string url = "http://localhost:50759/api/v1/login";
    public void LoginUser(string userName, string password)
    {
        _client = new HttpClient
        {
            BaseAddress = new Uri(url)
        };

        _client.DefaultRequestHeaders.Accept.Clear();
        _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        var model = new UserModel
        {
            UserName = userName,
            UserPassword = password
        };

        var userModel = JsonConvert.SerializeObject(model);
        var content = new StringContent(userModel, Encoding.UTF8, "application/json");

        GetUserTask(_client, content).Wait();

    }

    private async Task GetUserTask(HttpClient client, StringContent content)
    {
        using (client)
        {   
            HttpResponseMessage res = await client.PostAsync(url, content);
            res.EnsureSuccessStatusCode();
            if (res.IsSuccessStatusCode)
            {
                var response = await res.Content.ReadAsStringAsync();

                JavaScriptSerializer JSserializer = new JavaScriptSerializer();
                //deserialize to your class
                //var userResponse = JSserializer.Deserialize<UserResponse>(response);

            }
        }
    }

}

仅提供我在解决方案中创建了两个启动项目并从那里运行代码的信息。

【问题讨论】:

    标签: c# asp.net-mvc model-view-controller asp.net-web-api


    【解决方案1】:

    你正在陷入僵局。确保在进行异步调用时不捕获上下文:

    private async Task GetUserTask(HttpClient client, StringContent content)
    {
        using (client)
        {
            HttpResponseMessage res = await client.PostAsync(url, content).ConfigureAwait(false);
            res.EnsureSuccessStatusCode();
            if (res.IsSuccessStatusCode)
            {
                var response = await res.Content.ReadAsStringAsync().ConfigureAwait(false);
            }
        }
    }
    

    请注意我已添加到您的两个异步调用中的 .ConfigureAwait(false)

    话虽如此,进行异步调用然后像这样阻塞它是完全浪费的:

    GetUserTask(_client, content).Wait();
    

    你完全扼杀了异步调用的所有好处。我强烈建议您使用代码的异步版本:

    public async Task LoginUser(string userName, string password)
    {
        _client = new HttpClient
        {
            BaseAddress = new Uri(url)
        };
    
        _client.DefaultRequestHeaders.Accept.Clear();
        _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    
        var model = new UserModel
        {
            UserName = userName,
            UserPassword = password
        };
    
        var userModel = JsonConvert.SerializeObject(model);
        var content = new StringContent(userModel, Encoding.UTF8, "application/json");
    
        await GetUserTask(_client, content);
    }
    

    当然还有一个异步动作控制器动作,它将使用异步方法:

    public async Task<ActionResult> Index()
    {
        await new UserFacade().LoginUser("user", "secret");
        return View();
    }
    

    【讨论】:

    • 感谢达林的帮助。
    猜你喜欢
    • 2012-10-23
    • 2014-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-16
    • 2012-06-14
    • 1970-01-01
    相关资源
    最近更新 更多