I get a json result from an javascript api query(no problems, valid json) and I would like to insert it into mongoDb.
My json string:
{"data":[{"accessible_wheelchair":true,"address":"181 Washington St","attire":"casual","category_ids":[344],"category_labels":[["Social","Food and Dining","Ice Cream Parlors"]],"country":"us","cuisine":["Ice Cream","Frozen Yogurt","Bagels","Deli","Donuts"],"factual_id":"403b11e4-c383-4305-8ba1-96aa6339eaba","hours":{"sunday":[["11:00","22:00"]],"saturday":[["11:00","22:00"]],"tuesday":[["11:00","22:00"]],"friday":[["11:00","22:00"]],"thursday":[["11:00","22:00"]],"wednesday":[["11:00","22:00"]],"monday":[["11:00","22:00"]]},"hours_display":"Open Daily 11:00 AM-10:00 PM","latitude":42.707169,"locality":"Boxford","longitude":-71.066385,"meal_deliver":false,"name":"Benson Ice Cream","open_24hrs":false,"parking":true,"payment_cashonly":false,"postcode":"01921","price":1,"rating":4.5,"region":"MA","tel":"(978) 352-2911","website":"http://bensonsicecream.com/","wifi":false},{"accessible_wheelchair":true,"address":"256 Georgetown Rd","address_extended":"Unit 5","attire":"casual","category_ids":[363],"category_labels":[["Social","Food and Dining","Restaurants","Pizza"]],"country":"us","cuisine":["Pizza","Cafe","Sandwiches","Subs"],"factual_id":"05e95c81-1125-447b-a500-84e0d380540d","fax":"(314) 423-3377","hours":{"sunday":[["11:00","21:00"]],"saturday":[["11:00","22:00"]],"tuesday":[["11:00","21:00"]],"friday":[["11:00","22:00"]],"thursday":[["11:00","21:00"]],"wednesday":[["11:00","21:00"]],"monday":[["11:00","21:00"]]},"hours_display":"Mon-Thu 11:00 AM-9:00 PM; Fri-Sat 11:00 AM-10:00 PM; Sun 11:00 AM-9:00 PM","latitude":42.697431,"locality":"Boxford","longitude":-70.988191,"meal_cater":true,"meal_deliver":true,"meal_takeout":true,"name":"Boxford House of Pizza","open_24hrs":false,"parking":true,"payment_cashonly":false,"postcode":"01921","price":1,"rating":4.5,"region":"MA","tel":"(978) 887-2212","website":"http://www.bostonrestaurantgroup.com","wifi":false}],"included_rows":2,"total_row_count":2}
I post the json string(arrayString) to a C# controller with ajax.
$.ajax({
url: '/Place/CreateMany',
type: 'POST',
contentType: 'application/json;',
data: JSON.stringify(arrayString),
success: function (valid) {
if (valid) {
alert("success ");
} else {
alert("failure" + arrayString);
}
}
});
The controller errors out with a vague 500 internal server error.
[HttpPost]
public ActionResult CreateMany(string arrayString)
{
JObject jObject = JObject.Parse(arrayString);
JToken placeObj = jObject["data"];
foreach (string data in placeObj)
{
//have a working model defined called PlaceModel
//works with insertOne
var document = BsonSerializer.Deserialize<PlaceModel>(data);
//I am using a working repo(InsertPlace) that uses MongoDB method "insertOne"
//I would like to use a new repo that uses "insertMany"
this._places.InsertPlace(document);
}
return RedirectToAction("List", _places.SelectAll());
}
Not sure what to do to go from json string array of more than one to a single object of my model type (PlaceModel)
This is my first post, so please go easy, but I am open to suggestions.
Veeram was correct. I needed to use BSON serialization not JSON.
[HttpPost]
public void CreateMany(string jsonString)
{
//sets up mongo connection, DB and collection
var Client = new MongoClient();
var DB = Client.GetDatabase("PlacesDb");
var collection = DB.GetCollection<PlaceModel>("PlaceCollection");
if (jsonString != null)
{
IList<PlaceModel> documents = BsonSerializer.Deserialize<IList<PlaceModel>>(jsonString);
collection.InsertMany(documents);
}
}
On the ajax post, I had to add datatype: 'json' and pass my json string as an array jsonString:jsonString with jsonString in [] brackets
self.saveToMongoDB = function (jsonString) {
$.ajax({
url: '/Place/CreateMany',
type: 'POST',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
data: JSON.stringify({ jsonString: jsonString }),
success: function (valid) {
if (valid) {
alert("success " + jsonString);
} else {
alert("failure" + jsonString);
}
}
});
};
Related
I'm using ajax to send an int64 and a string from a month selector to my server-side, but my variable is always null or 0.
JS:
function deleteConta(id) {
var data = $("#monthSelector").val();
var params = {
id: id,
dataAtual: data
};
$.ajax({
type: "POST",
url: '/Contas/ContaView?handler=Delete',
contentType: "application/json; charset=utf-8",
data: JSON.stringify(params),
headers:
{
"RequestVerificationToken": $('input:hidden[name="__RequestVerificationToken"]').val()
},
success: function (partialReturn) {
$("#partial").html(partialReturn);
}
});
}
C#:
public PartialViewResult OnPostDelete([FromBody] long id, string dataAtual)
{
contaDTO.Remove(id, contaDTO.Database, contaDTO.ContaCollection);
dataCorrente = DateTime.ParseExact(dataAtual, "yyyy-MM", null).AddMonths(1);
contas = BuscarContasUsuarioMes(User.Identity.Name, dataCorrente);
return Partial("_PartialContas", contas);
}
I already checked with debugger and my variables are ok and filled with value expected (One test was like {id: 50, dataAtual: '2023-01'}
Checked a lot of forums, but Couldn't figure out how to make this thing work.
By declaring the number parameter with [FromBody] you tell ASP.NET Core to use the input formatter to bind the provided JSON (or XML) to a model. So your test should work, if you provide a simple model class.
Have you tried to remove it and sending value to the action?
—- UPDATE ——
Try this
function deleteConta(id) {
var data = $("#monthSelector").val();
$.ajax({
type: "POST",
url: '/Contas/ContaView?handler=Delete',
data: { id: id, dataAtual: data },
headers:
{
"RequestVerificationToken": $('input:hidden[name="__RequestVerificationToken"]').val()
},
success: function (partialReturn) {
$("#partial").html(partialReturn);
}
});
}
I don´t know why my parameter "ParametroFiltro Filtro" is getting null, the other parameters "page" and "pageSize" is getting OK.
public class ParametroFiltro
{
public string Codigo { get; set; }
public string Descricao { get; set; }
}
My ApiController Get method:
public PagedDataModel<ParametroDTO> Get(ParametroFiltro Filtro, int page, int pageSize)
My ajax call:
var fullUrl = "/api/" + self.Api;
$.ajax({
url: fullUrl,
type: 'GET',
dataType: 'json',
data: { Filtro: { Codigo: '_1', Descricao: 'TESTE' }, page: 1, pageSize: 10 },
success: function (result) {
alert(result.Data.length);
self.Parametros(result.Data);
}
});
You are trying to send a complex object with GET method. The reason this is failing is that GET method can't have a body and all the values are being encoded into the URL. You can make this work by using [FromUri], but first you need to change your client side code:
$.ajax({
url: fullUrl,
type: 'GET',
dataType: 'json',
data: { Codigo: '_1', Descricao: 'TESTE', page: 1, pageSize: 10 },
success: function (result) {
alert(result.Data.length);
self.Parametros(result.Data);
}
});
This way [FromUri] will be able to pick up your complex object properties directly from the URL if you change your action method like this:
public PagedDataModel<ParametroDTO> Get([FromUri]ParametroFiltro Filtro, int page, int pageSize)
Your previous approach would rather work with POST method which can have a body (but you would still need to use JSON.stringify() to format body as JSON).
Provide the contentType property when you make the ajax call. Use JSON.stringify method to build the JSON data to post. change the type to POST and MVC Model binding will bind the posted data to your class object.
var filter = { "Filtro": { "Codigo": "_1", "Descricao": "TESTE" },
"page": "1", "pageSize": "10" };
$.ajax({
url: fullUrl,
type: 'POST',
dataType: 'json',
contentType: 'application/json',
data: JSON.stringify(filter),
success: function (result) {
alert(result.Data.length);
self.Parametros(result.Data);
}
});
It's also possible to access POST variables via a Newtonsoft.Json.Linq JObject.
For example, this POST:
$.ajax({
type: 'POST',
url: 'URL',
data: { 'Note': note, 'Story': story },
dataType: 'text',
success: function (data) { }
});
Can be accessed in an APIController like so:
public void Update([FromBody]JObject data)
{
var Note = (String)data["Note"];
var Story = (String)data["Story"];
}
If you append json data to query string, and parse it later in web api side. you can parse complex object too. It's useful rather than post json object, espeicaly in some special httpget requirement case.
//javascript file
var data = { UserID: "10", UserName: "Long", AppInstanceID: "100", ProcessGUID: "BF1CC2EB-D9BD-45FD-BF87-939DD8FF9071" };
var request = JSON.stringify(data);
request = encodeURIComponent(request);
doAjaxGet("/ProductWebApi/api/Workflow/StartProcess?data=", request, function (result) {
window.console.log(result);
});
//webapi file:
[HttpGet]
public ResponseResult StartProcess()
{
dynamic queryJson = ParseHttpGetJson(Request.RequestUri.Query);
int appInstanceID = int.Parse(queryJson.AppInstanceID.Value);
Guid processGUID = Guid.Parse(queryJson.ProcessGUID.Value);
int userID = int.Parse(queryJson.UserID.Value);
string userName = queryJson.UserName.Value;
}
//utility function:
public static dynamic ParseHttpGetJson(string query)
{
if (!string.IsNullOrEmpty(query))
{
try
{
var json = query.Substring(7, query.Length - 7); //seperate ?data= characters
json = System.Web.HttpUtility.UrlDecode(json);
dynamic queryJson = JsonConvert.DeserializeObject<dynamic>(json);
return queryJson;
}
catch (System.Exception e)
{
throw new ApplicationException("can't deserialize object as wrong string content!", e);
}
}
else
{
return null;
}
}
In .NET Core, the HttpClient sets the transfer-encoding: chunked header by default. This can cause the .NET Web API controller parameters to be null.
To get around this, you'll need to set the ContentLength header explicitly:
var json = JsonConvert.SerializeObject(myObject);
var content = new StringContent(json, Encoding.UTF8, "application/json");
content.Headers.ContentLength = json.Length;
var response = await client.PostAsync("http://my-api.com", content);
SO answer if you already know the transfer-encoding header is the issue: How to disable Chunked Transfer Encoding in ASP.Net C# using HttpClient
Related bug which won't be fixed, which gives some insight into the problem: https://github.com/dotnet/runtime/issues/30283
I have a server-side method used to return the data to the user. The data is stored in a SQL Server database and is mapped using EF 6. Once extracted from the database using an id value, the object is subsequently serialized using the Json.NET framework. The object is used "as is", without filtering out the references to other tables. Because of that, I've had to use the "PreserveReferencesHandling" option.
On the client-side, AJAX is used to call the method. I'm having trouble extracting the data from the object (client-side) which does get serialized and is delivered to the browser as expected.
Server-side method:
[WebMethod]
public static string ContactData(long id)
{
IService<Contact> contactService = new ContactService();
Contact contactEdit = contactService.GetById(id);
string str = JsonConvert.SerializeObject(contactEdit, new JsonSerializerSettings
{
PreserveReferencesHandling = PreserveReferencesHandling.Objects
});
return str;
}
Client-side function (the important part):
$.ajax({
type: "POST",
url: "Contacts.aspx/ContactData",
data: JSON.stringify({ id: contactId }), // id by which I am receiving the object
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (contact) {
$("#tbFirstName").val(contact.d[0].Contact.first_name); // I've tried various combinations to no avail
},
});
This is how the JSON object (testing purposes data) looks like in Visual Studio's JSON Visualizer:
And this is what the browser (FF 32, it that matters) receives:
Firebug
I will post more info if needed.
First parse the json before you process it. and loop through it using jquery each function.
$.ajax({
type: "POST",
url: "Contacts.aspx/ContactData",
data: JSON.stringify({ id: contactId }), // id by which I am receiving the object
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (contact)
{
var contact=jQuery.parseJSON(contact);
$.each(contact, function(i, item) {
alert(i + " ==> "+ item.first_name);
});
}
});
I am getting an error in an ajax call from jQuery.
Here is my jQuery function:
function DeleteItem(RecordId, UId, XmlName, ItemType, UserProfileId) {
var obj = {
RecordId: RecordId,
UserId: UId,
UserProfileId: UserProfileId,
ItemType: ItemType,
FileName: XmlName
};
var json = Sys.Serialization.JavaScriptSerializer.serialize(obj);
$.ajax({
type: "POST",
url: "EditUserProfile.aspx/DeleteRecord",
data: json,
contentType: "application/json; charset=utf-8",
dataType: "json",
async: true,
cache: false,
success: function(msg) {
if (msg.d != null) {
RefreshData(ItemType, msg.d);
}
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert("error occured during deleting");
}
});
}
and this is my WebMethod:
[WebMethod]
public static string DeleteRecord(Int64 RecordId, Int64 UserId, Int64 UserProfileId, string ItemType, string FileName) {
try {
string FilePath = HttpContext.Current.Server.MapPath(FileName);
XDocument xmldoc = XDocument.Load(FilePath);
XElement Xelm = xmldoc.Element("UserProfile");
XElement parentElement = Xelm.XPathSelectElement(ItemType + "/Fields");
(from BO in parentElement.Descendants("Record")
where BO.Element("Id").Attribute("value").Value == RecordId.ToString()
select BO).Remove();
XDocument xdoc = XDocument.Parse(Xelm.ToString(), LoadOptions.PreserveWhitespace);
xdoc.Save(FilePath);
UserInfoHandler obj = new UserInfoHandler();
return obj.GetHTML(UserId, UserProfileId, FileName, ItemType, RecordId, Xelm).ToString();
} catch (Exception ex) {
HandleException.LogError(ex, "EditUserProfile.aspx", "DeleteRecord");
}
return "success";
}
Can anybody please tell me what's wrong in my code?
I am getting this error:
{
"Message":"Invalid JSON primitive: RecordId.",
"StackTrace":"
at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializePrimitiveObject()
at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeInternal(Int32 depth)
at System.Web.Script.Serialization.JavaScriptObjectDeserializer.BasicDeserialize(String input, Int32 depthLimit, JavaScriptSerializer serializer)
at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize(JavaScriptSerializer serializer, String input, Type type, Int32 depthLimit)
at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize[T](String input)
at System.Web.Script.Services.RestHandler.GetRawParamsFromPostRequest(HttpContext context, JavaScriptSerializer serializer)
at System.Web.Script.Services.RestHandler.GetRawParams(WebServiceMethodData methodData, HttpContext context)
at System.Web.Script.Services.RestHandler.ExecuteWebServiceCall(HttpContext context, WebServiceMethodData methodData)",
"ExceptionType":"System.ArgumentException"
}
Just a guess what does the variable json contain after
var json = Sys.Serialization.JavaScriptSerializer.serialize(obj);?
If it is a valid json object like {"foo":"foovalue", "bar":"barvalue"} then jQuery might not send it as json data but instead serialize it to foor=foovalue&bar=barvalue thus you get the error "Invalid JSON primitive: foo"
Try instead setting the data as string
$.ajax({
...
data: '{"foo":"foovalue", "bar":"barvalue"}', //note the additional quotation marks
...
})
This way jQuery should leave the data alone and send the string as is to the server which should allow ASP.NET to parse the json server side.
Using
data : JSON.stringify(obj)
in the above situation would have worked I believe.
Note: You should add json2.js library all browsers don't support that JSON object (IE7-)
Difference between json.js and json2.js
it's working
something like this
data: JSON.stringify({'id':x}),
As noted by jitter, the $.ajax function serializes any object/array used as the data parameter into a url-encoded format. Oddly enough, the dataType parameter only applies to the response from the server - and not to any data in the request.
After encountering the same problem I downloaded and used the jquery-json plugin to correctly encode the request data to the ScriptService. Then, used the $.toJSON function to encode the desired arguments to send to the server:
$.ajax({
type: "POST",
url: "EditUserProfile.aspx/DeleteRecord",
data: $.toJSON(obj),
contentType: "application/json; charset=utf-8",
dataType: "json"
....
});
Jquery Ajax will default send the data as query string parameters form like:
RecordId=456&UserId=123
unless the processData option is set to false, in which case it will sent as object to the server.
contentType option is for the server that in which format client has sent the data.
dataType option is for the server which tells that what type of data
client is expecting back from the server.
Don't specify contentType so that server will parse them as query
String parameters not as json.
OR
Use contentType as 'application/json; charset=utf-8' and use JSON.stringify(object) so that server would be able to deserialize json from string.
I guess #jitter was right in his guess, but his solution didn't work for me.
Here is what it did work:
$.ajax({
...
data: "{ intFoo: " + intFoo + " }",
...
});
I haven't tried but i think if the parametter is a string it should be like this:
$.ajax({
...
data: "{ intFoo: " + intFoo + ", strBar: '" + strBar + "' }",
...
});
I was facing the same issue, what i came with good solution is as below:
Try this...
$.ajax({
type: "POST",
url: "EditUserProfile.aspx/DeleteRecord",
data: '{RecordId: ' + RecordId + ', UserId: ' + UId + ', UserProfileId:' + UserProfileId + ', ItemType: \'' + ItemType + '\', FileName: '\' + XmlName + '\'}',
contentType: "application/json; charset=utf-8",
dataType: "json",
async: true,
cache: false,
success: function(msg) {
if (msg.d != null) {
RefreshData(ItemType, msg.d);
}
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert("error occured during deleting");
}
});
Please note here for string type parameter i have used (\') escape sequence character for denoting it as string value.
Here dataTpe is "json" so, data/reqParam must be in the form of string while calling API,
many as much as object as you want but at last inside $.ajax's data stringify the object.
let person= { name: 'john',
age: 22
};
var personStr = JSON.stringify(person);
$.ajax({
url: "#Url.Action("METHOD", "CONTROLLER")",
type: "POST",
data: JSON.stringify( { param1: personStr } ),
contentType: "application/json;charset=utf-8",
dataType: "json",
success: function (response) {
console.log("Success");
},
error: function (error) {
console.log("error found",error);
}
});
OR,
$.ajax({
url: "#Url.Action("METHOD", "CONTROLLER")",
type: "POST",
data: personStr,
contentType: "application/json;charset=utf-8",
dataType: "json",
success: function (response) {
console.log("Success");
},
error: function (error) {
console.log("error found",error);
}
});
If manually formatting JSON, there is a very handy validator here: jsonlint.com
Use double quotes instead of single quotes:
Invalid:
{
'project': 'a2ab6ef4-1a8c-40cd-b561-2112b6baffd6',
'franchise': '110bcca5-cc74-416a-9e2a-f90a8c5f63a0'
}
Valid:
{
"project": "a2ab6ef4-1a8c-40cd-b561-2112b6baffd6",
"franchise": "18e899f6-dd71-41b7-8c45-5dc0919679ef"
}
On the Server, to Serialize/Deserialize json to custom objects:
public static string Serialize<T>(T obj)
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
MemoryStream ms = new MemoryStream();
serializer.WriteObject(ms, obj);
string retVal = Encoding.UTF8.GetString(ms.ToArray());
return retVal;
}
public static T Deserialize<T>(string json)
{
T obj = Activator.CreateInstance<T>();
MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json));
DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
obj = (T)serializer.ReadObject(ms);
ms.Close();
return obj;
}
I had the same issue. I was calling parent page "Save" from Popup window Close. Found that I was using ClientIDMode="Static" on both parent and popup page with same control id. Removing ClientIDMode="Static" from one of the pages solved the issue.
these answers just had me bouncing back and forth between invalid parameter and missing parameter.
this worked for me , just wrap string variables in quotes...
data: { RecordId: RecordId,
UserId: UId,
UserProfileId: UserProfileId,
ItemType: '"' + ItemType + '"',
FileName: '"' + XmlName + '"'
}
I have been happy serializing with javascript objects into JSON using
JSON.stringify
And sending along to my "static" webmethod in c#/asp.net and sure enought it arrives .. I need the correct number of parameters hence if my json object has "startDate","endDate","reserve" then my webmethod needs these as parameters.
"Basically with my order object that i have, i have a number of parameters on this object so i would need to use the same number on the webmethod - this is a bit messy??" - I will explain
I have a rather complex "Order" object in javascript and wish to serialize it using stringify and send it along to my webmethod but i don't want to specify all the parameters is there a way round this?
I was hoping for something like this on my webmethod
public static bool MakeReservation(object order)
Then in my webmethod i only have 1 parameter BUT i can then desearilize this to a true c# object using JSON.NET. I have tried it like this sending the json across but because there is ONLY 1 parameter on my webmethod its failing.
Basically what i am trying to say if i that i want to continue to use my webmethod but i don't want to have to do specify 15 parameters on the webmethod
I want the JSON - String to arrive into my webmethod and then i can decompose it on the server.
Is this possible?
Here is how i am currently sending my JSON to the server (webmethod) using jquery
var jsonData = JSONNew.stringify(orderObject);
$.ajax({
type: "POST",
url: "MyService.aspx/DoReservation",
data: jsonData,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(msg) {
success = true;
},
error: function(msg) {
success = false;
},
async: false
});
If you try to submit an object that looks like this:
JSON.stringify({ endDate: new Date(2009, 10, 10), startDate: new Date() });
it will try and map endDate and startDate to corresponding parameters in your webmethod. Since you only want to accept one single method, I suspect you may get away with it by submitting the following:
JSON.stringify({ order: orderObject });
Which it might reasonably try to assign as a value to the 'order' parameter of your webmethod. Failing that, submitting
JSON.stringify({ order: JSON.stringify(orderObject) });
and then deserializing it using JSON.NET should definitely work, but it's uglier, so try the first example first. That's my best shot.
It's possible. I'm not so good at explaining stuff, I'll just show you my example code:
Javascript:
var Order = function(name, orderid, price) {
this.name = name;
this.orderid = orderid;
this.price = price;}
var pagePath = window.location.pathname;
function setOrder() {
var jsOrder = new Order("Smith", 32, 150);
var jsonText = JSON.stringify({ order: jsOrder });
$.ajax({
type: "POST",
url: pagePath + "/SetOrder",
contentType: "application/json; charset=utf-8",
data: jsonText,
dataType: "json",
success: function(response) {
alert("wohoo");
},
error: function(msg) { alert(msg); }
});
}
C# Code behind
public class Order
{
public string name { get; set; }
public int orderid { get; set; }
public int price { get; set; }
}
[WebMethod]
public static void SetOrder(object order)
{
Order ord = GetOrder(order);
Console.WriteLine(ord.name +","+ord.price+","+ord.orderid);
}
public static Order GetOrder(object order)
{
Order ord = new Order();
Dictionary<string,object> tmp = (Dictionary<string,object>) order;
object name = null;
object price = null;
object orderid = null;
tmp.TryGetValue("name", out name);
tmp.TryGetValue("price", out price);
tmp.TryGetValue("orderid", out orderid);
ord.name = name.ToString();
ord.price = (int)price;
ord.orderid = (int) orderid;
return ord;
}
My code isn't that beautiful but I hope you get the meaning of it.
I recently went through this very issue with a complexe JSON object I wanted to deserilize in my controller. The only difference is I was using the .toJSON plugin on the client instead of .stringify.
The easy answer:
public static bool MakeReservation(string orderJSON)
{
var serializer = new JavaScriptSerializer();
var order = serializer.Deserialize<Order>(orderJSON);
}
Now, as a longer term solution we created a custom ActionFilterAttribute to handle these cases. It detects the JSON parameters and handles deserilizing the object and mapping to the action. You may want to look into doing the same.