我在同一个解决方案中创建了两个项目,一个用于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);
}
}
}
}
仅仅是因为我在解决方案中创建了两个启动项目并从那里运行代码的信息。
答案 0 :(得分: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();
}