web-dev-qa-db-ja.com

UpdateTargetIdにビューを挿入する代わりに、ASP.NET MVC Ajax応答を取得して新しいページにリダイレクトする方法

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に読み込まれているため、ページ内にページが表示されます。私が考えている2つのこと:

  1. 私はこれを間違って設計しており、このタイプのアクションを異なる方法で処理する必要があります(ajaxを使用しない)。
  2. リダイレクト結果を返す代わりに、クライアント側でリダイレクトを行うJavaScriptを含むビューを返します。

誰もが#1にコメントを持っていますか?または、#2が適切なソリューションである場合、「リダイレクトjavascriptビュー」はどのようになりますか?

83
Jeff Widmer

JavascriptResultを使用してこれを実現できます。

リダイレクトするには:

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

現在のページをリロードするには:

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

最も単純なオプションのようです。

167
Ben Foster

URLを含むJSONを返し、クライアント側でJavaScriptを使用してwindow.locationを変更できます。私は、サーバーからJavaScript関数を呼び出すよりもこの方法を好みます。

サーバ側:

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

クライアント側:

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

もちろん、サーバー側でエラーが発生する可能性があるため、ロジックを追加できます。その場合、結果プロパティはこの状況を示し、リダイレクトを回避できます。

24

作成しようとしている動作は、AJAXを使用して実際に行うのが最善ではありません。 AJAXは、他のページに完全にリダイレクトするのではなく、ページの一部のみを更新したい場合に最適です。これは、AJAX本当に。

あなたが説明している動作でAJAXを使用しないことをお勧めします。

または、jquery Ajaxを使用してリクエストを送信し、リクエストの完了時にコールバックを指定することもできます。コールバックでは、失敗したか成功したかを判断し、成功すると別のページにリダイレクトできます。 jquery Ajaxの方がはるかに使いやすいことがわかりました。特に、とにかく他の目的で既にライブラリを使用しているからです。

Jquery ajax here に関するドキュメントを見つけることができますが、構文は次のとおりです。

jQuery.ajax( options )  

jQuery.get( url, data, callback, type)

jQuery.getJSON( url, data, callback )

jQuery.getScript( url, callback )

jQuery.post( url, data, callback, type)
12
Joseph

エレガントではありませんが、特定の状況で機能します。

コントローラー

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>
11
Valamas

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;
    }
});
5
christo8989

以下のように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");
            }
});
3
Hiren Patel

$。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'"上記のフィルターはそれをキャッチし、リダイレクトを行うために評価します。

これはどう :

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
Bimal Das

Ajaxログインフォームがあるため、これを行う必要がありました。ユーザーが正常にログインすると、他のページが証明書利用者へのリダイレクトを処理するため(STS 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);

    }
1
Ryan Mann

ベン・フォスターが言うように、あなたはJavascriptを返すことができ、目的のページにリダイレクトされます。

現在のページにページをロードするには:

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

新しいタブでページをロードするには:

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

正しい問題を解決する代わりに、ジョセフの最良の答えに満足していないと、彼はこれが間違ったユースケースだと言った。実際、たとえば、古いコードベースをajax化されたコードに変換しているときに、必要な場合は必要な場所がたくさんあります。プログラミングでは、言い訳はありません。なぜなら、そのすべての悪い開発者と良い開発者をコーディングしているのはあなただけではなく、あなたは一緒に仕事をしなければならないからです。そのため、Ajaxでリダイレクトをコーディングしないと、仲間の開発者がその解決策を強制することができます。すべてのAMDパターンサイトまたはmvc4を使用したいのと同じように、私の会社は1年間、それを避けることができます。

それでは、解決策について話しましょう。

私はajaxリクエストとレスポンスの処理を徹底的に行ってきましたが、最も簡単な方法は、ステータスコードをクライアントに送信し、それらのコードを理解するための1つの標準javascript関数を使用することでした。たとえばコード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を使用することについて、私はJquery ajaxを使用したいと思いますが、私は世界全体でAjax.BeginFormでいっぱいのアプリケーションがあり、もちろんそれをしませんでした。しかし、私はそれと共に生きなければなりません。

したがって、開始フォームにも成功コールバックがあります。コールバックを使用するためにjquery ajaxを使用する必要はありません Ajax.BeginForm、Calls Action、Returns JSON、OnSuccessでJSONオブジェクトにアクセスする方法JS関数?

ありがとう

0
Asif Ashraf

これらのメタリフレッシュタグの1つを挿入することにより、ajas呼び出しから非jsベースのリダイレクトを取得できます。これはここで動作しているようです:return Content("<meta http-equiv=\"refresh\" content=\"0;URL='" + @Url.Action("Index", "Home") + "'\" />");

注:メタリフレッシュはFirefoxによって自動的に無効にされるため、あまり有用ではないことがわかりました。

0
Vasily Hall

JavaScriptクラスからリダイレクトしている場合

同じビュー-異なるコントローラー

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

同じ見方ではない

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

ヘルパークラスを追加:

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( "Index"、 "Cement");

すべてのajaxリクエストをインターセプトするために、javascriptコードをグローバルjavascriptインクルードファイルまたはレイアウトファイルに追加します

<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
faisale