ASP .Net MVC 3: дочернее действие и перенаправление
Мне нужно отобразить регистрационную форму и форму входа на главной странице.
Если проверка не проходит в этих двух формах, мне нужно отобразить правильные ошибки на главной странице.
Но если ошибки не было, пользователь должен быть перенаправлен на защищенную панель мониторинга.
Для этого я использую child action
на домашней странице вот так:
@Html.Action("Register", "Membership")
Он работает отлично, как и ожидалось, если есть какие-либо ошибки, так как он может re-render
partial view
с надлежащим model
который имеет validation state
Информация.
Но если ошибки не было, то при попытке перенаправления выдается сообщение о том, что:
Child actions are not allowed to perform redirect actions.
Есть ли способ обойти это? Я уверен, что есть способ разместить формы регистрации и авторизации на главной странице. Скорее всего, я не знаю, так как я новичок в ASP .Net MVC.
Не могли бы вы указать мне правильное направление здесь?
3 ответа
Один из способов сделать это - использовать формы 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>
Регистрационная форма "Регистрация" частичный вид:
@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" />
}
Вы не должны использовать дочерние действия в этом контексте.
Решением вашей проблемы может быть размещение двух форм на вашей странице, одна для регистрации и одна для входа. Форма регистрации отправляет действие "Зарегистрировать" в контроллере "Членство", действие "Вход" отправляет действие "Вход в систему" в контроллере "Членство".
В случае возникновения ошибки в одном из действий вы можете:
- Показать выделенную страницу входа / регистрации и использовать результаты модели / проверки для отображения сообщений об ошибках
- Перенаправить на URL/ действие, с которого пришел пользователь, и показать сообщение об ошибке, которое вы помещаете в TempData
Без использования javascript для перенаправления: если вы помещаете формы в дочерние представления, иногда, если вы указываете имя действия и имя контроллера в помощнике Beginform (внутри дочернего представления), эта проблема не возникает. например, я изменил свой дочерний вид действия следующим образом:
До:
@using (Html.BeginForm())
{
...
}
После:
@using (Html.BeginForm("InsertComment", "Comments", FormMethod.Post, new { id = "commentform" }))
{
...
}
Теперь вы можете поместить команду RedirectAction в действие "InsertComment", и все будет работать.
Две формы на одной странице управления:
1. Укажите имя для кнопки "Отправить" (каждая форма) (например, "submitvalue")
Form1:
<input type="submit" value="login" name="submitValue" class="btn btn-success pull-right" />
form2:
<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" мы определяем, какой из них является нашей целью.