Controller returns raw JSON object as view - javascript

i'm using MVC architecture, i've a POST form as Bootstrap Modal that attach its form data after submit to an AJAX Call
$.ajax({
type: "POST",
url: action,
enctype: "multipart/form-data",
data: dataString,
cache: false,
contentType: contentType,
processData: processData,
beforeSend: function () {
block('#mymodal');
},
success: function (data, status, xhr) { console.log("success ajax"); onAjaxSuccess(xhr, status, '#mymodal') },
error: function (xhr, status) { console.log("error ajax"); onAjaxFailed(xhr, status, error, '#error-div') },
complete: function (xhr, status) { console.log("complete ajax"); onAjaxComplete(xhr, status, '#mymodal', '#alert', '#myModal') }
});
where action is the Controller Method where it passes the required data, contentType and processData are both false
this ajax call is working fine and sends the call to the controller correctly
public ActionResult MyCtroller(myViewModel model)
{
//processing stuff
JsonResultObject result = new JsonResultObject();
try
{
//return secess
}
catch (Exception ex)
{
//return error
}
SearchCriteria<MyModel> viewModel = new SearchCriteria<MyModel>();
viewModel.SortExpression = m => m.OrderByDescending(a => a.Date);
SearchResult<MyModel> searchResult = MyModelService.Instance.Search(viewModel);
result.PartialViewHtml = RenderPartialViewToString("PartialView.cshtml", searchResult);
return Json(result));
}
after the processing is completed and it's time to return the page it print the result as pure JSON with the partial view in that JSON as object, instead of rendering the partialView and the success, complete, error in the Ajax call earlier doesn't get called
{
"IsRedirect": false,
"RedirectUrl": null,
"Success": true,
"AlertMessage": {
"IsAutoHide": false,
"Dissmisable": true,
"ShowIcon": false,
"Message": "success",
"AlertCSS": "alert alert-success",
"AlertType": 3,
"AlertTypeMetronic": "success"
},
"PartialViewHtml":"-----partialView HTML code-----"
}

You should call Json directly with the data you intend to serialize. The Json call will return a JsonResult object so do not pass it an instance of JsonResult. If you do want to use JsonResult directly then return that without the additional call to Json.
Also use the overload of Json with the JsonRequestBehavior parameter.
[HttpPost]
public ActionResult MyCtroller(myViewModel model)
{
var result = new ActualInstanceOrContainerToBeReturned;
return Json(result, JsonRequestBehavior.AllowGet);
}
Also I am not sure why you would want to return the view inside the JsonResult so I will not comment except to say that might be bad design. In the interest of SOC keep the data and the view separate (this includes the generation of these items).

I think you need to change your controller
public ActionResult MyCtroller(myViewModel model)
{
//processing stuff
JsonResultObject result = new JsonResultObject();
try
{
//return secess
}
catch (Exception ex)
{
//return error
}
SearchCriteria<MyModel> viewModel = new SearchCriteria<MyModel>();
viewModel.SortExpression = m => m.OrderByDescending(a => a.Date);
SearchResult<MyModel> searchResult = MyModelService.Instance.Search(viewModel);
// result.PartialViewHtml = RenderPartialViewToString("PartialView.cshtml", searchResult);
// If you want to render as html partial view
return PartialView("PartialView.cshtml", searchResult);
// return Json(result));
}
and Javascript code
$.ajax({
type: "POST",
url: action,
enctype: "multipart/form-data",
data: dataString,
cache: false,
contentType: contentType,
processData: processData,
beforeSend: function () {
block('#mymodal');
},
success: function (data, status, xhr) {
console.log("success ajax");
onAjaxSuccess(xhr, status, '#mymodal')
$("#YOUR_DIV_ID").html(data);
},
error: function (xhr, status) { console.log("error ajax"); onAjaxFailed(xhr, status, error, '#error-div') },
complete: function (xhr, status) { console.log("complete ajax"); onAjaxComplete(xhr, status, '#mymodal', '#alert', '#myModal') }
});

Related

Combining Ajax posts with MVC controllers and redirects

I'm trying to get my server-side code to play nicely with some page templates we got from a design agency. All is good except that I'm struggling to implement the correct behaviour with the results of the form submission.
What should happen is, if the form submits successfully, some JQuery is triggered to animate into a success message. If not, the user should be redirected to an error page.
Here's the form submit script:
$.ajax({
type: 'POST',
data: JSON.stringify(userObject),
url: submitFormUrl,
contentType: 'application/json; charset=utf-8',
cache: 'false',
dataType: 'json',
success: function (data) {
if(data.Success){
console.log('success');
$('.thanks-msg').fadeIn(1000);
$('#market-message').hide();
}else{
console.log('Error');
}
}
});
And here's the controller action that it posts to:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Register(User userObject)
{
bool userExists;
try
{
if (ModelState.IsValid)
{
userExists = InsertUser(userObject); //calls a sproc
}
else
{
return CollectValidationErrors(); // collects all validation errors into a string
}
}
catch(Exception ex)
{
ViewBag.ErrorMessage = "Sorry! There has been an error " + ex.Message;
return Json(new { result = "Redirect", url = Url.Action("Error", "Home") });
}
if(userExists)
{
ViewBag.ErrorMessage = "This user already exists";
return Json(new { result = "Redirect", url = Url.Action("Error", "Home") });
}
return Json(new { success = true }, JsonRequestBehavior.AllowGet);
}
What happens is that the form submission is received and the code inside executed successfully. But if an error state is returned, there's no redirect.
What am I doing wrong?
Try to use error property of ajax call:
$.ajax({
type: 'POST',
data: JSON.stringify(userObject),
url: submitFormUrl,
contentType: 'application/json; charset=utf-8',
cache: 'false',
dataType: 'json',
error: function (XMLHttpRequest, textStatus, errorThrown) {
//Do Something
},
success: function (data) {
if(data.Success){
console.log('success');
$('.thanks-msg').fadeIn(1000);
$('#market-message').hide();
}else{
console.log('Error');
}
}
});
You do not send an error.
You can throw an Exception (forces HTTP Status 500 Internal Server Error) in the Controller Action. It will result that the success is not invoked, but the error function of ajax.
$.ajax({
type: 'POST',
data: JSON.stringify(userObject),
url: submitFormUrl,
contentType: 'application/json; charset=utf-8',
cache: 'false',
dataType: 'json',
success: function (data) {
if(data.Success){
console.log('success');
$('.thanks-msg').fadeIn(1000);
$('#market-message').hide();
}else{
console.log('Error');
}
},
error: function(function (xhr, status, errorThrown)){
// Do Redirect
}
});

Pass a single parameter to WebApi controller using jQuery Ajax

I am trying to pass a single parameter (string value) to webapi controller but, it is not working. The parameter value is reaching the controller as 'null'. Here is my WebApi config,
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}"
);
}
}
Controller:
[HttpPost]
public HttpResponseMessage GetDataView(string request)
{
try
{
var result = DB.GetDataView(request);
return Request.CreateResponse(HttpStatusCode.OK, result);
}
catch (Exception ex)
{
//todo: log exception
throw ex;
}
}
AJAX
var serverName = 'ds100';
$.ajax({
url: 'api/ServerInfo/GetDataView',
type: 'POST',
dataType: 'json',
data: serverName,
success: function (data, textStatus, xhr) {
},
error: function (xhr, textStatus, errorThrown) {
}
Am I missing anything? Any help is appreciated.
The issue seems to be on you ajax parameters the data parameter receives an object (json) that holds a property for each of the values you are passing in the request, I think you should use
var serverName = 'ds100';
$.ajax({
url: 'api/ServerInfo/GetDataView',
type: 'POST',
dataType: 'json',
data: {request: serverName} ,
success: function (data, textStatus, xhr) {
},
error: function (xhr, textStatus, errorThrown) {
}
and that should do it

Do you need to use two calls - 1 get and 1 post in ajax or can you send data back with the success / failure?

I have the following controller method:
public JsonResult CreateGroup(String GroupName)
{
ApplicationUser user;
var userName = User.Identity.Name;
using (DAL.GDContext context = new DAL.GDContext())
{
user = context.Users.FirstOrDefault(u => u.UserName == userName);
if (user != null)
{
var group = new Group();
group.GroupName = GroupName;
group.Members.Add(user);
context.Groups.Add(group);
context.SaveChanges();
}
}
string result = userName;
return Json(result, JsonRequestBehavior.AllowGet);
}
with the following ajax call:
$(function () {
$('#CreateGroup').on("click", function () {
var groupName = $('#groupname').val();
if (groupName != '') {
$.ajax({
url: '#Url.Action("CreateGroup","AjaxMethods")',
type: "POST",
data: JSON.stringify({ 'GroupName': groupName }),
dataType: "json",
cache: false,
contentType: "application/json; charset=utf-8",
success: function (data) {
alert("success");
CreateGroup(data);
},
error: function () {
alert("An error has occured!!!");
}
});
}
});
The CreateGroup function fails saying "Uncaught ReferenceError: data is not defined"
Do i have to use another Json request - type post - to get the username?
you can do the call without using JSON.stringify. Also your controller method has a cache attribute that may yield more control. Personally, I would use the controller cache control. You are probably getting a cached version of the controller call prior to returning data.
[OutputCache(NoStore = true, Duration = 0)]
public ActionResult CreateGroup(string GroupName)
$.ajax({
url: '#Url.Action("CreateGroup","AjaxMethods")',
type: "POST",
data: { 'GroupName': groupName },
dataType: "json",
traditional: true,
success: function (data, status, xhr ) {
alert("success");
CreateGroup(data);
},
error: function () {
alert("An error has occured!!!");
}
});
NOTE: Update success callback.

AJAX post data is null in controller mvc

I try to send a JSON object back to the server. This is my AJAX call:
$.ajax({
url: '/Home/NewService',
async: false,
type: "POST",
data: JSON.stringify(props),
error: function (jqXHR, textStatus, errorThrown) {
console.log("FAIL: " + errorThrown);
},
success: function (data, textStatus, jqXHR) {
console.log("SUCCES");
}
});
The evaluation of JSON.stringify(props) in the browser's debugger is
"[{"name":"firstName","value":"firstValue"}]"
This is the method in the controller which is being called:
[HttpPost]
public void NewService(dynamic json)
{
Response.Write(json);
}
The problem I have is that always the json variable from above is an empty object.
The success function gets called but when I debug the json var is displayed as empty.
Please tell me what I am doing wrong.
Thank you.
I don't think you can bind to a dynamic type the way you're trying to. You can try to create a class that maps your data, something like:
public class Content
{
public string Name { get; set; }
public string Value { get; set; }
}
Now in your action:
[HttpPost]
public ActionResult NewService(Content[] data)
{
// sweet !
}
And in your js like Olaf Dietsche said you need to specify your contentType:
var props = [
{ "Name": "firstName", "Value": "firstValue" },
{ "Name": "secondName", "Value": "secondValue" }
];
$.ajax({
url: '/Home/NewService',
contentType: "application/json",
async: true,
type: "POST",
data: JSON.stringify(props),
error: function (jqXHR, textStatus, errorThrown) {
console.log("FAIL: " + errorThrown);
},
success: function (data, textStatus, jqXHR) {
console.log("SUCCESS!");
}
});
According to jQuery.ajax(), the default content type is is application/x-www-form-urlencoded. If you want to send the data as JSON, you must change this to
$.ajax({
url: '/Home/NewService',
contentType: 'application/json',
...
});
Use the following code to solve this problem
Ajax Call
function SaveDate() {
var obj = {};
obj.ID = '10';
obj.Name = 'Shafiullah';
$.ajax({
url: '/Home/GetData',
dataType: "json",
type: "Post",
contentType: 'application/json',
data: JSON.stringify({ ID: obj.ID, Name: obj.Name }),
async: true,
processData: false,
cache: false,
success: function (data) {
alert(data.id + ' , ' + data.name);
},
error: function (xhr) {
alert('error');
}
});
}
My controller action method
[HttpPost]
public IActionResult GetData([FromBody] Employee employee)
{
return Json(employee);
}

Unable to fetch data from TempData

i am saving some value in TempData in my controller_method. but when i access it in view , i get nothing...
Controller code:
public ActionResult Read_Surah()
{
TempData["Verse_Count"] = obj1.Total_Ayahs; // int data
return Json(new { key = Records }, JsonRequestBehavior.AllowGet);
}
view part:
$.ajax({
url: "../Gateway/Admin_Mgmt?Action_Code=" + 115 + "&S_ID=" + surah_id,
type: 'Post',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
async: false,
data: '',
success: function (result)
{
var mera_obj = result.key;
contents = mera_obj;
mera_obj.size;
#{
string q = (string)TempData["Verse_Count"];
}
alert(#q);
return false;
},
error: function (xhr, ajaxOptions, thrownError) {
alert("Error : " + xhr.responseText); },
});
but its showing 'undefined' in alert...
Do not use TempData to pass value from Controller to view.
Use ViewBag, as TempData is used to provide you data from controller to controller or Action to Action.
See the link for reference:
http://www.codeproject.com/Articles/476967/WhatplusisplusViewData-2cplusViewBagplusandplusTem

Categories