Update database with JSOn string asp.net MVC4 - ajax

Hey I am trying to post a form to my controller as Json and then update the database where columns match. I can't seem to get it to work. I am using a function as shown below to convert the form data into a json string and it's posting through but I'm having trouble with the controller method I need to find out how to match the valuse in the json with the values in the database any help would be great
$.ajax({
type: 'POST',
contentType: 'application/json',
url: "Admin/update/",
dataType: "json",
data: formToJSON(),
success: function (themessage) {
}
});
Converting form with JSON.stringify
function formToJSON() {
return JSON.stringify({
"username": $('#username').val(),
"fname": $('#fname').val(),
"lname": $('#lname').val(),
"address1": $('#address1').val(),
"address2": $('#address2').val(),
"postcode": $('#postcode').val(),
"town": $('#town').val(),
"memcat": $('#memcat').val(),
"phone": $('#phone').val(),
"email": $('#email').val(),
"message": $('#message').val(),
"password": $('#password').val(),
"Admin": $('#Admin').val(),
});
}
Post contains
{"username":"Broon","fname":"Paw","lname":"Broon","address1":"12 Glebe Street","address2":"Sinderins","postcode":"DD12 4RT","town":"Dundee","memcat":"Ordinary","phone":"123456","email":"paw#localhost","password":"paw","Admin":"no"}
Controller Method
//
// POST: /Admin/
public JsonResult update(string username)
{
var themessage = from b in db.member
select b;
themessage = themessage.Where(b => username.Contains(b.username));
foreach (var item in themessage)
{
item.username = username;
}
db.SaveChanges();
return Json(themessage, JsonRequestBehavior.AllowGet);
}
The problem is accessing the json data to match the database data. I'm guessing I may need to parse the json some way? Above I have only tried to match the username.

Related

Jquery Data Tables Can't post data with Ajax (asp.Net)

I've been trying to post data to jquery Data Tables but i couldn't. I have a web method in server side which returns data as object array. I need to get data with ajax post. But i can't. So i need some help.
Here is my c# web method:
[WebMethod]
public static object[] Questions()
{
table = new DataTable();
List<object> questionList = new List<object>();
table = RunSelectCommand("SELECT QUESTION_ID,QUESTION_TEXT,QUESTION_GROUP FROM QUESTIONS WHERE QUESTION_ACTIVE='Y'");
for(int i=0 ; i<table.Rows.Count ; i++)
{
questionList.Add(new
{
q_id = table.Rows[i]["QUESTION_ID"].ToString(),
q_text = table.Rows[i]["QUESTION_TEXT"].ToString(),
q_group = table.Rows[i]["QUESTION_GROUP"].ToString()
});
}
return questionList.ToArray();
}
And jquery:
$(document).ready(function () {
$('#questTable').DataTable({
processing: true,
serverSide:true,
ajax: {
url: 'Question.aspx/Questions',
type:'POST'
},
columns: [
{ data: 'q_id' },
{ data: 'q_text' },
{ data: 'q_group' }
]
});
});
But i debuged it with break point and i noticed that web method doesn't work. And here is the error that i get: DataTables warning: table id=questTable - Invalid JSON response. For more information about this error, please see http://datatables.net/tn/1
Thanks in advance.
Problem solved. It was about my web method returns object array and data tables doesn't accept it. That's why i got Invalid JSON response. error. So i change my js structure. I post data as usual then i use data tables data property for post. It works:
function GetData()
{
$.ajax({
type: 'POST',
dataType: 'json',
contentType: 'application/json',
url: 'Question.aspx/Questions',
data: '{}',
success: function (result) {
$('#questTable').DataTable({
data:result.d,
columns: [
{ data: 'q_id' },
{ data: 'q_text' },
{ data: 'q_group' }
]
});}
}

Laravel 5: Retrieve JSON array from $request

I'm a Laravel newbie and I'm converting a php/jquery app to Laravel. The original code used a JSON array with an ajax POST, which was retrieved like this:
$json = file_get_contents('php://input');
$data = json_decode($json,true);
I'm doing much the same thing on the POST side, but I don't see any data coming through in my Laravel $request collection. Is there something special that I need to do to retrieve JSON data structured like this:
[
{ "name": "John", "location": "Boston" },
{ "name": "Dave", "location": "Lancaster" }
]
Here is my jQuery ajax POST code (with hard coded data)
$.ajax({
type: "POST",
url: "/people",
data: '[{ "name": "John", "location": "Boston" }, { "name": "Dave", "location": "Lancaster" }]',
dataType: "json",
success:function(data) {
$('#save_message').html(data.message);
}
});
Here is the code in my Controller that receives the POST
public function store(Request $request)
{
dd($request->all());
}
But all I get is:
[]
Any ideas on how I can retreive my data?
You need to change your Ajax call to
$.ajax({
type: "POST",
url: "/people",
data: '[{ "name": "John", "location": "Boston" }, { "name": "Dave", "location": "Lancaster" }]',
contentType: "json",
processData: false,
success:function(data) {
$('#save_message').html(data.message);
}
});
change the dataType to contentType and add the processData option.
To retrieve the JSON payload from your controller, use:
dd(json_decode($request->getContent(), true));
instead of
dd($request->all());
$postbody='';
// Check for presence of a body in the request
if (count($request->json()->all())) {
$postbody = $request->json()->all();
}
This is how it's done in laravel 5.2 now.
Just a mention with jQuery v3.2.1 and Laravel 5.6.
Case 1: The JS object posted directly, like:
$.post("url", {name:'John'}, function( data ) {
});
Corresponding Laravel PHP code should be:
parse_str($request->getContent(),$data); //JSON will be parsed to object $data
Case 2: The JSON string posted, like:
$.post("url", JSON.stringify({name:'John'}), function( data ) {
});
Corresponding Laravel PHP code should be:
$data = json_decode($request->getContent(), true);
You can use getContent() method on Request object.
$request->getContent() //json as a string.
As of Laravel 5.2+, you can fetch it directly with $request->input('item') as well.
Retrieving JSON Input Values
When sending JSON requests to your application, you may access the
JSON data via the input method as long as the Content-Type header of
the request is properly set to application/json. You may even use
"dot" syntax to dig deeper into JSON arrays:
$name = $request->input('user.name');
https://laravel.com/docs/5.2/requests
As noted above, the content-type header must be set to application/json so the jQuery ajax call would need to include contentType: "application/json",
$.ajax({
type: "POST",
url: "/people",
data: '[{ "name": "John", "location": "Boston" }, { "name": "Dave", "location": "Lancaster" }]',
dataType: "json",
contentType: "application/json",
success:function(data) {
$('#save_message').html(data.message);
}
});
By fixing the AJAX call, $request->all() should work.
My jQuery ajax settings:
$.ajax({
headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
url: url,
dataType: "json",
type: "post",
data: params,
success: function (resp){
....
},
error: responseFunc
});
And now i am able to get the request via $request->all() in Laravel
dataType: "json"
is the important part in the ajax request to handle the response as an json object and not string.

Web Api 2 deserialize LINQ2SQL object with collection property

The context is long, so I'll start with the question: Why isn't the InductionQAs collection property being rehydrated?
In a Web API 2 method, LINQ produces an object ic with a collection property InductionQAs. After I eliminate a huge irrelevant object graph and prevent a circular reference, ic is returned by the method. Here's the code. Error handling has been removed for brevity.
// GET: api/InductionContent/5
[Authorize]
public object Get(int id)
{
var dc = new Models.InductionsDataContext();
var user = GetUser(dc);
var ic = dc.InductionContents.Single(c => c.InductionContentID == id);
ic.User.InductionContents.Clear(); //don't ship this it can be huge
return ic;
}
Here's the invoking JS code. Ignore the authorisation header business, that all works fine.
var token, headers;
$.ajax({ //get session token
url: "api/token",
headers: { Authorization: "Basic " + btoa("username:password") },
}).done(function (result) {
localStorage.setItem('access_token', token = result.access_token);
var headers = { Authorization: "Session " + token };
$.ajax({ //get an induction content object
url: "api/InductionContent/5",
headers: headers
}).done(function (ic) {
//at this point we have an object graph
var json = JSON.stringify(ic);
});
});
This is what JSON.stringify(ic) returns:
{
"InductionContentID": 5,
"InductionTemplateID": 1,
"InductionContent1": "<p>We recognise that it is ...(redacted)</p>",
"InductionContentOrder": 301,
"Caption": "Workplace Health and Safety",
"OwnerId": 0,
"ParentId": 0,
"TopicId": 5,
"InductionQAs": [
{
"InductionQAID": 1,
"InductionContentID": 5,
"Question": "Who is responsible for ...(redacted)",
"Answers": "A|B|C|*D",
"InductionQAOrder": 1
}
],
"User": null
}
All well and good. Now we round-trip it.
$.ajax({
type: "post",
url: "api/InductionContent",
headers: headers,
data: ic
});
This calls into the following web method:
// POST: api/InductionContent
[Authorize]
public void Post([FromBody]Models.InductionContent ic)
{
//redacted
}
The method is invoked and ic has a value. ic.User contains data, but inspection of ic.InductionQAs reveals that it has not been initialised.
Serialisation is configured as follows:
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings
.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
GlobalConfiguration.Configuration.MessageHandlers
.Add(new AuthenticationHandler(CreateConfiguration()));
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
MVC is smart but not quite smart enough. It needs a hint. The "round-trip" call should have looked like this:
$.ajax({
type: "post",
url: "api/InductionContent",
contentType: "text/json",
headers: headers,
data: JSON.stringify(ic)
}).done(function (result) {
//etc
});
There are two things to note here.
We have assumed manual control of payload encoding
We have annotated the post with the encoding used
One another thing...
Having got it all to work I decided the method should return the id of the freshly minted database row. Changing the method return type to int and appending a last line
return nc.InductionContentId;
should have been enough, but the done method of the ajax call totally failed to fire. Investigation with Fiddler revealed that the id value had indeed been returned with a content-type of text/json.
When you specify a content type for a jQuery ajax call, the same content type is used for the response. If the return value is an object, this will work fine. The object will be serialised as JSON and at the other end it will be parsed to provide the result object.
But for a simple value like an int, this comes unglued at the parsing stage. To resolve the problem, a return content type of plain text by using the dataType attribute.
$.ajax({
type: "post",
url: "api/InductionContent",
contentType: "text/json",
dataType: "text",
headers: headers,
data: JSON.stringify(ic)
}).done(function (result) {
var id = result;
//etc
});

JSON encoded improperly when using KendoGrid POST payload

I am binding to a JSON data source, then rebinding after the user initiates a search based on filters on the page. The JSON payload is encoded improperly and nothing I've tried thus far seems to explain why.
If I could just add the correct JSON to the HTTP post, everything would work normally, and does with the $.ajax method listed first.
Using $.ajax call (works)
$.ajax(
{
url: '/api/DataProcessing',
type: "Post",
contentType: "application/json; charset=utf-8",
data: '' + JSON.stringify(searchObject),
dataType: 'json',
success: function (result) {
$(".kendoDataProcessing").data("kendoGrid").dataSource = new kendo.data.DataSource({ data: result });
$(".kendoDataProcessing").data("kendoGrid").dataSource.read();
$(".kendoDataProcessing").data("kendoGrid").refresh();
},
error: function (xhr, ajaxOptions, thrownError) {
alert('Status: ' + xhr.status + ', Error Thrown: ' + thrownError);
}
});
However, when I update the kendogrid data source in what I expect to send an equivalent payload, it encodes the JSON in an unexpected way (see below the code block for before and after HTTP requests captured in Fiddler. (encodes improperly)
$(".kendoDataProcessing").kendoGrid({
dataSource: {
transport: {
read: {
url: '/api/DataProcessing',
type: 'Post',
contentType: 'application/json; charset=utf-8',
data: '' + JSON.stringify(searchObject),
dataType: 'json',
}
},
pageSize: 25
},
height: 620,
sortable: true,
pageable: true,
filterable: true,
columns: [
{
field: "Client",
title: "Client Name",
width: 120
}, {
field: "Study",
title: "Study",
width: 100
}, {
field: "DataLogId",
title: "Batch Description",
width: 120
}, {
field: "Indicator",
title: "Indicator",
width: 100
}, {
field: "UserName",
title: "Username",
width: 110
}, {
field: "AssessmentPoint",
title: "Assessment Point",
width: 130
}, {
field: "DateStamp",
title: "Date Stamp",
width: 180
}]
});
**Expected JSON encoding (HTTP call created using $.ajax method) **
{"Client":"Choose a client...","Study":"Choose a study...","UserName":"Choose a user...","from":"","To":"","AssessmentPoint":"Choose an AP...","Indicator":"Choose an indicator...","DataLogId":""}
**Actual JSON encoding (HTTP call created using Kendogrid data source update and rebind **
0=%7B&1=%22&2=C&3=l&4=i&5=e&6=n&7=t&8=%22&9=%3A&10=%22&11=C&12=h&13=o&14=o&15=s&16=e&17=+&18=a&19=+&20=c&21=l&22=i&23=e&24=n&25=t&26=.&27=.&28=.&29=%22&30=%2C&31=%22&32=S&33=t&34=u&35=d&36=y&37=%22&38=%3A&39=%22&40=C&41=h&42=o&43=o&44=s&45=e&46=+&47=a&48=+&49=s&50=t&51=u&52=d&53=y&54=.&55=.&56=.&57=%22&58=%2C&59=%22&60=U&61=s&62=e&63=r&64=N&65=a&66=m&67 ... (continues)
It looks like it is making the json string into an array of sorts. So I tried with just a test string of "floof" and it encoded to "0=f&1=l&2=o&3=o&4=f"
Controller method called:
public HttpResponseMessage Post([FromBody]DataProcessingSearch dataProcessingSearch)
{
// dataProcessingSearch var is null (was passed oddly encoded)
}
Additional Details (search object)
var searchObject = new Object();
searchObject.Client = $('#ClientList').val();
searchObject.Study = $('#StudyList').val();
searchObject.Site = $('#SiteList').val();
searchObject.UserName = $('#UserList').val();
searchObject.from = $('#beginSearch').val();
searchObject.To = $('#endSearch').val();
searchObject.AssessmentPoint = $('#AssessmentPointList').val();
searchObject.Indicator = $('#IndicatorList').val();
searchObject.DataLogId = $('#DataLogIdText').val();
demo: http://so.devilmaycode.it/json-encoded-improperly-when-using-kendogrid-post-payload
function searchObject(){
return {
Client : $('#ClientList').val(),
Study : $('#StudyList').val(),
Site : $('#SiteList').val(),
UserName : $('#UserList').val(),
from : $('#beginSearch').val(),
To : $('#endSearch').val(),
AssessmentPoint : $('#AssessmentPointList').val(),
Indicator : $('#IndicatorList').val(),
DataLogId : $('#DataLogIdText').val()
}
}
// i have putted the dataSource outside just for best show the piece of code...
var dataSource = new kendo.data.DataSource({
transport: {
read : {
// optional you can pass via url
// the custom parameters using var query = $.param(searchObject())
// converting object or array into query sring
// url: "/api/DataProcessing" + "?" + query,
url: "/api/DataProcessing",
dataType: "json",
// no need to use stringify here... kendo will take care of it.
// also there is a built-in function kendo.stringify() to use where needed.
data: searchObject
},
//optional if you want to modify something before send custom data...
/*parameterMap: function (data, action) {
if(action === "read") {
// do something with the data example add another parameter
// return $.extend({ foo : bar }, data);
return data;
}
}*/
}
});
$(".kendoDataProcessing").kendoGrid({
dataSource: dataSource,
...
});
comments are there just for better explanation you can completely remove it if don't need it. the code is fully working as is anyway.
doc: http://docs.telerik.com/kendo-ui/api/wrappers/php/Kendo/Data/DataSource
What May be the wrong perception:-
1.The Json() method accepts C# objects and serializes them into JSON
strings. In our case we want to return an array of JSON objects; to
do that all you do is pass a list of objects into Json().
public JsonResult GetBooks()
{
return Json(_dataContext.Books);
}
Can you identify what is wrong with the above method? If you didn't already know, the above method will fail at runtime with a "circular reference" exception.
Note: try to return Json, HttpResponse may serialize the data in such a way that it is not acceptable by Kendo Grid. this has happened with me in my project.
Try this Approach:-
Now lets create instances of them in a JsonResult action method.
public JsonResult GetFooBar()
{
var foo = new Foo();
foo.Message = "I am Foo";
foo.Bar = new Bar();
foo.Bar.Message = "I am Bar";
return Json(foo);
}
This action method would return the following JSON:
{
"Message" : "I am Foo",
"Bar" : {
"Message" : "I am Bar"
}
}
In this example we got exactly what we expected to get. While serializing foo it also went into the Bar property and serialized that object as well. However, let's mix it up a bit and add a new property to Bar.
I remember working with a kendo grid in the past. Solution back then was returning jsonp. (needed to work crossdomain not sure if it does in your case)
Suggestion change you controller method to return sjonp by decorating you method with a JsonpFilterAttribute. Something like so:
[JsonpFilter]
public JsonResult DoTheThing(string data, string moreData)
{
return new JsonResult
{
Data = FetchSomeData(data, moreData)
};
}
Then in de Kendo grid try use http://demos.telerik.com/kendo-ui/datasource/remote-data-binding.
For the Jsonpfilter attribute first look at here or else here.

Does ko.toJSON() work with dates?

I am using knockoutjs on an asp.net mvc page. I am using ajax to persist a form back to the server by calling ko.toJSON(viewModel) and then posting the results back to the server using jQuery. All of the properties on the view model are successfully serialized except for the Javascript date which is persisted as an empty object.
Declaration:
var viewModel = {
startTime: ko.observable(),
type: ko.observable(),
durationInMinutes: ko.observable(),
notes: ko.observable()
};
Save Data:
var postData = ko.toJSON(viewModel);
$.ajax({
url: "/data",
type: "POST",
data: postData,
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function () {
console.log('success!');
},
error: function () {
console.log('fail!');
}
});
The console.log value of viewModel.startTime() is:
Date {Tue May 10 2011 11:30:00 GMT-0500 (Central Daylight Time)}
After line 1 of Save Data, the value of postData is:
{
"startTime": {},
"type": "1",
"durationInMinutes": "45",
"notes": "asfasdfasdfasdfasdfasdfasdfas",
"displayableStartTime": "10-May 11:30"
}
If I expand line 1 of Save Data to
var jsonEvent = ko.toJS(viewModel);
jsonEvent.startTime = viewModel.startTime();
var postData = JSON.stringify(jsonEvent);
The value of postData is:
{
"startTime": "2011-05-10T16:30:00.000Z",
"type": "1",
"durationInMinutes": "45",
"notes": "asfasdfasdfasdfasdfasdfasdfas",
"displayableStartTime": "10-May 11:30"
}
Can anyone explain what might be going on and how I might be able to get knockoutjs to handle the date object?
Given the current issue with ko.toJS and dates, one option would be to create a dependentObservable containing the real value that you want the server to deal with.
Something like:
var viewModel = {
startTimeForInput: ko.observable(),
type: ko.observable(),
durationInMinutes: ko.observable(),
notes: ko.observable()
};
viewModel.startTime = ko.dependentObservable(function() {
return this.startTimeForInput().toJSON();
}, viewModel);
ko.applyBindings(viewModel);
Now, when you call ko.toJSON you will get the startTime with the correct value that the server could use.
For older browsers, something like json2.js would include the .toJSON for Date objects.
I had a problem with ko.toJSON() giving me a bad date format when the date was DateTime.MinValue.
Though probably not a fix for your problem, this fix worked for my ko.toJSON() date problem:
var postData = JSON.parse(JSON.stringify(ko.toJSON(viewModel)).replace(/\"1-01-01/g, "\"0001-01-01"));
ASP.Net WebMethod fails because ko.toJSON() produces different results for DateTime.MinValue

Resources