Asp.Net MVC 2 - странное поведение: RedirectToAction и ValidationSummary не работают
Я работал с MVC 2 некоторое время, и я выполнил ReturnToAction, а также ValidationSummary - но это немного отличается тем, что мои кнопки "submit" являются элементами управления с помощью javascript/JQuery - я отлаживаю действие, и оно идет в правильную Действие контроллера, но как только оно проходит через RedirecToAction, ничего не происходит....
Моя вторая проблема заключается в том, что мой ValidationSummary не показывает - я запускаю тест, и когда он возвращает представление, когда ModelState является недействительным - ничего не отображается
Это проблема с моими кнопками / формами / отправить /JQuery?
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<script type="text/javascript">
$(function () {
/*stuff here to setup some JQuery Sortable lists*/
$("#UpdateButton").click(function () {
//create Arrays from JQuery Sortable List and go to Action for "submit" //processing
$.ajax({
url: '/Admin/SortedLists/',
data: { items: editedRoles, items2: $("#deleteList").sortable('toArray') },
type: 'POST',
traditional: true
});
});
//go to Action and just "Reload" the page
$("#UndoButton").click(function () {
//reload the page
var url = '<%= Url.Action("EditRoles") %>';
window.location.href = url;
});
$("#roleList, #deleteList").disableSelection();
$("#deleteList").hide();
});
function addNewRole() {
var text = $("#New_Role").val();
$("#roleList").append('<li id="-1~' + text + '" class="ui-state-default">' +
'<span class="ui-icon ui-icon-closethick"></span>' +
// '<span class="ui-icon ui-icon-arrowthick-2-n-s"></span>' +
'<input id="-1" type="text" value="' + text + '" />' +
'</li>');
$("#roleList").sortable('refresh');
}
</script>
<%= Html.ActionLink("Back", "Index") %>
<% using (Html.BeginForm()) { %>
<br />
<%= Html.Encode(ViewData["Message"]) %>
<%=Html.ValidationSummary(true, "Edit was unsuccessful. Please correct the errors and try again.")%>
<div class="demo">
<%=Html.TextBox("New Role", "New Role")%>
<a href="javascript:addNewRole()"> Add</a>
<br />
<br />
<ul id="roleList" class='droptrue'>
//create an unordered list with textboxes and a close icon
<%
foreach (var item in Model.Roles)
{%>
<li class="ui-state-default" id="<%=Html.AttributeEncode(item.Id)%>~<%=Html.AttributeEncode(item.Name)%>"><span class="ui-icon ui-icon-closethick"></span><%=Html.TextBox(item.Id.ToString(), item.Name, new {@id = item.Id})%></li>
<% } %>
</ul>
<ul id="deleteList" class='droptrue'>
</ul>
<br />
</div>
<input id="UpdateButton" type="submit" name="submitButton" value="Update" /><%= Html.ValidationMessage("UpdateButton", "*") %>
<input id="UndoButton" type="submit" name="submitButton" value="Undo" />
<% } %>
И контроллер выглядит так:
public AdminController()
{
var wrapper = new ModelStateWrapper(ModelState);
_rolesService = new RolesService(new RolesRepository(), new RolesValidator(wrapper, new DateValidator(wrapper)));
}
public ActionResult Index()
{
return View();
}
public ActionResult EditRoles()
{
var roles = _rolesService.FetchAllRoles();
return View(new AdminEditRolesViewModel(roles));
}
[HttpPost]
public ActionResult SortedLists(List<string> items, List<string> items2)
{
var roles = _rolesService.BuildRolesFromList(items);
var deletedRoles = _rolesService.BuildRolesFromList(items2);
//The Services have contain the ModelState, this is where errors happen
//ValidationSummary doesnt show anything
if (_rolesService.EditRoles(roles) == false)
{
roles = _rolesService.FetchAllRoles();
return View("EditRoles", new AdminEditRolesViewModel(roles));
}
if (_rolesService.DeleteRoles(deletedRoles) == false)
{
roles = _rolesService.FetchAllRoles();
return View("EditRoles", new AdminEditRolesViewModel(roles));
}
_rolesService.Save();
//This RedirecToAction is passed, but doesnt actually go to my Index()
return RedirectToAction("Index");
}
Мои службы обрабатывают такие вещи, как проверка, я передаю им ModelState и оболочку ModelStateDictionary и добавляю ошибки - я добавляю ошибки неправильно?
public bool DeleteRoles(IEnumerable<Role> deletedRoles)
{
//some work, if fails add error
_validator.AddError("UpdateButton",
"Role: " + role.Name +
" can not be deleted because Employees still use this";
return _validator.IsValid();
}
Спасибо за любую помощь - это сводит меня с толку
2 ответа
Это нормально для передачи через RedirectToAction() в отладчике. На самом деле он не будет выполнять перенаправление, пока не вернется из метода. Но действие вашего контроллера запущено. Вы просто ничего не видите, потому что ваш интерфейсный уровень представления, который является веб-страницей, ничего не делает для обработки обратного вызова, который устанавливает ваш ajax-вызов. Чтобы решить эту проблему, вы создадите функцию обратного вызова следующим образом:
$.ajax({
url: '/Admin/SortedLists/',
data: { items: editedRoles, items2: $("#deleteList").sortable('toArray') },
type: 'POST',
traditional: true,
success: function(data) {
alert(data);
}
});
Очевидно, что вы будете делать что-то более полезное с "данными", но мы пока просто показываем это.
ValidatorSummary не отображается, потому что метод, который его создает, не является вашим действием при POST. Он "стирается" с помощью RedirectToAction. Чтобы решить это, вы будете использовать что-то вроде этого:
return View("~/Views/Home/Index.aspx", model);
Это отправит пользователя прямо туда и сохранит ваше состояние модели, включая проверки.
Я думаю, у вас есть пара проблем.
- Перенаправление не происходит так, как вы ожидаете
Я думаю, это потому, что вы публикуете форму асинхронно с $.ajax()
вызов, но вы не обрабатываете возвращаемые значения. RedirectToAction
возвращает URL-адрес и код состояния HTTP 302 (может быть, 301, я забыл), который сообщает браузеру запросить возвращенный URL-адрес. Ваше действие контроллера возвращает HTTP-перенаправление асинхронному вызову javascript, который не обрабатывает его.
Вам нужно либо изменить свой JavaScript для отправки, либо обработать возвращаемое значение с помощью чего-то вроде .ajaxSuccess()
,
- ValidationSummary не отображается.
Ваш ValidationSummary не отображается по двум причинам. Во-первых, из-за того, что я только что описал возврат Ajax. Во-вторых, вы "потеряли" ModelState, когда вы сделали RedirectToAction
, Если вы явно не обработаете передачу ModelState (обычно экспортируя ее в TempData и импортируя ее в целевом действии), она будет потеряна при перенаправлении.