Как получить 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 и поэтому я в конечном итоге со страницей внутри страницы. Две вещи, о которых я думаю:




  1. либо я проектирую это
    неправильно и должно обрабатывать этот тип
    действие по-другому (не используя ajax).

  2. вместо возврата перенаправления
    результат, возвращает представление, которое имеет
    javascript в нем что делает
    перенаправление на стороне клиента.


есть ли у кого-нибудь комментарии к #1? Или если #2-Хорошее решение, что бы выглядело " перенаправление javascript view например?

599   14  

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

    Ничего не найдено.