MVC RedirectToAction through ajax jQuery call in k

2020-02-07 01:43发布

问题:

I am building a MVC3 web application and I am using knockoutjs. There are two views in the application. SetUpNewCompany and ManageAccount. To Set up a new company the user first enters the account number and clicks search. If the account number already exists the user can click on a button to go to the ManageAccount view. In the SetUpNewCompanyController I redirect using the RedirectToAction method. However, when the Index2 action in ManageAccount is executed the view is not displayed. If I type in the complete URL the view is displayed.

SetUpNewCompanyController.cs

[HttpPost]
 public RedirectToRouteResult RedirectToManageAccount(string accountNumber)
 {
        return RedirectToAction("Index2", new RouteValueDictionary(new {controller=
            "ManageAccount", companyId = "7e96b930-a786-44dd-8576-052ce608e38f" }));
 }

This above is called by the function below when a button is clicked

self.redirectToManageAccount = function () {
        var accountNumber = "7e96b930-a786-44dd-8576-052ce608e38f";
        $.ajax({
            type: "POST",
            url: "/SetUpNewCompany/RedirectToManageAccount",
            data: { accountNumber: accountNumber },
            success: function (data) {
            },
            error: function () {
            }
        });
 }

ManageAccountController.cs

public ActionResult Index2(String companyId)
    {
        var viewModel = new Models.Index();

        List<String> compList = new List<String>();
        compList.Add("MyCompany");

        List<String> usersList = new List<String>();
        usersList.Add("User1");

        viewModel.Users = usersList;
        viewModel.Companies = compList;
        viewModel.CompanyId = companyId;
        viewModel.Role = "Role1";

        return View("ManageAccount",viewModel);
    }

The URL that is generated is

http://localhost:53897/ManageAccount/Index2?companyId=7e96b930-a786-44dd-8576-
052ce608e38f

The console window in Firebug shows

GET http://localhost:53897/ManageAccount/Index2?companyId=7e96b930-a786-44dd-8576-
052ce608e38f 200 OK and the spinner keeps spinng

Also, how do I get the URL below instead of the one with querystring

http://localhost:53897/ManageAccount/Index2/7e96b930-a786-44dd-8576-052ce608e38f

回答1:

Since you use AJAX to call the RedirectToManageAccount action method, you are responsible for handling its response yourself and as your success handler function is empty, you are effectively ignoring whatever arrives as a response.

If you want to force a redirect from within the AJAX response handler, I suggest

  1. Modifying your action method as follows

    [HttpPost]
    public ActionResult RedirectToManageAccount(string accountNumber)
    {
        var redirectUrl = new UrlHelper(Request.RequestContext).Action("Index2", "ManageAccount", new { companyId = "7e96b930-a786-44dd-8576-052ce608e38f" });
        return Json(new { Url = redirectUrl });
    }
    
  2. Updating your AJAX call in this way

    self.redirectToManageAccount = function () {
      var accountNumber = "7e96b930-a786-44dd-8576-052ce608e38f";
      $.ajax({ type: "POST",
               url: "/SetUpNewCompany/RedirectToManageAccount",
               data: { accountNumber: accountNumber },
               dataType: 'json',
               success: function (response) {
                   window.location.href = response.Url;
               },
               error: function () {
               }
      });
    }
    

As for your second question:

Also, how do I get the URL below instead of the one with querystring http://localhost:53897/ManageAccount/Index2/7e96b930-a786-44dd-8576-052ce608e38f

You just have to define an appropriate route entry for this URL in your RegisterRoutes() function:

routes.MapRoute(null,
                "ManageAccount/Index2/{companyId}",
                new { controller = "ManageAccount",
                      action = "Index2" }                            
);

EDIT: As your AJAX call only serves to call an action method which causes a redirect, you can simplify it in a following way, provided you in this point (on the client side) know the companyId already:

self.redirectToManageAccount = function () {
    var companyId = "12345";
    window.location.href = '@(Html.ActionUri("Index2", "ManageAccount"))?companyId=' + companyId;
}

where I used this extension method

public static string ActionUri(this HtmlHelper html, string action, string controller)
{
    return new UrlHelper(html.ViewContext.RequestContext).Action(action, controller);
}