UpdateTargetId에 뷰를 삽입하는 대신 새 페이지로 리디렉션하는 ASP.NET MVC Ajax 응답을 얻는 방법은 무엇입니까?


88

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 Index 뷰는 UpdateTargetId에로드되므로 페이지 내 페이지로 끝납니다. 내가 생각하는 두 가지 :

  1. 내가 이것을 잘못 설계하고 있으며 이러한 유형의 작업을 다르게 처리해야합니다 (ajax를 사용하지 않음).
  2. 리디렉션 결과를 반환하는 대신 클라이언트 측에서 리디렉션을 수행하는 자바 스크립트가있는 뷰를 반환합니다.

누구든지 # 1에 대한 의견이 있습니까? 또는 # 2가 좋은 해결책이라면 "자바 스크립트보기 리디렉션"은 어떤 모습일까요?

답변:


171

JavascriptResult이것을 달성하기 위해 사용할 수 있습니다 .

리디렉션하려면 :

return JavaScript("window.location = 'http://www.google.co.uk'");

현재 페이지를 다시로드하려면 :

return JavaScript("location.reload(true)");

가장 간단한 옵션 인 것 같습니다.


4
굉장 해요 .. 도와 줬어요.
CrazyCoderz 2011-08-21

1
동의합니다. 이것이 올바른 접근 방식입니다. 이 대답 stackoverflow.com/a/2841608/498969 는 기본 컨트롤러를 사용하여 기본적으로이 기능을 적용하는 방법을 보여줍니다.
Adam Spicer

@Ben Foster :이 찾아보기를 사용하여 URL http :: window.location ..을 열려고합니다. 나는 별도의 문제로이 게시 stackoverflow.com/questions/13896307/...
앤드 러스

30
프로젝트의 컨트롤러로 리디렉션하려면 Url 도우미를 사용할 수 있습니다. 예 :return JavaScript( "window.location = '" + Url.Action("Edit","Dispatch") + "'" );
Chris Morgan

2
짧은. 단순한. 우수한. 큰!
Vikram

30

URL과 함께 JSON을 반환하고 클라이언트 측에서 JavaScript를 사용하여 window.location을 변경할 수 있습니다. 저는 서버에서 JavaScript 함수를 호출하는 것보다이 방법을 선호하는데, 이것이 우려의 분리를 깨고 있다고 생각합니다.

서버 측:

return Json(new {result = "Redirect", url = Url.Action("ActionName", "ControllerName")});

고객 입장에서:

if (response.result == 'Redirect')
    window.location = response.url;

물론 서버 측에 오류가있을 수 있고이 경우 결과 속성이이 상황을 표시하고 리디렉션을 피할 수 있기 때문에 더 많은 논리를 추가 할 수 있습니다.


12

생성하려는 동작은 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)

그런 다음 삭제 작업에 대한 일반 POST를 수행하면 대부분의 경우 성공하고 홈 인덱스 페이지로 리디렉션 할 수 있습니다. 실패 할 경우 오류 메시지와 사용자가 취해야 할 적절한 조치와 함께 다른보기를 표시하십시오. 괜찮 으세요?
Jeff Widmer

예, 그게 더 말이되는 것 같네요.
Joseph

나는 이것을 Ajax 제출에서 Joseph의 권장 사항에 따라 일반 POST로 변환했습니다. 이것은 삭제 확인 메시지를 더 깔끔하게 처리 할 수있는 방법을 제공했기 때문에 실제로 더 잘 작동했습니다.
Jeff Widmer

12

우아하지는 않지만 특정 상황에서 나를 위해 작동합니다.

제어 장치

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>

2
우아하지 않은 이유는 무엇입니까? 강력하게 타이핑되고 명확하게 느껴집니다. 나는 그 접근 방식을 좋아합니다. +1
T-moty

6

사용 JavaScript은 확실히 일을 할 것입니다.

Content이것이 당신의 스타일이라면 사용할 수도 있습니다 .

예:

MVC 컨트롤러

[HttpPost]
public ActionResult AjaxMethod()
{
    return Content(@"http://www.google.co.uk");
}

자바 스크립트

$.ajax({
    type: 'POST',
    url: '/AjaxMethod',
    success: function (redirect) {
        window.location = redirect;
    }
});

감사합니다! 이것은 정말 나를 도왔습니다.

5

다음과 같이 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");
            }
});

2

이건 어때 :

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;
       }  
}

1

나는 ajax 로그인 양식을 가지고 있기 때문에 이것을해야했습니다. 사용자가 성공적으로 로그인하면 다른 페이지가 신뢰 당사자로 다시 리디렉션을 처리하기 때문에 새 페이지로 리디렉션하고 이전 요청을 종료합니다 (STS SSO 시스템이기 때문에).

그러나 중앙 로그인 홉이되는 자바 스크립트가 비활성화 된 상태에서도 작동하기를 원했기 때문에이 문제를 생각해 냈습니다.

    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);

    }

1

$ .ajaxSetup으로 들어오는 응답에 대해 일종의 ajax 응답 필터를 수행 할 수 있습니다 . 응답에 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'" 이면 필터 위의 필터가이를 포착하고 리디렉션을 평가합니다.


0

나는 올바른 문제를 수정하는 대신 Joseph의 베스트 답변에 만족하지 않고 이것이 잘못된 사용 사례라고 말했습니다. 실제로 예를 들어 오래된 코드베이스를 ajax화된 코드로 변환하는 경우 많은 곳이 있으며 거기에서 필요하면 필요합니다. 프로그래밍에는 변명의 여지가 없습니다. 코딩하는 사람뿐만 아니라 모든 개발자가 나쁘고 좋은 개발자와 함께 작업해야하기 때문입니다. 따라서 ajax에서 코드 리디렉션을 수행하지 않으면 동료 개발자가 이에 대한 솔루션을 갖도록 강요 할 수 있습니다. 내가 모든 AMD 패턴 사이트 또는 mvc4를 사용하는 것을 좋아하고, 우리 회사는 1 년 동안 저를 멀리 할 수 ​​있습니다.

이제 해결책에 대해 이야기합시다.

나는 지옥의 ajax 요청 및 응답 처리를 수행했으며 가장 간단한 방법은 상태 코드를 클라이언트에 보내고 해당 코드를 이해하는 하나의 표준 자바 스크립트 함수를 갖는 것입니다. 예제 코드 13을 단순히 보내면 리디렉션을 의미 할 수 있습니다.

따라서 {statusCode : 13, messsage : '/ home / logged-in'}과 같은 json 응답은 물론 {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.BeginForm의 $ .ajax intead 사용에 관해서는 Jquery ajax를 사용하고 싶습니다.하지만 결정을 내리기 위해 전 세계에서 내가 아닙니다. Ajax.BeginForm으로 가득 찬 응용 프로그램이 있으며 물론 그렇게하지 않았습니다. 하지만 나는 그것과 함께 살아야합니다.

따라서 시작 양식에도 성공 콜백이 있습니다. 콜백을 사용하기 위해 jquery ajax를 사용할 필요가 없습니다. 여기에 대해 Ajax.BeginForm, Calls Action, Returns JSON, OnSuccess JS 함수에서 JSON 객체에 액세스하려면 어떻게해야합니까?

감사


0

JavaScript 클래스에서 리디렉션하는 경우

동일한보기-다른 컨트롤러

<strike>window.location.href = `'Home'`;</strike>

같은 견해가 아니다

<strike>window.location.href = `'Index/Home'`;</strike>

0

도우미 클래스를 추가합니다.

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 ( "색인", "시멘트");

모든 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>


0

Ben Foster가 말했듯이 Javascript를 반환하면 원하는 페이지로 리디렉션됩니다.

현재 페이지에서 페이지를로드하려면 :

return JavaScript("window.location = 'http://www.google.co.uk'");'

새 탭에서 페이지를로드하려면 :

return JavaScript("window.open('http://www.google.co.uk')");

0

이러한 메타 새로 고침 태그 중 하나를 입력하여 ajax 호출에서 비 js 기반 리디렉션을 가져올 수 있습니다. 여기에서 작동하는 것 같습니다. return Content("<meta http-equiv=\"refresh\" content=\"0;URL='" + @Url.Action("Index", "Home") + "'\" />");

참고 : Firefox에서 메타 새로 고침이 자동으로 비활성화되어 유용하지 않다는 것을 발견했습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.