3

ユーザーをPartialView作成または変更するために使用され、ViewModelを実装するフォームがありますDynamicActionUserModel。このpartialViewを参照するビューには、すべてのテーブルが表示MembershipUsersされ、新しいユーザーを作成しMembership.CreateUser()たり、ユーザー'Membership.UpdateUser()`を変更したりすることができます。partialViewのフォームは、データを送信するためにコントローラーにajax投稿を行います。

私が直面している問題は、ユーザーが作成されると、ユーザー名、電子メール、パスワード、およびロールがシリアル化されてコントローラーに戻されDynamicActionUserModel.RegisterModel、検証されることですが、ユーザーが変更されると、パスワードは使用可能なプロパティではありません(クライアント側で変更できるようにしたいので、設定されず、DynamicActionUserModel.RegisterModel常にModelState.IsValidfalseになります。

おそらく、モデルとビューのデザインを変更する必要がありますか、それともモデルを検証するが、ユーザーが変更されているときにパスワードを無視する方法はありますか?これのベストプラクティスがわからない。

別のオプションは、特にユーザーを変更するために別のViewModelと別のpartialViewを作成することだと思いますが、それはお粗末なようです。

モデル

public class DynamicActionUserModel {
    public string Action { get; set; }
    public RegisterModel RegisterModel { get; set; }
}

public class RegisterModel {
    [Required]
    [Display(Name = "User Name")]
    public string UserName { get; set; }

    [Required]
    [DataType(DataType.EmailAddress)]
    [Display(Name = "Email")]
    public string Email { get; set; }

    [Required]
    [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    public string[] SelectedRoles { get; set; }
    public MultiSelectList Roles { get; set; }

}

コントローラ

[HttpGet]
public ActionResult CreateUser() {
    var model = new DynamicActionUserModel {
        Action = "CreateUser",
        RegisterModel = new RegisterModel {
            Roles = new MultiSelectList(System.Web.Security.Roles.GetAllRoles())
        }
    };

    return PartialView("_UserPartial", model);
}

[HttpGet]
public ActionResult ModifyUser() {
    var model = new DynamicActionUserModel {
        Action = "ModifyUser",
        RegisterModel = new RegisterModel {
            Roles = new MultiSelectList(System.Web.Security.Roles.GetAllRoles())
        }
    };

    return PartialView("_UserPartial", model);
}

[HttpPost]
public ActionResult ModifyUser(DynamicActionUserModel model) {
    bool isEqual = true;

    if(!ModelState.IsValid) { // this is always false because password is empty
        return PartialView("_UserPartial", model);
    }

    var user = Membership.GetUser(model.RegisterModel.UserName);
    // do stuff
    Membership.UpdateUser(user);

    return Json(new {success = false});
}

意見

@using RobotDog.Models
@model IEnumerable<RobotDog.Models.UserModel>

<!-- table of users -->
<div class="modify-form">
    @Html.Action("ModifyUser")
</div>
<div class="create-user-form">
    @Html.Action("CreateUser")
</div>

PartialView

@model RobotDog.Models.DynamicActionUserModel

@using(Html.BeginForm(Model.Action,"Admin", FormMethod.Post, new { @class = "ajax" })) {
    <!-- Email -->
    @Html.TextBoxFor(x => x.RegisterModel.Email, new { @class = inputSize, placeholder = "Email"})

    <!-- UserName -->
    @if(Model.Action == "ModifyUser") {
        @Html.HiddenFor(x => x.RegisterModel.UserName)
        <span class="input-xlarge uneditable-input">@Html.DisplayNameFor(x => x.RegisterModel.UserName)</span>
    } else {
        @Html.TextBoxFor(x => x.RegisterModel.UserName, new { @class = inputSize, placeholder = "User Name" })
    }

    <!-- Password -->
    @if(Model.Action == "Createuser") {
        @Html.PasswordFor(x => x.RegisterModel.Password, new { @class = inputSize, placeholder = "Password"})
    }

    <!-- Roles -->
    @Html.ListBoxFor(x => x.RegisterModel.SelectedRoles, Model.RegisterModel.Roles)

    <!-- Submit -->
    <input type="submit" value="Submit" class="btn"/>
}
4

2 に答える 2

2

ModelState.Remove("password")を呼び出す前に試してみてください。ただし、ここでModelState.IsValid提案されているように、プロパティが常に必要であるとは限らない場合は、必須としてマークしないでください。

于 2012-10-20T18:09:56.837 に答える
0

見たことがありModelState.IsValidFieldますか?

注:MVC4の時点でも、ドキュメントは逆方向であり、次のように記載されている必要があります。

指定されたキーに関連付けられている、またはプレフィックスが付けられているModelErrorオブジェクトがあるかどうかを判別します。

私はこれのために少し拡張メソッドヘルパーを作りました:

public static class ModelStateHelpers
    {
        public static bool IsValidFor<TModel, TProperty>(this TModel model,
                                                         System.Linq.Expressions.Expression<Func<TModel, TProperty>> expression,
                                                         ModelStateDictionary modelState)
        {
            string name = ExpressionHelper.GetExpressionText(expression);

            return modelState.IsValidField(name);
        }
    }

使い方は簡単です:

 bool billingValid = model.IsValidFor(x => x.CheckoutModel.BillingAddress, ModelState);
于 2012-12-15T05:18:26.793 に答える