user1778158
user1778158

Reputation: 93

Asp.Net Core 2.0 RedirectToAction not working after post

I am new to MVC. Here is the gist of what I am doing on my View:

Display Identity User with their assigned User Roles.

Clone User Roles portion of page:

Have a SelectList where the end-user can select some other Identity User.

Display that selected user's current User Roles - I have this working in a Partial View.

Have a Clone User button and onclick remove all User Roles for the currently displayed user and then add them to all the Roles that the selected user from the SelectList is assigned to.

I have the View working the way I want it to with one exception - after changing the user's Identity Roles (via clicking the Clone User link) the portion of my View does not refresh to show the new Roles. In my ViewModel that would be UserRoles. If I press CTRL+F5 to refresh then I see the newest Roles.

Here is my ViewModel:

public ApplicationUser AppUser { get; set; }
public TblEmployee Employee { get; set; }
[Display(Name = "User Roles")]
public List<Tuple<string, string>> UserRoles { get; set; }
[Display(Name = "Available Roles")]
public List<Tuple<string, string>> AllRoles { get; set; }
[Display(Name = "Select Employee")]
public List<SelectListItem> EmployeeList { get; set; }

I have a link on my page:

<a id="uxCloneUserButton" class="hidden">
    <i class="glyphicon glyphicon-duplicate"></i>  &nbsp;Clone User
</a>

And then in my script in my View I have the following:

$('#uxCloneUserButton').click(function () {
    var selectedId = $('#uxEmployeeSelect').val();
    var appUserId = $('#uxHiddenAppUserId').val();
    var url = '@Url.Action("CloneUser", "ApplicationUser")';

    //post id and username to controller action
    $.post(url, { id: appUserId, cloneUserId: selectedId }, function (data) {
    });
});

I get to the Action on my Controller with the proper parameters and it is working fine. In my Controller I have this:

[HttpPost]
public async Task<IActionResult> CloneUser(string id, string cloneUserId)
{   
    ApplicationUser currentUser = await _userManager.FindByIdAsync(id);
    ApplicationUser cloneUser = await _userManager.FindByIdAsync(cloneUserId);
    //Remove currentUser from all current roles
    var currentUserRoles = await _userManager.GetRolesAsync(currentUser);
    if (currentUserRoles.Count > 0)
        await _userManager.RemoveFromRolesAsync(currentUser, currentUserRoles.ToArray());
    var cloneUserRoles = await _userManager.GetRolesAsync(cloneUser);
    if (cloneUserRoles.Count > 0)
        await _userManager.AddToRolesAsync(currentUser, cloneUserRoles.ToArray());               
    return RedirectToAction(nameof(Details), new { id = id });            
}

Your help is greatly appreciated. I just need this portion of the page to refresh after the click and I am all set.

UPDATE

I was able to get it working, but my solution doesn't feel like a good one.

I added a string to my ViewModel:

public string JSRedirectLocation { get; set; }

I set the property in my Details Action where I assign all of my VM properties:

//Redirect location
model.JSRedirectLocation = "/ApplicationUser/Details/" + model.AppUser.Id;

I changed my JavaScript to redirect after post:

//post id and username to controller action
$.post(url, { id: appUserId, cloneUserId: selectedId }, function (data) {
    window.location = '@Model.JSRedirectLocation';
});

Can somebody tell me if I should be doing this some cleaner way, please? This solution seems to me to be redundant and feels like a workaround. Thanks.

Upvotes: 2

Views: 2702

Answers (1)

Mohammad Akbari
Mohammad Akbari

Reputation: 4766

Your request is ajax call, for this you must return json and then handle response redirect to target.So in action use :

[HttpPost]
public async Task<IActionResult> CloneUser(string id, string cloneUserId)
{   
    //.. your code

    var redirectUrl = Url.Action(nameof(Details), new { id = id });

    return Json(new {
        redirectUrl = redirectUrl
    }); 
}

and in ajax call use following code:

$.post(url, { id: appUserId, cloneUserId: selectedId }, function (data) {
    window.location = data.redirectUrl;
});

Upvotes: 3

Related Questions