MVC5アプリケーション:IDユーザーの結果が無効なモデル状態になりますか?
-
21-12-2019 - |
質問
MVC4 / EF5からMVC5 / EF6への開発におけるアプリケーションをアップグレードして(とりわけ)ASP.NET IDを利用しています。ユーザーを作成しようとすると、私のコードはモデルを無効としてフラグを立て、ユーザーを作成していません。私のビューは単に電子メールを入力するためのボックスを表示してから、ログインしているadminを使用できるスイッチを選択して、いくつかのドロップダウンを介して新しいユーザー2を割り当てるためのメンバー整理またはスポンサーのいずれかを選択します。
私のUserControllerのcreate()メソッドは以下のとおりです。
// GET: Admin/UserManagement/Create
public ActionResult Create()
{
ViewBag.headerTitle = "Create User";
ViewData["Organization"] = new SelectList(db.MemberOrganizations, "Id", "Name");
ViewData["Sponsor"] = new SelectList(db.SponsorOrganizations, "Id", "Name");
ViewBag.SwitchState = true;
ApplicationUser newUser = new ApplicationUser();
newUser.RegisteredDate = DateTime.Now;
newUser.LastVisitDate = DateTime.Now;
newUser.ProfilePictureSrc = null;
return View(newUser);
}
// POST: Admin/UserManagement/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create([Bind(Include = "Property1, Property2, etc.")] ApplicationUser applicationUser)
{
if (ModelState.IsValid)
{
ViewBag.headerTitle = "Create User";
PasswordHasher ph = new PasswordHasher();
var password = ph.HashPassword("aR@nD0MP@s$w0r9");
var user = new ApplicationUser() { UserName = applicationUser.UserName, Email = applicationUser.Email, PasswordHash = password };
IdentityResult result = await UserManager.CreateAsync(user, user.PasswordHash);
if (result.Succeeded)
{
await db.SaveChangesAsync();
return RedirectToAction("Index", "UserManagement");
}
else
{
ModelState.AddModelError("", "Failed to Create User.");
}
}
ModelState.AddModelError("", "Failed to Create User.");
var errors = ModelState.Where(x => x.Value.Errors.Count > 0).Select(x => new { x.Key, x.Value.Errors }).ToArray();
var errors2 = ModelState.Values.SelectMany(v => v.Errors);
ViewData["Organization"] = new SelectList(db.MemberOrganizations, "Id", "Name", applicationUser.MemberOrgId);
ViewData["Sponsor"] = new SelectList(db.SponsorOrganizations, "Id", "Name", applicationUser.SponsorOrgId);
if (applicationUser.MemberOrgId != null)
{
ViewBag.SwitchState = true;
}
else
{
ViewBag.SwitchState = false;
}
ViewBag.OrganizationId = new SelectList(db.MemberOrganizations, "Id", "State", applicationUser.MemberOrgId);
// If we got this far, something failed, redisplay form
return View(applicationUser);
}
.
問題をデバッグしようとした試みでは、このの投稿。これらのフラグが立てられたときにモデル状態のプロパティに陥る:
誰もがこの問題についていくつかの考えを持っていますか?私の以前のコードはうまくいっていましたが、私はまだASP.NET IDに使用しています。
編集:Rikardによって提案されたように、sponsororgidとmigivergidがどちらも必要なものではありません(1だけ)私のモデルを設定しました。次のセグメントまで、私のコードがプロセスします。
var user = new ApplicationUser() { Name = applicationUser.Name, Email = applicationUser.Email, PasswordHash = password };
IdentityResult result = await UserManager.CreateAsync(user, user.PasswordHash);
if (result.Succeeded) // ERROR
{
await db.SaveChangesAsync();
return RedirectToAction("Index", "UserManagement");
}
.
result
の値を確認し、Errors->[string[]]->[0]
にドリルダウンしたとき、エラーメッセージは次のとおりです.Name cannot be null or empty
。誰もがこれについて考えを持っていますか?私のビューにフィールドを追加して、新しいユーザーName
を指定し、それを上記のnew ApplicationUser()
コード行に組み込む。私が何かが足りないところをよく確信していません。
edit2: create()表示[関連する]:
@model PROJECTS.Models.ApplicationUser
@{
ViewBag.Title = "Create";
Layout = "~/Areas/Admin/Views/Shared/_LayoutAdmin.cshtml";
string cancelEditUrl = "/Admin/UserManagement/";
}
@using (Html.BeginForm("Create", "UserManagement", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
@Html.HiddenFor(model => model.RegisteredDate)
<div class="container">
<div class="row">
<div class="editor-label">
@Html.LabelFor(model => model.Name)
</div>
<div class="editor-field" style="margin-bottom: 15px">
@Html.TextBoxFor(model => model.Name, new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.Name)
</div>
</div>
<div class="row">
<div class="editor-label">
@Html.LabelFor(model => model.Email)
</div>
<div class="editor-field" style="margin-bottom: 15px">
@Html.TextBoxFor(model => model.Email, new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.Email)
</div>
</div>
....
. 解決
最後の画像でSEができるように、値string.Empty( "")を持つプロパティ sponsororgid にエラーがあります。 ApplicationUser の sponsororgid は、 [requried] 属性を有する。
編集
あなたの問題に関しては、ユーザーをデータベースに追加しようとしたとき(UserManager.Create(ユーザー、パスワード)を呼び出したときに起こりました。
IdentityResult result = await UserManager.CreateAsync(user, user.PasswordHash);
if (result.Succeeded)
{
await db.SaveChangesAsync();
return RedirectToAction("Index", "UserManagement");
}
else
{
var errors = string.Join(",", result.Errors);
ModelState.AddModelError("", errors);
}
.
その後、「エラー」の値をデバッグするか、ModelStateからエラーメッセージを読んでください。
あなたの編集
についてこの部分に名前を追加する:
var user = new ApplicationUser() { UserName = applicationUser.UserName, Email = applicationUser.Email, PasswordHash = password, Name = applicationUser.Name };
.
編集2 問題は、ユーザー名を指定せずにユーザーを作成することはできません。しかし、ユーザーのEメールをユーザー名に追加することができます。その後、ユーザー指定のユーザー名に変更します。検証に合格するために、この部分を追加する必要があります。
UserManager.UserValidator = new UserValidator<User>(UserManager) { RequireUniqueEmail = true };
. 他のヒント
返信に遅れていることを実感していますが、この問題を解決する前にこれに4つのスレッドを読みました。それは完全には明らかではなく、カスタムプロパティとの継承の競合のようです。私の問題の根本は、最初の名前の+ "" + lastnameとして定義したいカスタムプロパティ(...または私は思った)の私の登録でした。
public class ApplicationUser : IdentityUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
// public new string UserName { get; set; }
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
...remainder removed for clarity.
.
この行をIdentityModels.csからコメントアウトしたら、私のカスタムプロパティを削除しました。 poof!問題:解決しました。私はIUSER [TKEY]に戻って継承定義を掘りました、そして私は私が私の(私たちの)問題の根源だと思いました。
namespace Microsoft.AspNet.Identity
{
// Summary:
// Minimal interface for a user with id and username
//
// Type parameters:
// TKey:
public interface IUser<out TKey>
{
// Summary:
// Unique key for the user
TKey Id { get; }
//
// Summary:
// Unique username
string UserName { get; set; }
}
}
.
私はApplicationUserクラスにカスタムプロパティを追加できることを知っていましたが、既に使用中に特定のプロパティ名があることがわかっていませんでした - このクラスで定義されていません。最初に、UserNameフィールドを単にパブリック文字列として追加した後、これを受け取りました。
[...] warning CS0114: 'MyApp.Models.ApplicationUser.UserName' hides inherited member 'Microsoft.AspNet.Identity.EntityFramework.IdentityUser<string,Microsoft.AspNet.Identity.EntityFramework.IdentityUserLogin,Microsoft.AspNet.Identity.EntityFramework.IdentityUserRole,Microsoft.AspNet.Identity.EntityFramework.IdentityUserClaim>.UserName'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword.
.
私は以下の指示が得意ですので、「新しい」キーワードを追加しました(上の上の行をコメントアウトしなければならなかったことを忘れないでください...)。コンパイル時CS0114の警告を解決しましたが、IUSERのユーザー名を妨げました。
op(そして他の無数)は同じことをしました、私は彼がこれを書いたときに信じています:
var user = new ApplicationUser() { UserName = applicationUser.UserName, Email = applicationUser.Email, PasswordHash = password };
. あなたのApplicationUserクラスにユーザー名と電子メールのプロパティがある場合、これらのプロパティは実際のプロパティを非表示にしているので、アプリケーションクラスからそれらを削除します。これは問題を解決します。