HttpPost
MVC5 アプリで動作していた次のDelete() メソッドがあります。私の知る限りでは、このコントローラー、ビュー、さらにはモデルに関連するものは何も変更されていません。
// POST: Admin/UserManagement/Delete/5
[HttpPost, ActionName("DeleteConfirmed")]
[ValidateAntiForgeryToken]
public async Task<ActionResult> DeleteConfirmed(string id)
{
ApplicationUser applicationUser = db.Users.Find(id);
if (applicationUser == null)
{
ModelState.AddModelError("", "Failed to find User ID for deletion.");
}
else
{
IdentityResult result = await UserManager.DeleteAsync(applicationUser);
if (result.Succeeded)
{
await db.SaveChangesAsync();
return RedirectToAction("Index", "UserManagement");
}
else
{
ModelState.AddModelError("", "Failed to Delete User.");
var errors = string.Join(",", result.Errors);
ModelState.AddModelError("", errors);
}
}
return View(applicationUser);
}
UserManager ピース:
[CustomAuthorization(myRoles = "Admin")]
public class UserManagementController : Controller
{
protected ApplicationDbContext db { get; set; }
private ApplicationUserManager _userManager;
public UserManagementController()
{
this.db = new ApplicationDbContext();
}
public UserManagementController(ApplicationUserManager userManager)
{
UserManager = userManager;
}
public ApplicationUserManager UserManager
{
get
{
return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
private set
{
_userManager = value;
}
}
私のコードがIdentityResult result = await UserManager.DeleteAsync(applicationUser)
それに到達すると、すぐに下の Dispose() メソッドにジャンプし、Index View の読み込みの代わりに、次のように表示されます。Server Error in '/' Application.
The object cannot be deleted because it was not found in the ObjectStateManager.
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
if (UserManager != null)
{
UserManager.Dispose();
UserManager = null;
}
}
base.Dispose(disposing);
}
誰かが私が間違っている場所を教えてもらえますか? このエラーは今まで見たことがありません。以前は、この DeleteConfirmed() コードは意図したとおりに機能していました。
編集:
Startup.cs :
using Microsoft.Owin;
using Owin;
[assembly: OwinStartupAttribute(typeof(PROJECT.Startup))]
namespace PROJECT
{
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
}
}
}
EDIT2:
CustomAuthorization.cs (ヘルパー):
public class CustomAuthorization : AuthorizeAttribute
{
public string myRoles { get; set; }
public override void OnAuthorization(AuthorizationContext filterContext)
{
var userAuthInfo = HttpContext.Current.User;
if (userAuthInfo != null)
{
if (!userAuthInfo.Identity.IsAuthenticated)
{
string returnUrl = filterContext.HttpContext.Request.RawUrl;
filterContext.Result = new RedirectResult("/Account/Login?returnUrl=returnUrl");
return;
}
string[] roles = myRoles.Split(',');
var userAuth = false;
foreach (string role in roles)
{
if (userAuthInfo.IsInRole(role))
{
userAuth = true;
break;
}
}
if (!userAuth)
{
var result = new RedirectResult("/Home?auth=0");
filterContext.Result = result;
}
}
}
}
EDIT3
/App_Start/ の Startup.Auth.cs:
public partial class Startup
{
// For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
public void ConfigureAuth(IAppBuilder app)
{
// Configure the db context and user manager to use a single instance per request
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
// Enable the application to use a cookie to store information for the signed in user
// and to use a cookie to temporarily store information about a user logging in with a third party login provider
// Configure the sign in cookie
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
}
});
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
}
}
haim770 が指摘した解決策は、アクション メソッド内で 2 つの DbContext 参照を誤って使用していたことですDeleteConfirmed()
。
ApplicationUser applicationUser = db.Users.Find(id)
正しく変更されasync
、すべてが意図したとおりに機能します。ApplicationUser applicationUser = await UserManager.FindByIdAsync(id);
時間を割いて支援してくれたすべての人に感謝します!