Get a successful Ajax action to open another popup
Right now I'm trying to have an Ajax window open another window on completion. Basically, the first window asks if the user wants to do something and the second tells them it was successful. The first needs a yes or no and the second just needs an ok. How do I tell the Ajax Actionlink to open another one when its done? I'm working in MVC 3 with C#.
Right now my ActionLink is:
@Ajax.ActionLink("Reset User Password", "ResetUserPW", "Admin",
new { userName = Model.UserName },
new AjaxOptions { Confirm = "Reset Password?", HttpMethod = "HttpGet" })
This works fine (I know there is no OnSuccess bit, that fact is mentioned later). It executes the logic fine and resets the user's password. I just can't figure out how to get it to open another window. Here's my Controller Action:
public ActionResult ResetUserPW(string userName)
{
string newExcept;
MembershipUser user = Membership.GetUser(userName);
if (user != null)
{
try
{
string newPassword = Membership.GeneratePassword(8, 2);
if (user.ChangePassword(user.GetPassword(), newPassword))
{
var mailMessage = new UserMailer();
return PartialView();
//return RedirectToAction("Users"); //Tried this return
result, no go
}
else
{
const string ErroExcept = "There was an error processing your request (the password reset has failed). Please try again.";
ModelState.AddModelError("", ErroExcept);
}
}
catch (Exception ex)
{
newExcept = String.Format("There was an error processing your request({0}). Please try again.", ex.Message);
ModelState.AddModelError("", newExcept);
}
}
else
{
newExcept = "There is no record of the specified user in the database.";
ModelState.AddModelError("", newExcept);
}
return RedirectToAction("Use开发者_开发百科rs");
}
It never gets to the last line of code since it executes correctly. There are no data tags at the top, though I have tried changing the HttpMethod to a POST one and adding the POST tag. Also, I am very much so aware that there is no OnSuccess or OnCompletion in the ActionLink. I tried putting a whole lot of different things in there and got no results, so I trimmed them. And after all, the entire question is what do I put in the OnSuccess = area?
I'm not too great or familiar with JQuery and I think thats why this is so hard for me to solve. I've searched exhaustively and written tons of different types of JQuery code, but could not use any of them with the Ajax link. The Controller action accepts the userName since the Admin does this action and will need to do it for all users (said to stop the inevitable: "You can get the user's user name with User.Identity.name" statement). Also, tell me if trimming the exceptions and ModelState code would be helpful. Thanks in advance.
Final Solution:
public ActionResult ResetUserPW(string userName)
{
string newExcept;
MembershipUser user = Membership.GetUser(userName);
if (user != null)
{
try
{
string newPassword = Membership.GeneratePassword(8, 2);
if (user.ChangePassword(user.GetPassword(), newPassword))
{
var mailMessage = new UserMailer();
mailMessage.AdminPWReset(user.UserName, newPassword, user.Email.SendAsync();
return Json(null);
}
else
{
ModelState.AddModelError("Password", "There was an error processing your request (the password reset has failed). Please try again");
}
}
catch (Exception ex)
{
ModelState.AddModelError("Password", String.Format("There was an error processing your request ({0}). Please try again.", ex.Message));
}
}
else
{
ModelState.AddModelError("Invalid User", "There is no record of the specified user in the database.");
}
if (!ModelState.IsValid)
{
return Json(GetModelStateErrors(ModelState));
}
return Json(null);
}
There are no verbs at the top. GetModelStateErrors is defined as such:
private IEnumerable<ModelStateError> GetModelStateErrors(ModelStateDictionary dictionary)
{
foreach(var key in dictionary.Keys)
{
var error = dictionary[key].Errors.FirstOrDefault();
if(error != null)
yield return new ModelStateError(key, error.ErrorMessage);
}
}
And finally, the Ajax link is:
@Ajax.ActionLink("Reset User Password", "ResetUserPW", "Admin",
new { userName = Model.UserName },
new AjaxOptions {
Confirm = "Reset Password?",
HttpMethod = "HttpGet",
OnSuccess="success"
})
Whoopsies, forgot to add the final Javascript I used. Its the same as the one gram said:
<script type="text/javascript">
function success(data) {
alert('You have successfully reset the user\'s password!');
}
</script>
You can put a javascript callback in OnSuccess that will run if the AjaxLink call returns a non-error status, like so:
<script src="../../Scripts/jquery.unobtrusive-ajax.min.js"></script>
<script type="text/javascript">
function success(data) {
alert('Your password was reset');
}
</script>
@Ajax.ActionLink("Reset User Password", "ResetUserPW", "Admin",
new { userName = Model.UserName },
new AjaxOptions { Confirm = "Reset Password?", HttpMethod = "HttpPost", OnSuccess = "success" })
But you need a way to return validation errors. So I would try something like this:
[HttpPost]
public ActionResult ResetUserPW(string userName) {
string newExcept;
MembershipUser user = Membership.GetUser(userName);
if (user != null) {
try {
string newPassword = Membership.GeneratePassword(8, 2);
if (user.ChangePassword(user.GetPassword(), newPassword)) {
var mailMessage = new UserMailer();
}
else {
ModelState.AddModelError("Password", "There was an error processing your request (the password reset has failed). Please try again.");
}
}
catch (Exception ex) {
ModelState.AddModelError("Password", String.Format("There was an error processing your request({0}). Please try again.", ex.Message));
}
}
else {
ModelState.AddModelError("Password", "There is no record of the specified user in the database.");
}
if (!ModelState.IsValid)
return Json(GetModelStateStateErrors(ModelState));
return Json(null);
}
private IEnumerable<ModelStateError> GetModelStateStateErrors(ModelStateDictionary dictionary) {
foreach (var key in dictionary.Keys) {
var error = dictionary[key].Errors.FirstOrDefault();
if (error != null)
yield return new ModelStateError(key, error.ErrorMessage);
}
}
with a simple DTO for ModelState:
public class ModelStateError {
public string Property { get; set; }
public string Error { get; set; }
public ModelStateError(string key, string value) {
this.Property = key;
this.Error = value;
}
}
If there are no validation errors, the data
parameter in success
will be null, otherwise, it will contain an array of validation errors that you can present to the user however you want.
精彩评论