not able to navigate using RedirectToAction - visual-studio

I am notable to naviagate to another page using Redirect ie when result is false, then i would like to navigate to exception page which is not happening.
public ActionResult IsLoginExsit(CustomerDO loginData)
{
if (!string.IsNullOrEmpty(loginData.UserName) && !string.IsNullOrEmpty(loginData.Password))
{
bool result = Businesss.Factory.BusinessFactory.GetRegistrations().IsLoginExist(loginData.UserName, loginData.Password);
if (result)
{
CustomerDO custInfo = new CustomerDO();
JsonResult jsonResult = new JsonResult();
jsonResult.Data = loginData;
custInfo = Businesss.Factory.BusinessFactory.GetRegistrations().GetCustInfoByUserName(loginData.UserName);
SessionWrapper.SetInSession("CustomerID", custInfo.Id);
SessionWrapper.SetInSession("CustomerFirstName", custInfo.FirstName);
SessionWrapper.SetInSession("CustomerLastName", custInfo.LastName);
return jsonResult;
}
else
{
return RedirectToAction("UnAuthorized", "Exceptions");
}
}
return View();
}

You seem to be invoking this action using AJAX. If you want to redirect this should be done on the client side in the success callback of this AJAX call using window.location.href. So for example you could adapt your action so that in case of error it returns a JSON object containing the url to redirect to:
else
{
return Json(new { errorUrl = Url.Action("UnAuthorized", "Exceptions") });
}
and then inside your AJAX success callback:
success: function(result) {
if (result.errorUrl) {
window.location.href = result.errorUrl;
} else {
...
}
}

Related

Controller that returns JSON format not returning to target page

Why is it that my controller can't manage to go to the target Index page after logging in?
[HttpPost]
[ValidateAntiForgeryToken]
public JsonResult Login(FormCollection fc)
{
var isSuccess = false;
Array errors = null;
more code here...
return Json(new { infoMessage = errors, successMessage = "", Status = isSuccess, gotoUrl = string.Format("/MyAccounts/Index") }, JsonRequestBehavior.AllowGet);
}
The motive is to redirect the page to Index but it returns the Json result document instead.
Add return inside if statement
if(isSuccess == true) {
//return redirect to target page
}
else {
return Json(new { infoMessage = errors, successMessage = "", Status = isSuccess, gotoUrl = string.Format("/MyAccounts/Index") }, JsonRequestBehavior.AllowGet);
}
It won't go to any target page because you specified it to return a json. What you want is to redirect to an action.
return RedirectToAction("Index", "MyAccounts");

ASP.NET MVC Ajax Error returning view instead of ajax

I'm making an ASP.NET MVC call to a method via AJAX and the error throws an exception. I'd like the message of the exception to be passed back to the client, and I'd prefer not to have to catch the exception. Something like this:
[HttpPost]
public ActionResult AddUser(User user) {
if (UserIsValid(user)) {
return Json(new { resultText = "Success!" });
}
throw new Exception("The user was invalid. Please fill out the entire form.");
}
I'm seeing in my firebug response an HTML page
<!DOCTYPE html>
<html>
<head>
<title>"The user was invalid. Please fill out the entire form."</title>
.....
I'd like to not be forced to use a try catch block to do this. Is there a way to automatically get the jQuery $(document).ajaxError(function () {} to read in this exception message? Is this bad practice? Can I override the controller OnException? Or do I have to try/catch and return JSON?
Something like this would be nice:
$(document).ajaxError(function (data) {
alert(data.title);
});
You can do this with a custom filter:
$(document).ajaxError(function(event, jqxhr) {
console.log(jqxhr.responseText);
});
-
[HttpPost]
[CustomHandleErrorAttribute]
public JsonResult Foo(bool isTrue)
{
if (isTrue)
{
return Json(new { Foo = "Bar" });
}
throw new HttpException(404, "Oh noes...");
}
public class CustomHandleErrorAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
var exception = filterContext.Exception;
var statusCode = new HttpException(null, exception).GetHttpCode();
filterContext.Result = new JsonResult
{
JsonRequestBehavior = JsonRequestBehavior.AllowGet, //Not necessary for this example
Data = new
{
error = true,
message = filterContext.Exception.Message
}
};
filterContext.ExceptionHandled = true;
filterContext.HttpContext.Response.Clear();
filterContext.HttpContext.Response.StatusCode = statusCode;
filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
}
}
Somewhat inspired by this blogpost: http://www.prideparrot.com/blog/archive/2012/5/exception_handling_in_asp_net_mvc
Rather than handle an exception that was raised by the server, why not have a flag in the JSON response?
[HttpPost]
public ActionResult AddUser(User user) {
if (UserIsValid(user)) {
return Json(new { success = true, resultText = "Success!" });
}
return Json(new { success = false, resultText = "The user was invalid. Please fill out the entire form." });
}

Pass ViewModel + Parameter to action using ajax call

How do I pass a view model and another parameter to my action method using jquery ajax?
with what I'm doing now, the action method is not being called. I think the cause is probably because the parameters are not being passed correctly in the data object of the jquery ajax call:
jQuery ajax:
$('#form-login').submit(function (event) {
event.preventDefault();
$.ajax({
url: "/Account/LogOn/",
data: $('#form-login').serialize(),
contentType: 'application/json; charset=utf-8',
success: function (data) {
if (data.userAuthenticated) {
window.location.href = data.url;
} else {
formBlock.clearMessages();
displayError($('#errorcred').val());
}
},
error: function () {
formBlock.clearMessages();
displayError($('#errorserver').val());
}
});
});
Action method (which accepts the view model and another parameter):
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
// Validate the email and password
if (ModelState.IsValid)
{
if (MembershipService.ValidateUser(model.UserName, model.Password))
{
FormsService.SignIn(model.UserName, model.RememberMe);
if (Url.IsLocalUrl(returnUrl))
{
if (Request.IsAjaxRequest())
{
return Json(new { userAuthenticated = true, url = returnUrl, isRedirect = true });
}
else
{
return Redirect(returnUrl);
}
}
else
{
if (Request.IsAjaxRequest())
{
return Json(new { userAuthenticated = true, url = Url.Action("Index", "Home"), isRedirect = true });
}
else
{
return RedirectToAction("Index", "Home");
}
}
}
}
else
{
if (Request.IsAjaxRequest())
{
return Json(new { userAuthenticated = false, url = Url.Action("LogOn", "Account") });
}
else
{
ModelState.AddModelError("", adm.ErrorUserNamePassword);
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
Remove the following from the $.ajax call:
contentType: 'application/json; charset=utf-8',
You have specified application/json encoding but the $('#form-login').serialize() function is sending application/x-www-form-urlencoded content.
As far as sending the returnUrl parameter is concerned, you could simply read it from the form action where it should be present (if you used the Html.BeginForm() helper):
$.ajax({
url: this.action,
...
});
Also you probably want to rename the event variable with something else as this is a reserved word in javascript:
$('#form-login').submit(function (e) {
e.preventDefault();
...
});
The only way I have found to do this is to just include the second parameter in your viewmodel and continue to serialize your form the way you are doing now.

HttpPost with AJAX call help needed

what else do i need in my code please, I have this so far:
<script type="text/javascript">
function PostNewsComment(newsId) {
$.ajax({
url: "<%= Url.Action("AddCommentOnNews", "Home", new { area = "News" }) %>?newsId=" + newsId + "&newsComment=" + $("#textareaforreply").val(), success: function (data) {
$("#news-comment-content").html(data + $("#news-comment-content").html());
type: 'POST'
}
});
}
$("#textareaforreply").val("");
</script>
and
[HttpPost]
[NoCache]
public ActionResult AddCommentOnNews(int newsId, string newsComment)
{
if (!String.IsNullOrWhiteSpace(newsComment))
{
var currentUser = ZincService.GetUserForId(CurrentUser.UserId);
ZincService.NewsService.AddCommentOnNews(newsId, newsComment, currentUser.UserId);
Zinc.DataModels.News.NewsCommentsDataModel model = new DataModels.News.NewsCommentsDataModel();
var today = DateTime.UtcNow;
model.CommentDateAndTime = today;
model.NewsComment = newsComment;
model.Firstname = currentUser.Firstname;
model.Surname = currentUser.Surname;
model.UserId = CurrentUser.UserId;
return View("NewsComment", model);
}
return null;
}
<div class="actions-right">
<%: Html.Resource(Resources.Global.Button.Reply) %>
</div>
i have no idea how this works, because it is not working in FF???
and the other thing is i must not pass return null i must pass JSON false ???
any help please?
thanks
You should encode your request parameters. Right now you have concatenated them to the request with a strong concatenation which is a wrong approach. There's a property called data that allows you to pass parameters to an AJAX request and leave the proper url encoding to the framework:
function PostNewsComment(newsId) {
$.ajax({
url: '<%= Url.Action("AddCommentOnNews", "Home", new { area = "News" }) %>',
type: 'POST',
data: {
newsId: newsId,
newsComment: $('#textareaforreply').val()
},
success: function (data) {
$('#news-comment-content').html(data + $('#news-comment-content').html());
}
});
}
Also you haven't shown where and how you are calling this PostNewsComment function but if this happens on the click of a link or submit button make sure that you have canceled the default action by returning false, just like that:
$('#someLink').click(function() {
PostNewsComment('123');
return false;
});
and the other thing is i must not pass return null i must pass JSON false ???
You could have your controller action return a JsonResult in this case:
return Json(new { success = false });
and then inside your success callback you could test for this condition:
success: function (data) {
if (!data.success) {
// the server returned a Json result indicating a failure
alert('Oops something bad happened on the server');
} else {
// the server returned the view => we can go ahead and update our DOM
$('#news-comment-content').html(data + $('#news-comment-content').html());
}
}
Another thing you should probably be aware of is the presence of dangerous characters such as < or > in the comment text. To allow those characters I would recommend you build a view model and decorate the corresponding property with the [AllowHtml] attribute:
public class NewsViewModel
{
public int NewsId { get; set; }
[AllowHtml]
[Required]
public string NewsComment { get; set; }
}
Now your controller action will obviously take the view model as argument:
[HttpPost]
[NoCache]
public ActionResult AddCommentOnNews(NewsViewModel viewModel)
{
if (!ModelState.IsValid)
{
var currentUser = ZincService.GetUserForId(CurrentUser.UserId);
ZincService.NewsService.AddCommentOnNews(viewModel.NewsId, viewModel.NewsComment, currentUser.UserId);
var model = new DataModels.News.NewsCommentsDataModel();
var today = DateTime.UtcNow;
model.CommentDateAndTime = today;
model.NewsComment = newsComment;
model.Firstname = currentUser.Firstname;
model.Surname = currentUser.Surname;
model.UserId = CurrentUser.UserId;
return View("NewsComment", model);
}
return Json(new { success = false });
}

Ajax.BeginForm that can redirect to a new page

I have an #Ajax.BeginForm for my model which has a boolean value (#Html.CheckBoxFor). If this is checked, I want my HttpPost action to redirect to a new page. Otherwise I want it to just continue being an #Ajax.BeginForm and update part of the page.
Here is my HttpPost action (Note: Checkout is the boolean value in my model)
Controller:
[HttpPost]
public ActionResult UpdateModel(BasketModel model)
{
if (model.Checkout)
{
// I want it to redirect to a new page
return RedirectToAction("Checkout");
}
else
{
return PartialView("_Updated");
}
}
You could use JSON and perform the redirect on the client:
[HttpPost]
public ActionResult UpdateModel(BasketModel model)
{
if (model.Checkout)
{
// return to the client the url to redirect to
return Json(new { url = Url.Action("Checkout") });
}
else
{
return PartialView("_Updated");
}
}
and then:
#using (Ajax.BeginForm("UpdateModel", "MyController", new AjaxOptions { OnSuccess = "onSuccess", UpdateTargetId = "foo" }))
{
...
}
and finally:
var onSuccess = function(result) {
if (result.url) {
// if the server returned a JSON object containing an url
// property we redirect the browser to that url
window.location.href = result.url;
}
}

Resources