I am using Servicestack and Ormlite for my project and testing with postman.
The C# type I am using for my timestamps is DateTime and it processes the info correctly to and from the MySql database. When I return the value in my response the value looks correct but when the response is inspected in either Postman or just browsing to the the request url the value I see is
[
{
"id": 1,
"accountType": 1,
"name": "Mr J Smith",
"memberSince": "/Date(1539189581000-0000)/",
"phone": "8138138138",
"email": "jjj#jjj.com",
"emailVerified": false
}
]
The value I send out is
MemberSince = {10/10/2018 12:39:41 PM}
Why the discrepancy? Is it a different format? How do I globally convert it?
UPDATE
I add this to my initialization routine and it works. Is this the best way to do this?
JsConfig<DateTime>.SerializeFn = time => new DateTime(time.Ticks, DateTimeKind.Utc).ToString("o");
JsConfig<DateTime?>.SerializeFn = time => time != null ? new DateTime(time.Value.Ticks, DateTimeKind.Utc).ToString("o") : null;
JsConfig.DateHandler = DateHandler.ISO8601;
I suggest you to check the serializer you are using, it has nothing to do with postman, is the way you are returning the data from the backend.
For example:
return Json(
new DataSourceResult
{
Data = "testing"
});
When the serializer sends this data the word Data on the ajax/javascript side I need to read it as data in lower case, because the serializer set the first letter to lower case.
So first of all, see what the serializer sends over the wire, and also try to change on your backend the format of your DateTime. As I am seeing the serializer takes all DateTime and convert them in that format. Try to send instead of the DateTime a string representation of the date and see what you receive on the other side. Should be the plain string.
Hope this helps
You can configure ServiceStack.Text to use the ISO8601 Date format with:
JsConfig.Init(new Config {
DateHandler = DateHandler.ISO8601
});
Related
I keep getting the error Cannot convert value to NodaTime.LocalTime, and I can't seem to find anyone else with the problem. I also can't find in the documentation how I can do this.
An example of what I'm trying to send is;
{
"time": "22:00"
}
Is something wrong with this format? As far as I'm aware, NodaTime.LocalTime is formatted exactly like this. I know a similar problem exists for the date object, but it really doesn't apply to this, as it has no Z at the end of the string. I also tried taking the semi-colon out of the string I send, but that didn't do anything.
Thank you!
your json is invalid, pls fix it according this example
using NodaTime.Serialization.JsonNet;
var d = new Data { time = NodaTime.LocalTime.Noon };
var json = JsonConvert.SerializeObject(d);
output
{"time":"12:00:00"}
So your json should be
var json = #"{
""time"": ""22:00:00""
}";
Data data = JsonConvert.DeserializeObject<Data>(json);
everything is working properly in this case
class
public class Data
{
public LocalTime time { get; set; }
}
I have an ugly JSON string that is getting returned from an API that looks like this (this is the result of Console.Write on the string):
{"d":"\"\\\"\\\\\\\"[{\\\\\\\\\\\\\\\"foo\\\\\\\\\\\\\\\":15,\\\\\\\\\\\\\\\"bar\\\\\\\\\\\\\\\":null}]\\\\\\\"\\\"\\n\""}
I am trying to parse this into a C# object in the simplest way possible, so I can access properties like foo and bar. But I am having a difficult time doing this.
I have tried parsing it a number of ways, including:
// code to get the response string
client.Headers.Add(HttpRequestHeader.ContentType, "application/json");
var serializedData = "{data: 'data'}";
var responseString = client.UploadString(url, "POST", serializedData);
// parse the response string
dynamic obj = Newtonsoft.Json.JsonConvert.DeserializeObject(jsonString);
This allows me to access the value of d, which is the actual string I need to parse. I then tried to parse that separately using JArray.Parse(obj["d"]), but I get an error saying that obj["d"] is not an array.
Unfortunately, I have no access to the API itself so can't modify how it's serializing the data it's returning.
Any suggestions?
You can replace all New Line, Backslash, Double quotes to format the JSON
var formattedJson = jsonString.Replace(#"\n", string.Empty)
.Replace(#"\", string.Empty)
.Replace("\"\"", string.Empty);
Console.WriteLine(formattedJson);
OUTPUT
{
"d": [
{
"foo": 15,
"bar": null
}
]
}
Convert to JArray.
var jArray = JArray.Parse(JObject.Parse(formattedJson)["d"].ToString());
Console.WriteLine($"{jArray[0]["foo"]} {jArray[0]["bar"]}");
OUTPUT
15
The problem is that the value of "d" is a string representing a string representing a string ... representing an array. You could call it JSON serialization "inception".
The way to deal with this is to deserialize the value corresponding number of times. If you're sure that the value is never going to be an actual string, you could do it like this, without having to know how many times the value was serialized:
var myObject = JObject.Parse(s);
var d = myObject["d"];
while(d.Type == JTokenType.String)
d = JToken.Parse(d.ToObject<string>());
myObject["d"] = d;
After this procedure myObject represents this data:
{
"d": [
{
"foo": 15,
"bar": null
}
]
}
Replacing escape characters in fine however I would not rely on the console.write command as the definitive output to examine. Here are a couple of other ways: -
Use Postman to make the API call so you can see the raw result. This will (hopefully) show it in an easy to read format that you can then define your class to deserialise to.
Write the raw response to a “.json” file. Open that file in a good editor (such as VS Code or VS itself) to see how the data is actually structured when it is received.
On a side note I would recommend using RestSharp to do the REST calls and Newtonsoft.Json to do the serialising/deserialising.
I have developed an ASP.NET Core middleware solution that calculates the value of the ETag that matches the GET request I am performing and returns it in the response.
The relevant code excerpt is below:
RequestHeaders requestHeaders = new RequestHeaders(actionContext.HttpContext.Request.Headers);
ResponseHeaders responseHeaders = new ResponseHeaders(actionContext.HttpContext.Response.Headers);
// return not modified for conditional GET and HEAD
if (requestHeaders.IfNoneMatch != null && (requestHeaders.IfNoneMatch.Any(val => val.Tag == eTag || val.Tag == "*")))
{
responseHeaders.ETag = new EntityTagHeaderValue(eTag);
actionContext.Result = new ObjectResult(null) { StatusCode = (int)HttpStatusCode.NotModified };
return;
}
responseHeaders.ETag = new EntityTagHeaderValue(eTag);
responseHeaders.CacheControl = new CacheControlHeaderValue() { MaxAge = TimeSpan.FromSeconds(600), Private = false };
With this code, I am successfully able to return an ETag response in the HTTP message, as well as get that ETag into an If-Match or If-None-Match header for subsequent responses.
However, there is some C# particularity I am missing, as when testing via Swagger, the headers of the response have weird formatting, as if I was doing a .ToString() on the C# property:
...
"date": "Tue, 24 Oct 2017 15:08:39 GMT",
"etag": "\"c96GUyc4QBo5w(...)ggSdPkEdgB1i56Qcs=\"",
"server": "Kestrel",
...
Is there a way to avoid the escaped \" in the HTTP response headers, or should I just ensure my clients all understand this limitation and properly parse the string?
When sending the other headers, the input format is the string without the \", which would make for a lot of extra conversion effort.
EDIT:
I discovered an alternative way to set the ETag that's less direct and doesn't check types (i.e. I don't have to use an EntityTagValue and can use a string directly)
actionContext.HttpContext.Response.Headers[HeaderNames.ETag] = eTag;
This way, the string is not escaped, and I can copy-paste it directly into further requests.
This is just a matter of how ToString() represents things. Because it gives a JSON form, quotes are escaped, and because E-Tags require quotes (except for *), the result is that there are escaped quotes. The quotes are not escaped as actual E-Tag headers in the HTTP though.
To my surprise , its not st.forward thing to do; saving Date to Salesforce .
I'm trying to update one field which is of type Date but it throws me some weird error .
Code :
var objSer = new JavaScriptSerializer();
string json = objSer .Serialize(new{
startdate = sfdcValue
});
MyUpdateMethod("objectName/" + id, json);
I tried to convert date to IS0 8601 standard (as suggested over SO)
1.) DateTime.UtcNow.ToString("s",System.Globalization.CultureInfo.InvariantCulture)
2.) DateTime.UtcNow.ToString("o")
Error Info :
{"message":"Cannot deserialize instance of double from VALUE_STRING
value 2017-05-26T10:31:40.5790708Z or request may be missing a
required field at [line:1, column:2]","errorCode":"JSON_PARSER_ERROR"}
You didn't elaborate on which method you are using to communicate between the server and client. I am using Javascript Remoting (#RemoteAction on the apex method) and I ran into this issue. For me, the date and datetime fields were being expected by Salesforce as date serials (your mileage may vary if using a different access method).
Given I was dealing with a dynamic list of fields, I ended up with a pair of marshall / unmarshall functions on the client that created client-only slave fields I removed before sending the data back to Salesforce (NB: the example below is javascript not c#). In your case, a marshall / unmarshall may take a different approach:
// Provide an client-only date field based on a date serial (SFDC input)
function createDateDerivedField(currentRecord, fieldName) {
Object.defineProperty(currentRecord, fieldName + '__ui', {
enumerable: true,
get: function () {
return currentRecord[fieldName] == null ? null : new Date(currentRecord[fieldName]);
},
set: function(newValue) {
// Update the original field
currentRecord[fieldName] = newValue == null ? null : (new Date(newValue)).getTime(); // Convert back to date serial
}
});
}
I get an error while parsing a json string into an object. I am using system.json to parse the json string.
The JSON file: (NOTE: I cannot change the structure of this json file because it is generated)
{
title: "My Title",
log: "",
nid: "1234",
type: "software",
language: "EN",
created: "1364480345",
revision_timestamp: "1366803957",
body: {
und: [
{
value: "abc",
summary: "def"
}
]
}
}
The C# code:
string jsonString = new WebClient().DownloadString(".......MyJson.json"); //For test purpose
var obj = JsonObject.Parse (jsonString); ///<--- At this line the exception is thrown
The Exception:
System.ArgumentException has been thrown.
Invalid JSON string literal format. At line 1, column 2
How to solve this?
Thanks in advance!
You can't. That isn't valid json. Field names must be enclosed in quotes. All json parsing tools will throw when trying to parse that.
You could process it and turn it to valid json before deserializing, but really, you need to correct it API side. No clients will work with that.
How to solve this?
(NOTE: I cannot change the structure of this json file because it is generated)
Easy, use json.Net. it works without any problem with your json
var j = JObject.Parse(jsonString);
You can even use dynamic keyword
dynamic j = JObject.Parse(jsonString);
Console.WriteLine("{0},{1}", j.title, j.body.und[0].value);