我正在尝试创建一个webapplication,一旦用户访问webapplication就会提示用户登录(我试图实现的东西看起来很像第一次访问时的Tumblr主页)
一切看起来都不错,但每当我提交一份表格时,另一份表格也会提交。因为我必须同时使用project_name.Models.LoginModel
和project_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
保留默认值(可以更改以及将例如地址数据添加到帐户吗?)
(只有一个按钮,但我想在注册表单中添加一个按钮,但是目前一个按钮已经发送了多个表单,我想阻止它发生,只需发送一个表单按钮就是应该发布。)
答案 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
。只会发布您提交的表单中存在的字段集,并且它们都将以Login
或Register
为前缀,对应LoginRegisterViewModel
上的两个属性。结果,只有一个或另一个将由模型绑定器实例化。另一个将为null。因此,您可以在非空的post操作中进行测试,并根据登录或注册用户进行分支。