MVC Redirecting Action using Json - c#

Purpose: The code written is suppose to save all the contents using Json and re direct to action.
Problem:
The current redirect using Json does not allow the redirection as suppose.
return new JsonResult { Data = new { status = status } };
The code is below for reference: Looking for suggestions:
View Code
$.ajax({
url: '/SA/Save',
type: "POST",
data: JSON.stringify(data),
dataType: "JSON",
contentType: "application/json",
success: function (d) {
//check is successfully save to database
if (d.status == true) {
//will send status from server side
alert('Successfully done.');
window.location.href = d.Url;
//clear form
t = [];
d = [];
r = [];
$('#SN').val('');
$('#SA').val('');
$('#t').empty();
$('#d').empty();
$('#r').empty();
}
else {
alert('Failed');
}
$('#submit').val('Save');
},
});
Controller
public JsonResult Save(SAVM O,)
{
bool status = false;
var userId = User.Identity.GetUserId();
if (ModelState.IsValid)
{
SA s = new SA
{
}
_db.SA.Add(O)
_db.SaveChanges();
status = true;
}
else
{
status = false
}
return new JsonResult { Data = new { status = status } };
}
Here want to redirect like this:
return RedirectToAction("F", "SA");
but using JsonResult
Solution
View
$.ajax({
url: '/SA/Save',
type: "POST",
data: JSON.stringify(data),
dataType: "JSON",
contentType: "application/json",
success: function (d) {
window.location.href = d.Url;
})
} });
Controller
public JsonResult Save(SAVM O,)
{
var userId = User.Identity.GetUserId();
if (ModelState.IsValid)
{
SA s = new SA
{
}
_db.SA.Add(O)
_db.SaveChanges();
return Json(new { Url = "F/SA" });
}

You have a couple of options here, you decide which one you prefer based on your requirements.
Do not use AJAX. AJAX requests are meant for data required for the current page. You should use a synchronous request for the redirection.
Return the URL to which the client should redirect on the success event:
return Json(new { url = "/F/SA" });
And then:
success: function (d)
{
window.location.url = d.url;
}
Return the already rendered View and load it to the current page:
return View("some view...");
And then:
success: function (d)
{
$("#someElement").html(d);
}

Related

Ajax call not redirecting to desired page using razor pages

I'm working on a .NET Core 3.1 razor pages project, and, on one of my pages, I have an AJAX call on submitting the form details. On clicking the button, I am hitting the post handler and ModelState is valid, but the post is not redirecting to the desired page. I have tried to debug the AJAX call using the devtools and my success and failure functions are not being hit.
Where am I going wrong?
Javascript
$.ajax({
url: "/Candidate/Add?handler=Candidate",
type: 'POST',
contentType: 'application/json',
dataType: 'json',
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
data: JSON.stringify(candidate),
success: function (data) {
//alert('success');
var t = data;
},
failure: function (data) {
var f = data;
}
})
Post handler
public async Task<IActionResult> OnPostCandidateAsync([FromBody] CandidateModel candidate)
{
if (!ModelState.IsValid)
{
IdTypeOptions = idTypeRepository.GetIDTypes().Result.Select(a => new SelectListItem
{
Value = a.Id.ToString(),
Text = a.Name
}).ToList();
industryOptions = industryRepository.GetIndustries().Result.Select(a => new SelectListItem
{
Value = a.Id.ToString(),
Text = a.Name
}).ToList();
GenderOptions = genderRepository.GetGender().Result.Select(g => new SelectListItem
{
Value = g.Id.ToString(),
Text = g.Name
}).ToList();
return Page();
}
//candidateModel.UserId =
var id = await candidateRepository.AddCandidate(candidate);
//return ()
return RedirectToPage("./Index");
}
Any help will be appreciated
ajax call always return some data, or partial view but never redirects inside of the action.
you have to fix on success of ajax
.....
data: ....,
success: function (data) {
window.location.href ...
//or
window.open(....)
},
error: function (jqXHR, exception) {
...error code
}
});
if you want to open another page use
window.location.href = 'http://...;' //the full url of razor page
if you want to open page in another window
window.open('the full url of razor page');
i had to return JsonResult on my post handler and passed the url i wanted to redirect to
public async Task<IActionResult> OnPostCandidateAsync([FromBody] CandidateModel candidate)
{
if (!ModelState.IsValid)
{
IdTypeOptions = idTypeRepository.GetIDTypes().Result.Select(a => new SelectListItem
{
Value = a.Id.ToString(),
Text = a.Name
}).ToList();
industryOptions = industryRepository.GetIndustries().Result.Select(a => new SelectListItem
{
Value = a.Id.ToString(),
Text = a.Name
}).ToList();
GenderOptions = genderRepository.GetGender().Result.Select(g => new SelectListItem
{
Value = g.Id.ToString(),
Text = g.Name
}).ToList();
return Page();
}
//candidateModel.UserId =
var id = await candidateRepository.AddCandidate(candidate);
return new JsonResult("/Candidate/Index");
//return ()
//return RedirectToPage("./Index");
}
and added the window.location.href on to the success function of the ajax call
$.ajax({
url: "/Candidate/Add?handler=Candidate",
type: 'POST',
contentType: 'application/json',
dataType: 'json',
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
data: JSON.stringify(candidate),
success: function (data) {
window.location.href = data;
},
failure: function (data) {
var f = data;
}
})
#Serge thank you for your assistance

How to show model state errors while saving data by calling ajax post

what i have tried in my action method is when the model state is not valid i redirect the view with the model data but it could not show the errors in view
public ActionResult Create(IndentmstViewData model)
{
model.fk_sessionUserid = Session["userID"].ToString();
model.fk_sessionLocid = Session["fk_locid"].ToString();
model.pk_IndentId = Convert.ToInt32(TempData["EditId"]);
if (ModelState.IsValid)
{
XDocument doc = new XDocument(new XDeclaration("1.0", "UTF - 8", "yes"),
new XElement("XMLdata",
from itemdet in model.GetItemDetails
select new XElement("ItemDetails",
new XElement("fk_itemid", itemdet.fk_ItemId),
new XElement("qty", itemdet.Qty),
new XElement("balqty", itemdet.indbalqty),
new XElement("estimatedcost", itemdet.EstimatedCost),
new XElement("partno", itemdet.PartNo),
new XElement("itemdesc", itemdet.itemDesc),
new XElement("fk_indentid", model.pk_IndentId))));
model.doc = doc.ToString();
if (model.pk_IndentId == 0)
{
_indent_mstService.Save(model.ADTO());
}
else
{
_indent_mstService.Update(model.ADTO());
}
}
else
{
string fk_locid = Session["fk_locid"].ToString();
model.IndentDate = DateTime.Now.ToString("dd/MM/yyyy").Replace("-", "/").ToString();
model.GetMenuData = GetMenuByUser();
model.GetItems = _HomeService.GetItems().ToList();
model.IndentNo = _indent_mstService.GetAutoIndentNo(fk_locid).FirstOrDefault();
return View(model);
}
return Json(model, JsonRequestBehavior.AllowGet);
}
jQuery Ajax Post method is
$.ajax({
url: $('#SaveDetails').val(),
type: "POST",
data: JSON.stringify(data),
dataType: "JSON",
contentType: "application/json",
success: function (data) {
window.location.replace("http://addusharma.somee.com/Indent_mst/Create");
alert("Record Save Successfully !!");
},
error: function (data) {
alert("error");
$('#form').empty();
var result = $(Data).find('#form').html();
$('#form').html(result);
}
});
what i want to achieve is, when model state is not valid it should show the model errors in my view
Ajax error function will be launched only if request failed. In your case controller returns success result in both cases. So you need to handle everything in success function.
success: function (data, text, xhr) {
if(xhr.hasOwnProperty('responseJSON')){
window.location.replace("http://addusharma.somee.com/Indent_mst/Create");
alert("Record Save Successfully !!");
}
else{
alert("error");
$('#form').empty();
var result = $(data).find('#form').html();
$('#form').html(result);
}
},
To show the Validation Errors you need to use validation Summary in your view.
#Html.ValidationSummary(false)
To know further about how to use ValidationSummary read here.
Controller
public ActionResult Create(IndentmstViewData model)
{
model.fk_sessionUserid = Session["userID"].ToString();
model.fk_sessionLocid = Session["fk_locid"].ToString();
model.pk_IndentId = Convert.ToInt32(TempData["EditId"]);
if (ModelState.IsValid)
{
XDocument doc = new XDocument(new XDeclaration("1.0", "UTF - 8", "yes"),
new XElement("XMLdata",
from itemdet in model.GetItemDetails
select new XElement("ItemDetails",
new XElement("fk_itemid", itemdet.fk_ItemId),
new XElement("qty", itemdet.Qty),
new XElement("balqty", itemdet.indbalqty),
new XElement("estimatedcost", itemdet.EstimatedCost),
new XElement("partno", itemdet.PartNo),
new XElement("itemdesc", itemdet.itemDesc),
new XElement("fk_indentid", model.pk_IndentId))));
model.doc = doc.ToString();
if (model.pk_IndentId == 0)
{
_indent_mstService.Save(model.ADTO());
}
else
{
_indent_mstService.Update(model.ADTO());
}
return JSON(new
{
ResultStatus=false,
Message="Here Success Message Text...",
Result=new
{
fk_sessionUserid= model.fk_sessionUserid,
fk_sessionLocid=model.fk_sessionLocid,
pk_IndentId=model.pk_IndentId,
Doc=model.doc
}
});
}
else
{
return JSON(new
{
ResultStatus=false,
Message="Here Error Text...",
Result=new
{
IndentDate= DateTime.Now.ToString("dd/MM/yyyy").Replace("-", "/").ToString(),
GetMenuData= GetMenuByUser(),
GetItems=_HomeService.GetItems().ToList(),
IndentNo=_indent_mstService.GetAutoIndentNo(fk_locid).FirstOrDefault()
}
});
}
}
JS
$.ajax({
url: $('#SaveDetails').val(),
type: "POST",
data: JSON.stringify(data),
dataType: "JSON",
contentType: "application/json",
success: function (data) {
if(data.ResultStatus==true){
window.location.replace("http://addusharma.somee.com/Indent_mst/Create");
alert(data.Message);
}else{
alert(data.Message);
}
},
error: function (data) {
alert(data.Message);
$('#form').empty();
var result = $(Data).find('#form').html();
$('#form').html(result);
}
});

Undefined variable sent from Ajax to MVC Controller

I have a method where my users can change their password,to a new one,requiring 2 variables,one is the new password,and the other,the repetition of the password.The thing is that when i call the method, it returns the string "undefined",and uses that string as the new password,saving it on the db.
Can someone tell me what I'm doing wrong?
Controller:
[HttpPost]
public JsonResult ChangePwdEnt(string pwd, string repeatpwd)
{
if (pwd == null || repeatpwd == null)
{
ViewBag.Error = "Insira os campos obrigatórios";
}
else
{
if (pwd == repeatpwd)
{
changePwd_Entidades(Session["ID"].ToString(),pwd);
return Json(true,JsonRequestBehavior.DenyGet);
}
else
{
ViewBag.Error = "As palavras chave precisam de ser iguais";
}
}
return Json(false, JsonRequestBehavior.DenyGet);
}
Script:
<script>
$('.alt-btn').on('click', function () {
$.ajax({
type: 'POST',
contentType: 'application/json',
url: '#Url.Action("ChangePwdEnt", "Home")?pwd=' +
$('#Info_pwd').val() + '&repeatpwd=' + $('#Info_repeatpwd').val(),
error: function (e) {
console.log(e);
},
success: function (Changed) {
if (Changed) {
window.location = "Entidades";
} else if (!Changed) {
window.location = "LoginEntidades";
}
}
});
});
I think you are using incorrect id to get value of password field.
And instead of sending both password to code better approach would be just compare your both password values at client side and if they both are same then parse those values to code side other wise ask user to input same password .
That would be better to Send the data in the data parameter while you're using POST method
var data = JSON.stringify({
'pwd': $('#Info_pwd').val(),
'repeatpwd':$('#Info_repeatpwd').val()
});
$.ajax({
type: 'POST',
contentType: 'application/json',
url: '#Url.Action("ChangePwdEnt", "Home"),
data: data,
error: function (e) {
console.log(e);
},
success: function (Changed) {
if (Changed) {
window.location = "Entidades";
} else if (!Changed) {
window.location = "LoginEntidades";
}
}
});
This is for using POST method. If you want to use GET method than it would be fine to pass data in query string.

Sending object to a controller in asp.net mvc using ajax

I have issue with sending object contains array to a controller
this is my js code
var messageId = 0;
function DraftMessage()
{
var to = [];
var i = 0;
$('#to option:selected').each(function (index, element) {
to[i++] = $(element).val();
});
console.log(to);
$.ajax({
type: "POST",
url: "#Url.Action("DraftMessage", "Activities")",
datatype: "json",
traditional: true,
async: false,
data: { "id": messageId, "To": to, "Title": $("#title").val(), "Project": $("#project").val(), "AreaId": $("#areaId").val(), "Body": $("#messageBody").val() },
beforeSend: function () { }
}).done(function (Id) {
console.log(Id);
messageId = Id;
});
}
$("input, select, textarea").change(function () { DraftMessage(); });
var contents = $('.note-editable').html();
$(".compose-message").on("blur", ".note-editable", function () {
if (contents != $(this).html()) {
DraftMessage();
contents = $(this).html();
}
});
and this is my controller side
public int DraftMessage(message draftMessage, HttpPostedFileBase[] files = null)
{
return new MessageActions().DraftMessage(draftMessage);
}
my issue is that the ajax request always send the to array as null, I do not know what is wrong so could anyone help me to resolve this issue.
Can you change your request and use
dataType: "json",
contentType: "application/json;charset=utf-8",
This should work. Please let me know.
Try this. Push your object to array and send it as Json.
array.push({yourobject datas here})
$.ajax({
type: "POST",
url: '/DraftMessage/Activities',
contentType: 'application/json',
data: JSON.stringify(array),
success: function (d) {
..
},
error: function (xhr, textStatus, errorThrown) {
console.log(errorThrown);
}
});
Convert your controller function's return type to JSonResult.
Hope helps.
do you want upload file using ajax ?!!
use the normal usage of form not the Ajax.BeginForm then in form submit event
write your code like this:
$('#Form').submit(function () {
var xhr = new XMLHttpRequest();
var fd = new FormData();
var file = $('#Image').val();
if (file) {
var fname = $('#Image')[0].files[0].name;
if (CheckFile(file)) {
var uploadFile = document.getElementById('Image').files[0];
var myArray = [];
myArray.push(uploadFile);
if (myArray.length > 0) {
for (var i = 0; i < myArray.length; i = i + 1) {
fd.append("File1", myArray[i]);
}
}
}
else {
return false;
}
}
fd.append("ID", messageId);
fd.append("Title", $('#Title').val());
fd.append("Project", $('#Project').val());
fd.append("AreaId", $('#AreaId').val());
fd.append("Body", $('#messageBody').val());
var form = $('#Form');
var token = $('input[name="__RequestVerificationToken"]', form).val();
fd.append("__RequestVerificationToken", token);
xhr.open("POST", "/ControllerName/Action/", true);
xhr.send(fd);
xhr.addEventListener("load", function (event) {
if (event.target.response != "OK") {
OnFail(event.target.response);
}
else {
OnSuccess(event);
}
}, false);
return false;
})
server side in controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult actionName(Model pModel){
HttpPostedFileBase File = Request.Files["File1"];
if (File != null && File.ContentLength != 0){
//do what you want
return Content("OK");
}
else{
Response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest;
return Content("Error Messages", System.Net.Mime.MediaTypeNames.Text.Plain);
}
}
You can try a different approach. You can serialize your entire form by doing something like this:
var formdata = $("#frmEmailInfo").serialize();
and then post it to the Controller:
$.ajax(
{
type: "POST",
data: formdata,
dataType: 'json',...

MVC JsonResult Method not accepting parameter

I have an MVC JsonResult Method that accepts one string parameter:
public JsonResult GetDestinations(string countryId)
{
List<Destination> destinations = new List<Destination>();
string destinationsXml = SharedMethods.GetDestinations();
XDocument xmlDoc = XDocument.Parse(destinationsXml);
var d = from country in xmlDoc.Descendants("Country")
from destinationsx in country.Elements("Destinations")
from destination in destinationsx.Elements("Destination")
where (string)country.Attribute("ID") == countryId
select new Destination
{
Name = destination.Attribute("Name").Value,
ID = destination.Attribute("ID").Value,
};
destinations = d.ToList();
return Json(new JsonResult { Data = destinations}, JsonRequestBehavior.AllowGet);
}
With a jquery method calling the method:
//Fetch Destinations
$("#Country").change(function () {
var countryId = $("#Country > option:selected").attr("value");
$("#Destination").html("");
$("#Resort").html("");
$("#Resort").append($("<option></option>").val(0).html("---Select---"));
$.ajax({
type: "POST",
traditional: true,
url: "/Destinations/GetDestinations",
data: "{countryId:'" + countryId + "'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
BindDestinationSelect(msg)
}
});
});
However, the JsonResult seems to only receive a null parameter. Even though Firebug is showing that a parameter is being passed:
JSON
countryId
"11"
Source
{countryId:'11'}
Any ideas? Thanks
I think the problem is in how you are actually passing the data, you are doing so as a string:
data: "{countryId:'" + countryId + "'}",
When in reality, you should be using a structure on the client side;
data: { countryId: countryId },
jQuery should be able to handle passing the id correctly then. As you are doing it now, it is trying to send JSON to the server, which is not what MVC is expecting, it's expecting a POST with name/value pairs.
You might also want to consider the jQuery Form Plugin, as it makes serializing your Javascript structures into POST data very easy.
Ah, after much searching I've discovered the reason why it fails.
Nothing to do with malformed JSON etc, but rather the fact that the controller method doesnt know what to expect if you try to pass it JSON values:
http://www.c-sharpcorner.com/Blogs/BlogDetail.aspx?BlogId=863
So in my case, I've just elected to pass it a single string value.
$("#Country").change(function () {
var countryId = $("#Country > option:selected").attr("value");
$("#Destination").html("");
$("#Resort").html("");
$("#Resort").append($("<option></option>").val(0).html("---Select---"));
$.ajax({
type: "POST",
traditional: true,
url: "/Destinations/GetDestinations",
data: "countryId=" + countryId,
success: function (msg) {
BindDestinationSelect(msg.Data)
}
});
Here I suggest you to decorate your action with HttpPost attribute
Like :-
[HttpPost]
public JsonResult GetDestinations(string countryId)
{
List<Destination> destinations = new List<Destination>();
string destinationsXml = SharedMethods.GetDestinations();
XDocument xmlDoc = XDocument.Parse(destinationsXml);
var d = from country in xmlDoc.Descendants("Country")
from destinationsx in country.Elements("Destinations")
from destination in destinationsx.Elements("Destination")
where (string)country.Attribute("ID") == countryId
select new Destination
{
Name = destination.Attribute("Name").Value,
ID = destination.Attribute("ID").Value,
};
destinations = d.ToList();
return Json(new JsonResult { Data = destinations}, JsonRequestBehavior.AllowGet);
}
public JsonResult BindAllData(string Userid)
{
List<VoteList> list = new List<VoteList>();
var indexlist = db.TB_WebSites.ToList();
int i = 0;
var countlist = db.Tb_Votes.ToList();
var VCountList = db.Tb_Votes.ToList();
foreach (TB_WebSites vt in indexlist)
{
bool voted = false;
}
return Json(new { List = _list });
}
function DataBind() {
$("#LoadingDatas").show();
var userid = $("#FBUserId").text();
//alert('Data : ' + userid);
var InnerHtml = "";
$.ajax(
{
url: '/Gitex/BindAllData/',
type: 'POST',
data: { "Userid": userid },
dataType: 'json',
async: true,
success: function (data) {
//alert('Done');
//alert(data.List.length);
for (var i = 0; i < data.List.length; i++) {
});
}
Try this, it worked for me
jQuery function
success :function(Destinations)

Categories