Я использую 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»?
источник
return JavaScript( "window.location = '" + Url.Action("Edit","Dispatch") + "'" );
Вы можете вернуть 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 может указать на эту ситуацию и избежать перенаправления.
источник
Поведение, которое вы пытаетесь создать, на самом деле не лучше всего делать с помощью 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)
источник
Хотя это не изящно, но в определенных ситуациях у меня работает.
Контроллер
if (RedirectToPage) return PartialView("JavascriptRedirect", new JavascriptRedirectModel("http://www.google.com")); else ... return regular ajax partialview
Модель
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>
источник
Использование
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; } });
источник
Вы можете просто написать в 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"); } });
источник
Как насчет этого :
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; } }
источник
Мне нужно было это сделать, потому что у меня есть форма входа в систему с помощью ajax. Когда пользователи успешно входят в систему, я перенаправляю на новую страницу и завершаю предыдущий запрос, потому что другая страница обрабатывает перенаправление обратно проверяющей стороне (потому что это система SSO STS).
Тем не менее, я также хотел, чтобы он работал с отключенным 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); }
источник
Вы можете просто сделать какой-то фильтр ответов 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'", указанный выше фильтр поймает это и оценит, чтобы выполнить перенаправление.
источник
Я не удовлетворен лучшим ответом Джозефа, вместо того, чтобы исправить правильную проблему, он сказал, что это неправильный вариант использования. На самом деле, есть много мест, например, если вы конвертируете старую кодовую базу в ajaxified, и там она вам НУЖНА, значит, она вам НУЖНА. В программировании нет оправдания, потому что не только вы кодите всех плохих и хороших разработчиков, и вы должны работать бок о бок. Так что, если я не кодирую перенаправление в ajax, мой коллега-разработчик может заставить меня найти решение для него. Точно так же, как мне нравится использовать все сайты с узором AMD или mvc4, и моя компания может удерживать меня от этого в течение года.
Итак, давайте поговорим о решении.
Я чертовски проделал обработку запросов и ответов ajax, и самый простой способ, который я обнаружил, - это отправить коды статуса клиенту и иметь одну стандартную функцию javascript для понимания этих кодов. Если я просто отправлю, например, код 13, это может означать перенаправление.
Итак, ответ json, например {statusCode: 13, messsage: '/ home / logged-in'}, конечно, предлагается множество вариантов, таких как {status: 'success', code: 13, url: '/ home / logged-in ', сообщение:' Вы вошли в систему '}
и т. д., так что на ваш выбор стандартные сообщения
Обычно я наследую от базового класса контроллера и выбираю стандартные ответы, подобные этому
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 intead для Ajax.BeginForm Я бы хотел использовать JQuery ajax, и я это делаю, но, опять же, это не я во всем мире, чтобы принимать решения. У меня есть приложение, полное Ajax.BeginForm, и, конечно, я этого не делал. Но я должен с этим жить.
Итак, в форме начала есть обратный вызов успеха, вам не нужно использовать jquery ajax для использования обратных вызовов. Что-то об этом здесь Ajax.BeginForm, Calls Action, Returns JSON, Как мне получить доступ к объекту JSON в моей функции OnSuccess JS?
Благодарность
источник
Если вы перенаправляете из класса JavaScript
тот же вид - другой контроллер
<strike>window.location.href = `'Home'`;</strike>
это не то же мнение
<strike>window.location.href = `'Index/Home'`;</strike>
источник
Добавьте вспомогательный класс:
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>
источник
Как говорит Бен Фостер, вы можете вернуть Javascripts, и он перенаправит вас на нужную страницу.
Чтобы загрузить страницу на текущей странице:
return JavaScript("window.location = 'http://www.google.co.uk'");'
Чтобы загрузить страницу в новой вкладке:
return JavaScript("window.open('http://www.google.co.uk')");
источник
Вы можете получить перенаправление не на основе js из вызова ajax, вставив один из этих мета-тегов обновления. Кажется, это работает:
return Content("<meta http-equiv=\"refresh\" content=\"0;URL='" + @Url.Action("Index", "Home") + "'\" />");
Примечание: я обнаружил, что мета-обновления автоматически отключаются Firefox, что делает это не очень полезным.
источник