如何在视图中传递多个模型以及如何在ASP.NET核心MVC 6中配置控制器从单个视图页面处理多个FORM?

时间:2016-05-09 17:13:37

标签: asp.net-core asp.net-core-mvc

我想在同一页面上实现登录和注册,两者都有自己的模型。

3 个答案:

答案 0 :(得分:1)

您需要一个封装这两个模型的视图模型。例如:

public class CombinedLoginRegisterViewModel
{
    public LoginViewModel Login { get; set; }
    public RegisterViewModel Register { get; set; }
}

在您的视图中,确保每个字段都包含在单独的表单标记中。这是最重要的部分。这样,您只会为其中一个子模型提交字段,而不是另一个。然后,另一个子模型将被设置为null,这是允许其他一切工作的原因。另外,请注意表单字段的名称前缀。只要您使用*For家庭的帮助者,您应该没事,但如果您使用部分帮助,您可能需要更加小心。无论长短,都应该使用包含Login.UsernameLogin.Password等名称属性的HTML输入,而不仅仅是Username / Password

在帖子上,根据发布的字段集,只有一个或那个不会为空。因此,您可以在后期操作中进行测试并进行相应的分支:

if (ModelState.IsValid)
{
    if (model.Login != null)
    {
        // do login
    }
    else if (model.Register != null)
    {
        // do register
    }
}

值得注意的是,验证仅发生在非空的类实例上。因此,如果发布的子模型字段集无效,您仍然可以要求属性等,ModelState.IsValid只会为false。由于另一个将为null,因此不会对其应用任何验证规则。

<强>更新

以下是我对@TrevorWard评论的一些示例代码:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LoginRegister(CombinedLoginRegisterViewModel model)
{
    // This check is basically just to confirm all required fields
    // were entered.
    if (ModelState.IsValid)
    {
        if (model.Login != null)
        {
            DoLogin(model.Login);
        }
        else if (model.Register != null)
        {
            DoRegister(model.Register);
        }

        // Second check here allows you to add ModelState errors in the
        // DoLogin/DoRegister method to bypass the redirect and redisplay
        // the form.
        if (ModelState.IsValid)
        {
            return RedirectToAction("Index", "Manage");
        }
    }

    // Redisplay view on validation errors
    return View(model);
}

protected void DoLogin(LoginViewModel model)
{
    // do login
}

protected void DoRegister(RegisterViewModel model)
{
    // do register
}

答案 1 :(得分:1)

我会使用View Components。但我不确定这是最好的实施。

简单实现如下:

的HomeController

public IActionResult Index()
{
    return View();
}

[HttpPost]
public ActionResult Login(LoginModel model)
{
     if (!ModelState.IsValid)
     {
         return View("Index", model);
     }
     return RedirectToAction("Index");
}

[HttpPost]
public ActionResult Register(RegisterModel model)
{
    if (!ModelState.IsValid)
    {
         return View("Index", model);
    }
    return RedirectToAction("Index");
}

索引视图

@Component.Invoke("LoginComponent")
@Component.Invoke("RegisterComponent")  

LoginComponent

 [ViewComponent(Name = "LoginComponent")]
 public class LoginComponent : ViewComponent
 {
     public LoginComponent()
     {

     }
     public IViewComponentResult Invoke()
     {
            return View(new LoginModel());
     }
 }

LoginModel

public class LoginModel
{
    [Required]
    public string L_UserName { get; set; }

    public string L_Password { get; set; }
}

最后登录组件视图

@model LoginModel
<form asp-controller="Home" asp-action="Login">
    @Html.ValidationSummary()
    <input asp-for="L_UserName" />
    <input asp-for="L_Password" />
    <input type="submit" />
</form>

答案 2 :(得分:0)

尝试让表单将其值提交给不同的控制器方法。您无法将多个模型传递给视图,但可以将这些模型组合到单个视图模型中。只要html元素的名称标签对应于控制器方法所期望的模型的属性,并且值是正确的类型,模型绑定器将为您解决问题。