Как получить 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"));
}
но представление индекса домашнего контроллера загружается в UpdateTargetId и поэтому я в конечном итоге со страницей внутри страницы. Две вещи, о которых я думаю:
- либо я проектирую это
неправильно и должно обрабатывать этот тип
действие по-другому (не используя ajax). - вместо возврата перенаправления
результат, возвращает представление, которое имеет
javascript в нем что делает
перенаправление на стороне клиента.
есть ли у кого-нибудь комментарии к #1? Или если #2-Хорошее решение, что бы выглядело " перенаправление javascript view например?
14 ответов:
можно использовать
JavascriptResultдля достижения этой цели.до переадресации:
return JavaScript("window.location = 'http://www.google.co.uk'");перезагрузить текущую страницу:
return JavaScript("location.reload(true)");кажется самый простой вариант.
вы можете вернуть JSON с URL-адресом и изменить окно.местоположение с помощью JavaScript на стороне клиента. Я предпочитаю этот способ, чем вызов функции JavaScript с сервера, который, как мне кажется, нарушает разделение проблем.
сервер:
return Json(new {result = "Redirect", url = Url.Action("ActionName", "ControllerName")});клиентской стороне:
if (response.result == 'Redirect') window.location = response.url;конечно, вы можете добавить больше логики, потому что на стороне сервера может быть ошибка, и в этом случае свойство result может указывать на эту ситуацию и избегать переадресация.
поведение, которое вы пытаетесь создать, на самом деле не лучше всего использовать 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 успех, как показано ниже:
$.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"); } });
Мне нужно было сделать это, потому что у меня есть форма входа 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; } });Если данные: окно".location = '/ Acount / Login'" выше фильтр поймает это и оценить, чтобы сделать перенаправление.
Я не удовлетворен лучшим ответом Джозефа, вместо того, чтобы исправить правильную проблему, он сказал, что это неправильный случай использования. На самом деле есть много мест, например, если вы конвертируете старую кодовую базу в ajaxified код, и там вам это нужно, тогда вам это нужно. В программировании нет оправдания, потому что это не только вы, кто кодирует его все плохие и хорошие разработчики, и вы должны работать бок о бок. Поэтому, если я не кодирую перенаправление в ajax, мой коллега-разработчик может заставить меня иметь решение для него. Так же, как мне нравится использовать все сайты AMD pattern или mvc4, и моя компания может держать меня от него в течение года.
Итак, давайте поговорим о решение сейчас.
Я сделал адскую обработку запросов и ответов ajax, и самый простой способ, который я узнал, - это отправить коды состояния клиенту и иметь одну стандартную функцию javascript для понимания этих кодов. Если я просто отправлю, например, код 13, это может означать перенаправление.
Итак, ответ json как { состояния: 13, сообщение: '/главная/вход в } конечно, есть тонны вариантов, предлагаемых как { статус: "успех", код: 13, URL-адрес: '/дом/вошедшего в', сообщение: 'Вы не вошли в систему теперь' }
и т. д. , Поэтому до вашего собственного выбора стандартных сообщений
обычно я наследую от базового класса контроллера и ставлю свой выбор стандартных ответов следующим образом
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); }об использовании $.Аякс вместо Аякса.BeginForm Я хотел бы использовать jQuery AJAX и я делаю, но опять это не я во всем мире принимаю решения У меня есть приложение, полное Ajax.BeginForm и, конечно же, я этого не делал. Но я должен жить с этим.
таким образом, есть успешный обратный вызов в форме begin, вам не нужно использовать jQuery ajax для использования обратных вызовов Что-то об этом здесь "Аякса".BeginForm, вызывает действие, возвращает 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)); } }затем вызовите свое действие:
этого.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, поместив один из этих тегов meta refresh. Это здесь, кажется, работает:
return Content("<meta http-equiv=\"refresh\" content=\"0;URL='" + @Url.Action("Index", "Home") + "'\" />");Примечание: я обнаружил, что мета-обновления автоматически отключаются Firefox, что делает это не очень полезным.
как насчет этого :
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; } }
Comments