コントローラの非同期アクションにポストするHtml.BeginFormで作成された標準フォームがあります。これは(これはアウトラインではなく、実際のコードである)のように見えます:ASP.NET MVC POSTは最初の試行で無期限に待機します
[HttpPost]
public async Task<ActionResult> Index(UserCreds creds)
{
try
{
if (ModelState.IsValid)
{
var user = await loginRep.Login(creds.Username, creds.Password);
if (user != null)
{
_context.SetAuthenticationToken(user);
return RedirectToAction("Index", "Landing");
}
else
{
ModelState.AddModelError("", "Login failed.");
}
}
else
{
_logger.Debug(string.Format("User failed authentication."));
}
}
catch (Exception ex)
{
throw new HttpException(500, string.Format("An error occured during the execution of the action {0} from Controller {1}", "Index", "Login"), ex);
}
return View();
}
初めてフォームを送信すると、ブラウザは1つがでステッピング見ることができるにもかかわらず、応答を無期限に待っているだろうRedirectToActionに到達したことを示します。ブラウザで要求を停止して再度送信すると、リダイレクトが発生します。その後のすべてのログイン試行も正常にリダイレクトされます。また、認証トークンは、その最初の試行の間に何らかの形で設定されません。
これはおそらく、loginRep.Login
の代理人の使用と関係があります。その中で最終的には次のようになります:
private async Task<LoginResponse> SendLoginRequest(string username, string password)
{
TaskCompletionSource<LoginResponse> tcs = new TaskCompletionSource<LoginResponse>();
LoginResponseCallback callback = null;
callback = new LoginResponseHandler(delegate (response) {
securityService.OnLoginResponse -= callback;
tcs.SetResult(response);
});
securityService.OnLoginResponse += callback;
securityService.SendLoginRequest(username, password);
return await tcs.Task;
}
何が起こっているのか分かりますか?デッドロックの場合、デバッガがリダイレクトに達することは期待できませんでした。また、最初の試み以外のすべての試みに対してログインが動作するとは思っていませんでした。
フォームは、ログイン要求の送信をスキップし、正常な応答がどのように表示されるかをハードコードするだけで初めて機能します。
非同期メソッドでうまく動作しない最初の呼び出しでのみ初期化されるもの(設定プロバイダなど)がありますか? – Porschiey
確かではありません。ただし、ログイン応答は初めて機能します。このプロジェクトはもともとMVC 2.0であり、その後MVC 5.0に移行されたことを忘れていました。おそらくWeb.configを削除して、古い構成が干渉するのを排除するために、新しい設定を行うべきだと私は考えていました。私はそれを試してみましょう。 –
新しいWeb.configの作成に時間がかかりすぎることが判明しました。ランタイム情報を現在のWeb.configに追加しましたが、問題は解決しません。 –