【问题标题】:Multiple Forms in same page ASP.net MVC同一页面中的多个表单 ASP.net MVC
【发布时间】:2012-04-03 16:55:02
【问题描述】:

我正在处理我的第一个 ASP.net MVC 项目,并且在同一页面中使用多种表单时遇到了一些问题。 首先,我创建了 2 个部分类: (*Register 将允许用户注册, *登录它允许用户登录。)

然后我使用 HTML.render 将它们集成到我的“日志页”中。 所以我必须使用 2 种不同的动作。喜欢这个:

    [HttpPost]
    public ActionResult Login(LogModel.Login Model)
    {
        if (ModelState.IsValid)
        {

            if (LogModel.Login.Verifuser(Model.IDUser, Model.Password))
            {
                FormsAuthentication.SetAuthCookie(Model.IDUser, false);
                if (LogModel.Login.IsAdmin(Model.IDUser, Model.Password))
                {
                    return View("Admin/Index");
                }
                else
                {
                    return View("Agence/Index");
                }
            }
            else
            {
                ModelState.AddModelError("", "Invalide username or Password");
                return View(Model);
            }
        }
        return View(Model);
    }

在错误情况下我重定向到新页面的问题(白页包含验证摘要)。所以我想知道如何在我的默认页面 Logpage 中显示此错误消息。

【问题讨论】:

  • 发布您的代码。请按照格式指南获取有关如何使其清晰易读的说明。
  • 到底是什么问题?如果您担心表单 POST 操作,您当然可以将两个表单 POST 到不同的控制器操作。

标签: asp.net-mvc


【解决方案1】:

您可以通过三个动作和一个复杂的模型来解决这个问题。

 public class LoginOrRegisterViewModel
 {
      public Models.RegisterViewModel Register { get; set; }
      public Models.LoginViewModel Login { get; set; }
 }


 [HttpGet]
 public ActionResult Login()
 {
      return View("Login", new LoginOrRegisterViewModel());
 }

 [HttpPost]
 public ActionResult Register(Models.LoginViewModel model)
 {
      if(!ModelState.IsValid)
           return View("Login", new LoginOrRegisterViewModel(){ Register = model });
      else
      {
           //TODO: Validate the user
           //TODO: Write a FormsAuth ticket
           //TODO: Redirect to somewhere
     }
 }

 [HttpPost]
 public ActionResult Login(Models.RegistrationViewModel model)
 {
      if(!ModelState.IsValid)
           return View("Login", new LoginOrRegisterViewModel(){ Login = model});
      else
      {
           //TODO: CRUD for registering user
           //TODO: Write forms auth ticket
           //TODO: Redirect
     }
 }

在您的代码中,确保您设置了表单的操作:

 @model Models.LoginOrRegisterViewModel

 @using(Html.BeginForm("Login", "Controller", FormMethod.Post, new { id = "loginForm"}))
 {
       @Html.EditorFor(m => Model.Login)
 }

 @using(Html.BeginForm("Register", "Controller", FormMethod.Post, new { id = "registerForm"}))
 {
       @Html.EditorFor(m => Model.Register)
 }

【讨论】:

  • 仅供参考,您的第二个 POST 方法应该称为 Register。
  • 这部分 """ public class LoginOrRegisterViewModel { public Models.RegisterViewModel Register {get;set;} public Models.LoginViewModel Login {get;set;} """ 我把它放在我的模型类中??? }
  • 还有什么是 ""LoginOrRegister"
  • 我将第二个POST方法更新为Register,Tuan是正确的,是错字。 LoginOrRegisterViewModel 是一个类,它是一个模型或视图模型。这些通常放在您的模型文件夹中。 “LoginOrRegister”应该是“LoginOrRegisterViewModel”,我在提交之前重构了我的代码,并且在提交之前没有仔细检查所有名称。还有一种方法可以为两个单独的表单共享一个控制器操作,但它很脏并且涉及循环通过 ModelState 并删除与提交表单无关的错误。我会坚持拆分操作
  • 对我来说,我必须在两种 POST 方法上都使用 LoginOrRegisterViewModel 作为输入参数。仅将基础之一(注册/登录视图模型)作为参数在模型内部给出了空值。
【解决方案2】:

看起来您还需要在 !Verifyuser 分支中调用 IsAdmin,让它返回正确的视图:

        if (ModelState.IsValid)
        {

            if (LogModel.Login.Verifuser(Model.IDUser, Model.Password))
            {
                FormsAuthentication.SetAuthCookie(Model.IDUser, false);
                if (LogModel.Login.IsAdmin(Model.IDUser, Model.Password))
                {
                    return View("Admin/Index");
                }
                else
                {
                    return View("Agence/Index");
                }
            }
            else
            {
                ModelState.AddModelError("", "Invalide username or Password");

                if (LogModel.Login.IsAdmin(Model.IDUser, Model.Password))
                    return View("Admin/Index", Model);
                else
                    return View("Agence/Index", Model);

            }
        }

目前,当您遇到 ModelState 错误时,您正在调用 return View(Model);,这会返回操作的默认视图,称为“登录”。

【讨论】:

  • 这没用,有 confision beetwen 模型
  • 然后您需要将 Model 转换为 Index 视图所期望的类型,或者构造它,然后将其传递给 Model 到 View("Admin/Index") 和 View("Agence/Index") .
  • 我是初学者,我是 ASP.net MVC,你能解释一下吗?我没有明白这一点:'(
【解决方案3】:

如果您希望同时将多个表单发布到控制器操作,请使用客户端 JS 创建一个 JSON 对象,该对象为每个表单提供一个单独的属性,并为每个属性指定一个对应于您的相应 ProperCase 参数的驼峰式名称控制器动作。然后,将该 JSON 对象的序列化发送到您的控制器:

let form1 = $('#my-form1-id');
let form2 = $('#my-form2-id');
let url = 'myArea/myController/myAction'
let viewData = {
    controllerParameter1: form1,
    controllerParameter2: form2
};

$.ajax({

    url: url,
    type: 'POST',
    data: JSON.stringify(viewData),
    dataType: "json",
    beforeSend: function () {
        $('#my-submit-button-id').html('<i class="fa fa-2x fa-cog fa-spin"></i>');
        $('#my-submit-button-id').attr("disabled", "disabled");
    },
    success: function (res) {
        alert("Submitted!");
    },
    error: function (status, err) {
        alert("Failed!");
    },
    complete: function (status, err) {

        $('#my-submit-button-id').html('Submit My 2 Forms');
    }
});

这应该适用于带有类似于以下签名的控制器操作:

[HttpPost]
public virtual async Task<ActionResult> MyAction(ViewModel1 controllerParameter1, ViewModel2 controllerParameter2)
{
    // do amazing things
}

【讨论】:

    猜你喜欢
    • 2013-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-27
    • 1970-01-01
    相关资源
    最近更新 更多