【问题标题】:ASP .Net MVC 3: Child Action and RedirectASP .Net MVC 3:子动作和重定向
【发布时间】:2012-04-19 20:03:22
【问题描述】:

我需要在首页显示注册表单和登录表单。

如果这两个表单的验证失败,我需要在主页上显示正确的错误。

但如果没有错误,则必须将用户重定向到受保护的仪表板。

为此,我在主页上使用child action,如下所示:

@Html.Action("Register", "Membership")

如果出现任何错误,它可以按预期完美运行,因为它能够使用具有 validation state 信息的正确 model re-renderpartial view

但是如果没有错误,当它尝试重定向时,它会抛出一个错误,说明:

Child actions are not allowed to perform redirect actions.

有没有办法解决这个问题?我确信有一种方法可以将注册和登录表单放在主页上。很可能我不知道,因为我对 ASP .Net MVC 还很陌生。

你能给我指出正确的方向吗?

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-3 asp.net-mvc-2 razor child-actions


    【解决方案1】:

    一种方法是使用 ajax 表单作为登录和注册位,而不是在提交有效时返回 RedirectResult,而是返回一些客户端脚本会注意并使用的 json为你做一个重定向。

    这是一个简化的例子。

    控制器:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using System.ComponentModel.DataAnnotations;
    using MvcApplication12.Models;
    
    namespace MvcApplication12.Controllers
    {
        public class HomeController : Controller
        { 
            public ActionResult Index()
            {
                return View();
            }
    
            public ActionResult Register()
            {
                return PartialView(new UserDetails());
            }
    
            [HttpPost]
            public ActionResult Register(UserDetails details)
            {
                if (ModelState.IsValid)
                {
                    return Json(new {redirect = true, url = Url.Action("Index","Dashboard")});
                }
                else
                {
                    return PartialView(details); 
                }
            } 
        }
    }
    

    主页“索引”视图:

    @{
        ViewBag.Title = "Index";
    }
    <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
    <script type="text/javascript">
        function checkForRedirect(data)
        {
            if (data.redirect && data.url)
            {
                location.href = data.url;
            }
        }
    </script>
    
    <p>Home page stuff.....</p>
    
    <div id="RegistrationArea">
        @Html.Action("Register")
    </div>
    
    <p> Home page stuff.....</p>
    

    注册表单'Register'部分视图:

    @model MvcApplication12.Models.UserDetails
    <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
    
    @using (Ajax.BeginForm(new AjaxOptions()
    {
        HttpMethod = "POST",
        Url = Url.Action("Register", "Home"),
        OnSuccess = "checkForRedirect(data)",
        UpdateTargetId = "RegistrationArea",
        InsertionMode = InsertionMode.Replace
    }))
    {
        @Html.LabelFor(m => m.UserName)
        @Html.EditorFor(m => m.UserName) 
        @Html.ValidationMessageFor(m => m.UserName)
    
        @Html.LabelFor(m => m.Password)
        @Html.EditorFor(m => m.Password) 
        @Html.ValidationMessageFor(m => m.Password)
    
        <input type="submit" />
    }
    

    【讨论】:

      【解决方案2】:

      您不应在该上下文中使用子操作。

      解决您的问题的方法可能是 在您的页面中放置两张表格,一张用于注册,一张用于登录。注册表单发布到 Membership 控制器中的 Register 操作,登录操作发布到 Membership 控制器中的 Login 操作。

      如果其中一项操作发生错误,您可以:

      • 显示专用登录/注册页面并使用模型/验证结果显示错误消息
      • 重定向到用户来自的 URL/Action 并显示您在 TempData 中放置的错误消息

      【讨论】:

        【解决方案3】:

        不使用 javascript 进行重定向: 如果您将表单放在子视图中,有时如果您在 Beginform 助手(子视图内部)中指定操作名称和控制器名称,则不会发生此问题。例如,我像这样更改了我的子操作视图:

        之前:

        @using (Html.BeginForm())
        {
         ...
        }
        

        之后:

            @using (Html.BeginForm("InsertComment", "Comments", FormMethod.Post, new { id = "commentform" })) 
        {
         ...
        }
        

        现在,您可以将 RedirectAction 命令放入“InsertComment”操作中,一切都会正常进行。


        一页管理两种形式:

        1.为提交按钮指定名称(每个表单)(例如:“submitvalue”)

        表格1:

         <input type="submit" value="login" name="submitValue" class="btn btn-success pull-right" />
        

        表格2:

         <input type="submit" value="register" name="submitValue" class="btn btn-success pull-right" />
        

        2.为这些表格做两个动作。 (例如:“注册”和“登录”)

        [HttpPost]
             public ActionResult Login(LoginVM model, string submitValue)
                    {
                        if (submitValue == "login")
                        { 
                       //Do Something
                        }  
                         ...
                     }
        
        
        [HttpPost]
        public ActionResult Register(RegisterVM model, string submitValue)
                    {
                        if (submitValue == "register")
                        { 
                       //Do Something
                         }  
                        ...
                     }
        
        • 如果您单击表单中的注册或登录按钮,这两个操作都会被调用,但我们会通过“if”语句确定哪个是我们的目标。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多