2016-10-26 17 views
0

私のMVCアプリケーションには1ページあります。このページでは、ユーザーがユーザー名とパスワードを入力してログインボタンをクリックするか、ユーザーが自分のファーストネームと電子メールアドレスを入力してサインアップボタンをクリックすることができます。MVC:2つのフォームタグと1つのViewModel

私の最初に考えたのは、すべての[Required]属性で、UserNamePasswordFirstNameEmail特性を持つビューモデルを作成することでした。その後、2つのビューを持つHtml.BeginForm()のです。これはおそらく動作しますが、コントローラにデータを返信すると、ModelState.IsValidは常にViewModelが無効なのでfalseを返します。

誰かがこのような状況を処理する適切な方法を教えてもらえますか?

+1

それぞれのケースには、2つの別々のビューモデルを持つ2つの別々のフォームという異なる検証ルールがあります。 – Jasen

+0

異なるタイプのログインに1つのモデルと1つのフォームを使用する場合は、モデルに[必須]属性を設定できないと思います。あなたは常にいくつかの空の値を持っています。 @Jasen氏によると、別のビューと別のモデルを使用してログインの種類ごとにお勧めします。 – kat1330

+0

AJAXまたはポストバックを使用していますか?ポストバックの場合、現在の回答の中には、あなたのために痛みを引き起こすものがあります。 –

答えて

2

私は、これは、このようなものの内側に2子のviewmodel年代を持つことになりますのviewmodelを作成することですachievieの最良の方法だと思います私のプロジェクトに非常に似たシナリオを実装している:

public class AuthModelView 
{ 
    public MemberLoginViewModel LoginModel { get; set; } 
    public MemberRegisterViewModel RegisterModel { get; set; } 

    [HiddenInput] 
    public string ReturnUrl { get; set; } 
} 

はMemberLoginViewModel:

public class MemberLoginViewModel 
{ 
    [Required(ErrorMessage = "")] 
    [Display(Name = "")] 
    [EmailAddress] 
    public string Email { get; set; } 


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

    [Display(Name = "")] 
    public bool RememberMe { get; set; } 
} 

MemberRegisterViewModel:

public class MemberRegisterViewModel 
{ 
    [Required(ErrorMessage = "")] 
    [DataType(DataType.EmailAddress)] 
    public string Email { get; set; } 

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

    [Required] 
    public string RepeatPassword { get; set; } 

    [HiddenInput(DisplayValue = false)] 
    public string ReturnUrl { get; set; } 
} 

そしてY OU「モデル」は、あなたの親ViewModelにある場合、あなたは2つの区切らフォームつのビューで を持っています2つの部分のビューをレンダリングするビュー

@Html.Partial("MemberLoginSummary", Model) 
    @Html.Partial("MemberRegisterSummary", Model) 

を作成します。あなたの部分図であなたは、単にような何か:あなたが別のライブラリを試してみたいなら、あなたはFluentValidation

で行くことができ

@Html.TextBoxFor(m => m.LoginModel.Email, null, new { @class = "form-control", placeholder = "email", id="Email" }) 
0

私は適切な方法はそれぞれのViewModelを持つことだと思います。必要に応じて、基礎となるビジネスロジックやコードとデータベースとの対話が、単一のモデルでも機能します。

あなたのオプションはよく討議されますhere

MVCページに複数のViewModelを持つことは痛みです。 Some guidance here on how

1

2つのビューモデルを定義できます。

ログインビューモデル:

public class LoginViewModel 
{ 
    [Requried] 
    public string UserName { get; set; } 

    [Requried] 
    public string Password { get; set; } 
} 

登録ビューモデル:

public class RegisterViewModel 
{ 
    [Requried] 
    public string UserName { get; set; } 

    [Requried] 
    public string Password { get; set; } 

    [Requried] 
    public string FirstName{ get; set; } 

    [Requried] 
    public string Email { get; set; } 
} 

ログインビュー:

@Html.BeginForm("Login", "Account", FormMethod.Post) 
{ 
    <!-- login form implements... --> 
} 

登録ビュー:

@Html.BeginForm("Register", "Account", FormMethod.Post) 
{ 
    <!-- register form implements... --> 
} 

コントローラ:

public IActionResult Login(LoginViewModel model) 
{ 
    if (ModelState.IsValid) 
    { 

    } 
} 

public IActionResult Register(RegisterViewModel model) 
{ 
    if (ModelState.IsValid) 
    { 

    } 
} 

それとも、あなただけの1つのモデルをしたい場合。 [Required]属性を削除してください。アクション内で確認できます。このように:

public IActionResult Login(YourViewModel model) 
{ 
    if (!string.IsNullOrEmpty(model.UserName) && !string.IsNullOrEmpty(model.Password)) 
    { 

    } 
} 

public IActionResult Register(YourViewModel model) 
{ 
    if (!string.IsNullOrEmpty(model.UserName) && 
     !string.IsNullOrEmpty(model.Password) && 
     !string.IsNullOrEmpty(model.FirstName) && 
     !string.IsNullOrEmpty(model.Email)) 
    { 

    } 
} 

希望!

1

をFluentValidationは、さまざまな方法のための単一のクラスの検証をカスタマイズするエレガントな方法を提供します。例えば

[Validator(typeof(LoginRegisterModelValidator))] 
public class LoginRegisterViewModel 
{ 
    public string UserName { get; set; } 

    public string Password { get; set; } 

    public string FirstName{ get; set; } 

    public string Email { get; set; } 
} 

については

あなたは複数のルールは、さまざまなアクションのためのバリデータクラスは[コントローラのアクションは、この

[HttpPost] 
[ValidateAntiForgeryToken] 
public ActionResult Login([CustomizeValidator(RuleSet = "LoginRuleSet")] LoginRegisterViewModel model) 
     { ... 
     } 

[HttpPost] 
[ValidateAntiForgeryToken] 
public ActionResult Register([CustomizeValidator(RuleSet = "RegisterRuleSet")] LoginRegisterViewModel model) 
     { ... 
     } 
} 
ようになり、この

public class LoginRegisterModelValidator : AbstractValidator<LoginRegisterViewModel> 
    { 
     public RegistryAddEditModelValidator() 
     { 
      /* Define the rule set to call them specifically inside contrller action parameter with CustomizeValidator Attribute */ 
      RuleSet("LoginRuleSet", LoginRuleSet); 
      RuleSet("RegisterRuleSet", RegisterRuleSet);    
     } 

protected void LoginRuleSet() 
     { 
      RuleFor(x => x.UserName).NotEmpty(); 
      RuleFor(x => x.Password).NotEmpty(); 
     } 

     protected void RegisterRuleSet() 
     { 
      RuleFor(x => x.Email).NotEmpty(); 
      RuleFor(x => x.FirstName).NotEmpty(); 
     } 
} 

ようになり を定義していることができます

希望すると、同じルールで異なるルールを検証するのに役立ちますクラス。

関連する問題