ASP.NET MVC Partial view ajax post?

2019-01-11 02:31发布

问题:

Index.html (View)

<div class="categories_content_container">
    @Html.Action("_AddCategory", "Categories")
</div>

_AddCategory.cshtml (PartialView)

<script>
    $(document).ready(function () {
        $('input[type=submit]').click(function (e) {
            e.preventDefault();
            $.ajax({
                type: "POST",
                url: '@Url.Action("_AddCategory", "Categories")',
                dataType: "json",
                data: $('form').serialize(),
                success: function (result) {
                    $(".categories_content_container").html(result);
                },
                error: function () {

                }
            });
        });
    });
</script>

@using (Html.BeginForm())
{
    // form elements
}

Controller

[HttpPost]
public ActionResult _AddCategory(CategoriesViewModel viewModel)
{
    if(//success)
    {
        // DbOperations...
        return RedirectToAction("Categories");
    }
    else
    {
        // model state is not valid...
        return PartialView(viewModel);
    }
}

Question: If operation is success I expect that redirect to another page (Categories). But no action, no error message. If operation is not success, it is working like my expected.

How can I do this? How can I route another page with using AJAX post?

回答1:

Don't redirect from controller actions that are invoked with AJAX. It's useless. You could return the url you want to redirect to as a JsonResult:

[HttpPost]
public ActionResult _AddCategory(CategoriesViewModel viewModel)
{
    if(//success)
    {
        // DbOperations...
        return Json(new { redirectTo = Url.Action("Categories") });
    }
    else
    {
        // model state is not valid...
        return PartialView(viewModel);
    }
}

and then on the client test for the presence of this url and act accordingly:

$.ajax({
    type: "POST",
    url: '@Url.Action("_AddCategory", "Categories")',
    data: $('form').serialize(),
    success: function (result) {
        if (result.redirectTo) { 
            // The operation was a success on the server as it returned
            // a JSON objet with an url property pointing to the location
            // you would like to redirect to => now use the window.location.href
            // property to redirect the client to this location
            window.location.href = result.redirectTo;
        } else {
            // The server returned a partial view => let's refresh
            // the corresponding section of our DOM with it
            $(".categories_content_container").html(result);
        }
    },
    error: function () {

    }
});

Also notice that I have gotten rid of the dataType: 'json' parameter from your $.ajax() call. That's extremely important as we are not always returning JSON (in your case you were never returning JSON so this parameter was absolutely wrong). In my example we return JSON only in the case of a success and text/html (PartialView) in the case of failure. So you should leave jQuery simply use the Content-Type HTTP response header returned by the server to automatically deduce the type and parse the result parameter passed to your success callback accordingly.



回答2:

The ajax call you made should not be able to redirect the whole page. It returns data to your asynchronous call only. If you want to perform a redirect, i

the javascript way to redirect is with window.location

So your ajax call should look like this:

<script>
    $(document).ready(function () {
        $('input[type=submit]').click(function (e) {
            e.preventDefault();
            $.ajax({
                type: "POST",
                url: '@Url.Action("_AddCategory", "Categories")',
                dataType: "json",
                data: $('form').serialize(),
                success: function (result) {
                    window.location='@Url.Action("Categories")';
                },
                error: function () {

                }
            });
        });
    });
</script>

In you action method, instead of returning a partial or redirect, return Json(true);

public ActionResult _AddCategory(CategoriesViewModel viewModel)
{
    if(//success)
    {
        return Json(true);
    }
    else
    {
        return Json(false);
    }
}