如何在MVC的(第一个)索引页面上实现登录和注册(表单)?

时间:2016-06-08 14:01:06

标签: c# asp.net-mvc asp.net-mvc-4

我正在尝试创建一个webapplication,一旦用户访问webapplication就会提示用户登录(我试图实现的东西看起来很像第一次访问时的Tumblr主页)

一切看起来都不错,但每当我提交一份表格时,另一份表格也会提交。因为我必须同时使用project_name.Models.LoginModelproject_name.Models.RegisterModel,所以在这里事情变得复杂了。如何在一个(index.cshtml)视图中使用这两个不同的模型,如何在我仅单击属于某个特定的提交按钮的同时防止两个(单独的)表单同时提交形成的?

我应该在以下代码中更改哪些内容?:

我的Index.cshtml

@model Rent_a_Car.Models.LoginModel @* <- My guess is that this is not a correct way to approach this problem? *@

@{
    ViewBag.Title = "Home Page";
}

<div class="registrate">
    <h2>Rent-a-Car</h2>
    <h4>Register</h4>
    <hr />
    @using (Html.BeginForm()) {
        @Html.AntiForgeryToken()
        @Html.ValidationSummary()

        <p>-</p>@*
        <div class="form-group">
            @Html.TextBoxFor(m => m.UserName, new { @class = "form-control text-box single-line", @name = "E-mail", @placeholder = "E-mail" })
        </div>
        <div class="form-group">
            @Html.PasswordFor(m => m.Password, new { @class = "form-control text-box single-line", @name = "Wachtwoord", @placeholder = "Wachtwoord" })
        </div>
        <div class="form-group">
            @Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control text-box single-line", @name = "Bevestig", @placeholder = "Bevestig uw wachtwoord" })
        </div>*@
    }
</div>

<div class="welcome">
    <h4>Log in</h4>
    <hr />
    @using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl })) {
        @Html.AntiForgeryToken()
        @Html.ValidationSummary(true)

        <p></p>
        <div class="form-group">
            @Html.TextBoxFor(m => m.UserName, new { @class = "form-control text-box single-line", @name = "E-mail", @placeholder = "E-mail" })
            @Html.ValidationMessageFor(m => m.UserName)
        </div>
        <div class="form-group">
            @Html.PasswordFor(m => m.Password, new { @class = "form-control text-box single-line", @name = "Wachtwoord", @placeholder = "Wachtwoord" })
            @Html.ValidationMessageFor(m => m.Password)
        </div>
        <div class="checkbox">
            @Html.CheckBoxFor(m => m.RememberMe)
            @Html.LabelFor(m => m.RememberMe)
        </div>
        <input type="submit" class="btn btn-default" value="Inloggen" />
    }
    <hr />
</div>

我的HomeController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Transactions;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using DotNetOpenAuth.AspNet;
using Microsoft.Web.WebPages.OAuth;
using WebMatrix.WebData;
using Rent_a_Car.Filters;
using Rent_a_Car.Models;

namespace Rent_a_Car.Controllers
{
[InitializeSimpleMembership]
public class HomeController : Controller
{
    public ActionResult Index(string returnUrl)
    {
        ViewBag.ReturnUrl = returnUrl;

        return View();
    }

    // POST: /

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public ActionResult Index(LoginModel model, string returnUrl)
    {
        if (ModelState.IsValid && WebSecurity.Login(model.UserName, model.Password, persistCookie: model.RememberMe))
        {
            return RedirectToLocal(returnUrl);
        }

        ModelState.AddModelError("", "De ingevulde gebruikersnaam of wachtwoord is onjuist ingevoerd.");
        return View(model);
    }

    private ActionResult RedirectToLocal(string returnUrl)
    {
        if (Url.IsLocalUrl(returnUrl))
        {
            return Redirect(returnUrl);
        }
        else
        {
            return RedirectToAction("Index", "Home");
        }
    }

并且AccountModels.cs保留默认值(可以更改以及将例如地址数据添加到帐户吗?)

(只有一个按钮,但我想在注册表单中添加一个按钮,但是目前一个按钮已经发送了多个表单,我想阻止它发生,只需发送一个表单按钮就是应该发布。)

1 个答案:

答案 0 :(得分:1)

如您所知,您只能使用一个模型作为视图的模型。因此,唯一的前进方向是创建一个包含这两个其他类的类:

public class LoginRegisterViewModel
{
    public LoginModel Login { get; set; }
    public RegisterModel Register { get; set; }
}

然后,在您看来,您可以使用@Html.TextBoxFor(m => m.Login.Username, ...)代替@Html.TextBoxFor(m => m.Username, ...),例如。

就两者同时发布而言,这不是真正发生的事情。这些字段被分隔成单独的HTML表单,因此只发布一组其他字段,而不是两者。但是,您的帖子操作只接受LoginModel,因此,无论您发布哪种表单,都只会绑定其中存在的属性。

相反,您的帖子操作应该接受新的LoginRegisterViewModel。只会发布您提交的表单中存在的字段集,并且它们都将以LoginRegister为前缀,对应LoginRegisterViewModel上的两个属性。结果,只有一个或另一个将由模型绑定器实例化。另一个将为null。因此,您可以在非空的post操作中进行测试,并根据登录或注册用户进行分支。