Как получить ответ ASP.NET MVC Ajax для перенаправления на новую страницу вместо того, чтобы вставлять представление в UpdateTargetId?
Я использую Ajax.BeginForm для создания формы, которая будет делать обратную передачу ajax для определенного действия контроллера, а затем, если действие будет успешным, пользователь должен перенаправляться на другую страницу (если действие не выполняется, тогда сообщение состояния отображается с помощью AjaxOptions UpdateTargetId).
using (Ajax.BeginForm("Delete", null,
new { userId = Model.UserId },
new AjaxOptions { UpdateTargetId = "UserForm", LoadingElementId = "DeletingDiv" },
new { name = "DeleteForm", id = "DeleteForm" }))
{
[HTML DELETE BUTTON]
}
Если удаление выполнено успешно, я возвращаю результат переадресации:
[Authorize]
public ActionResult Delete(Int32 UserId)
{
UserRepository.DeleteUser(UserId);
return Redirect(Url.Action("Index", "Home"));
}
Но представление индекса Home Controller загружается в UpdateTargetId, и поэтому я получаю страницу на странице. Две вещи, о которых я думаю:
- Либо я занимаюсь архитектурой
неправильно и должен обрабатывать этот тип
действие по-разному (не используя ajax).
- Вместо того, чтобы возвращать перенаправление
результата, верните представление, которое
javascript, в котором выполняется
перенаправлять на стороне клиента.
Есть ли у кого есть комментарии к # 1? Или, если # 2 - хорошее решение, как выглядит "переадресация JavaScript-просмотра"?
Ответы
Ответ 1
Вы можете использовать JavascriptResult
для достижения этой цели.
Чтобы перенаправить:
return JavaScript("window.location = 'http://www.google.co.uk'");
Чтобы перезагрузить текущую страницу:
return JavaScript("location.reload(true)");
Самый простой вариант.
Ответ 2
Вы можете вернуть JSON с URL-адресом и изменить window.location с помощью JavaScript на стороне клиента. Я предпочитаю этот способ, чем вызов функции JavaScript с сервера, что, по моему мнению, нарушает разделение проблем.
Серверная сторона:
return Json(new {result = "Redirect", url = Url.Action("ActionName", "ControllerName")});
Клиентская сторона:
if (response.result == 'Redirect')
window.location = response.url;
Конечно, вы можете добавить больше логики, потому что на стороне сервера может быть ошибка, и в этом случае свойство result может указывать на эту ситуацию и избегать перенаправления.
Ответ 3
Поведение, которое вы пытаетесь создать, на самом деле не лучше, если использовать AJAX. AJAX лучше всего использовать, если вы хотите обновить часть страницы, а не полностью перенаправить на другую страницу. Это на самом деле побеждает всю цель AJAX.
Я бы предложил просто не использовать AJAX с описанным вами поведением.
В качестве альтернативы вы можете попробовать использовать jquery Ajax, который отправит запрос, а затем вы укажете обратный вызов, когда запрос будет завершен. В обратном вызове вы можете определить, не удалось или не удалось, и перенаправить на другую страницу с успехом. Я нашел jquery Ajax намного проще в использовании, тем более, что я уже пользуюсь библиотекой для других вещей.
Вы можете найти документацию о jquery ajax здесь, но синтаксис выглядит следующим образом:
jQuery.ajax( options )
jQuery.get( url, data, callback, type)
jQuery.getJSON( url, data, callback )
jQuery.getScript( url, callback )
jQuery.post( url, data, callback, type)
Ответ 4
Пока не элегантный, работает для меня в определенных ситуациях.
контроллер
if (RedirectToPage)
return PartialView("JavascriptRedirect", new JavascriptRedirectModel("http://www.google.com"));
else
... return regular ajax partialview
Model
public JavascriptRedirectModel(string location)
{
Location = location;
}
public string Location { get; set; }
/Views/Shared/JavascriptRedirect.cshtml
@model Models.Shared.JavascriptRedirectModel
<script type="text/javascript">
window.location = '@Model.Location';
</script>
Ответ 5
Использование JavaScript
обязательно выполнит задание.
Вы также можете использовать Content
, если это больше ваш стиль.
Пример:
MVC-контроллер
[HttpPost]
public ActionResult AjaxMethod()
{
return Content(@"http://www.google.co.uk");
}
Javascript
$.ajax({
type: 'POST',
url: '/AjaxMethod',
success: function (redirect) {
window.location = redirect;
}
});
Ответ 6
Вы можете просто написать в Ajax Success, как показано ниже:
$.ajax({
type: "POST",
url: '@Url.Action("GetUserList", "User")',
data: { id: $("#UID").val() },
success: function (data) {
window.location.href = '@Url.Action("Dashboard", "User")';
},
error: function () {
$("#loader").fadeOut("slow");
}
});
Ответ 7
Мне нужно было сделать это, потому что у меня есть форма входа в систему ajax. Когда пользователи успешно подключаются, я перенаправляюсь на новую страницу и заканчиваю предыдущий запрос, потому что другая страница обрабатывает перенаправление обратно полагающейся стороне (потому что это система SSO SSO).
Однако я также хотел, чтобы он работал с отключенным javascript, являющимся центральным хостом для входа и всеми, поэтому я придумал это,
public static string EnsureUrlEndsWithSlash(string url)
{
if (string.IsNullOrEmpty(url))
throw new ArgumentNullException("url");
if (!url.EndsWith("/"))
return string.Concat(url, "/");
return url;
}
public static string GetQueryStringFromArray(KeyValuePair<string, string>[] values)
{
Dictionary<string, string> dValues = new Dictionary<string,string>();
foreach(var pair in values)
dValues.Add(pair.Key, pair.Value);
var array = (from key in dValues.Keys select string.Format("{0}={1}", HttpUtility.UrlEncode(key), HttpUtility.UrlEncode(dValues[key]))).ToArray();
return "?" + string.Join("&", array);
}
public static void RedirectTo(this HttpRequestBase request, string url, params KeyValuePair<string, string>[] queryParameters)
{
string redirectUrl = string.Concat(EnsureUrlEndsWithSlash(url), GetQueryStringFromArray(queryParameters));
if (request.IsAjaxRequest())
HttpContext.Current.Response.Write(string.Format("<script type=\"text/javascript\">window.location='{0}';</script>", redirectUrl));
else
HttpContext.Current.Response.Redirect(redirectUrl, true);
}
Ответ 8
Вы можете просто сделать какой-то фильтр ответа ajax для входящих ответов с $. ajaxSetup. Если ответ содержит перенаправление MVC, вы можете оценить это выражение на стороне JS. Пример кода для JS ниже:
$.ajaxSetup({
dataFilter: function (data, type) {
if (data && typeof data == "string") {
if (data.indexOf('window.location') > -1) {
eval(data);
}
}
return data;
}
});
Если данные: "window.location = '/Acount/Login" над фильтром поймает это и оценит, чтобы сделать перенаправление.
Ответ 9
Я не удовлетворен лучшим ответом Джозефа, вместо того, чтобы исправить правильную проблему, он сказал, что это неправильный вариант использования. На самом деле, есть много мест, например, если вы конвертируете старую базу кода в ajaxified код и там вам это нужно, тогда вам это нужно. В программировании нет оправдания, потому что не только вы, кто кодирует его всех плохих и хороших разработчиков, и вам приходится работать бок о бок. Поэтому, если я не перенаправляю код в ajax, мой коллега-разработчик может заставить меня иметь решение для него. Точно так же, как мне нравится использовать все шаблонные сайты AMD или mvc4, и моя компания может удержать меня от нее в течение года.
Итак, давайте поговорим о решении сейчас.
Я отлично справился с обработкой и обработкой ajax и самым простым способом, который я узнал, было отправить коды статуса клиенту и иметь одну стандартную функцию javascript для понимания этих кодов. Если я просто отправлю, например, код 13, это может означать перенаправление.
Итак, ответ json вроде {statusCode: 13, messsage: '/home/logged-in'}
конечно, есть тонны вариантов, предложенных как
{status: 'success', code: 13, url: '/home/logged-in', message: 'Вы вошли в систему'}
и т.д., поэтому до вашего собственного выбора стандартных сообщений
Обычно я наследую от базового класса Controller и ставил свой выбор стандартных ответов вроде этого
public JsonResult JsonDataResult(object data, string optionalMessage = "")
{
return Json(new { data = data, status = "success", message = optionalMessage }, JsonRequestBehavior.AllowGet);
}
public JsonResult JsonSuccessResult(string message)
{
return Json(new { data = "", status = "success", message = message }, JsonRequestBehavior.AllowGet);
}
public JsonResult JsonErrorResult(string message)
{
return Json(new { data = "", status = "error", message = message }, JsonRequestBehavior.AllowGet);
}
public JsonResult JsonRawResult(object data)
{
return Json(data, JsonRequestBehavior.AllowGet);
}
Об использовании $.ajax для Ajax.BeginForm
Я хотел бы использовать Jquery ajax, и я это делаю, но опять же не мне во всем мире принимать решения
У меня есть приложение, полное Ajax.BeginForm, и, конечно же, я этого не делал. Но я должен жить с ним.
Итак, в начале формы также есть обратный вызов успеха, вам не нужно использовать jquery ajax для использования обратных вызовов
Что-то об этом здесь
Ajax.BeginForm, вызывает действие, возвращает JSON, Как мне получить доступ к объекту JSON в моей функции JS OnSuccess?
Спасибо
Ответ 10
Если вы перенаправляетесь из класса JavaScript
тот же вид - различный контроллер
<strike>window.location.href = `'Home'`;</strike>
- не тот же вид
<strike>window.location.href = `'Index/Home'`;</strike>
Ответ 11
Добавить класс-помощник:
public static class Redirector {
public static void RedirectTo(this Controller ct, string action) {
UrlHelper urlHelper = new UrlHelper(ct.ControllerContext.RequestContext);
ct.Response.Headers.Add("AjaxRedirectURL", urlHelper.Action(action));
}
public static void RedirectTo(this Controller ct, string action, string controller) {
UrlHelper urlHelper = new UrlHelper(ct.ControllerContext.RequestContext);
ct.Response.Headers.Add("AjaxRedirectURL", urlHelper.Action(action, controller));
}
public static void RedirectTo(this Controller ct, string action, string controller, object routeValues) {
UrlHelper urlHelper = new UrlHelper(ct.ControllerContext.RequestContext);
ct.Response.Headers.Add("AjaxRedirectURL", urlHelper.Action(action, controller, routeValues));
}
}
Затем вызовите свое действие:
this.RedirectTo( "Индекс", "Цемент" );
Добавьте код javascript в любой глобальный файл или файл макета, содержащий javascript, чтобы перехватить все запросы ajax:
<script type="text/javascript">
$(function() {
$(document).ajaxComplete(function (event, xhr, settings) {
var urlHeader = xhr.getResponseHeader('AjaxRedirectURL');
if (urlHeader != null && urlHeader !== undefined) {
window.location = xhr.getResponseHeader('AjaxRedirectURL');
}
});
});
</script>
Ответ 12
Поскольку ben foster говорит, что вы можете вернуть Javascripts, и он перенаправит вас на нужную страницу.
Загрузка страницы на текущей странице:
return JavaScript("window.location = 'http://www.google.co.uk'");'
Чтобы загрузить страницу на новой вкладке:
return JavaScript("window.open('http://www.google.co.uk')");
Ответ 13
Вы можете перенаправить перенаправление на основе js-js из вызова ajax, поставив один из этих тегов meta refresh. Кажется, что это работает:
return Content("<meta http-equiv=\"refresh\" content=\"0;URL='" + @Url.Action("Index", "Home") + "'\" />");
Примечание. Я обнаружил, что мета-обновления автоматически отключены Firefox, что делает это не очень полезным.
Ответ 14
Как насчет этого:
public ActionResult GetGrid()
{
string url = "login.html";
return new HttpStatusCodeResult(System.Net.HttpStatusCode.Redirect,url)
}
И затем
$(document).ajaxError(function (event, jqxhr, settings, thrownError) {
if (jqxhr.status == 302) {
location.href = jqxhr.statusText;
}
});
Или
error: function (a, b, c) {
if (a.status == 302) {
location.href = a.statusText;
}
}