Unable to save Date to salesforce? - c#

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
}
});
}

Related

Postman shows datetime as unknown format

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
});

Parse JSON and find element with closest matching date

I have a JSON string containing some data.
I do not have types declared to match and am using dynamics, as there are many, many instances where API calls are made and JSON with totally different structures are returned.
What I am trying to do is loop through the array of entries in the first element of days - and get the entry where it's dateTime closely matches the current date time.
The error I am having is :
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: Cannot
implicitly convert type Newtonsoft.Json.Linq.JArray' tostring'. An
explicit conversion exists (are you missing a cast?)
I believe there's some added complexity with the need to use dynamics, and navigating through the reasonably complex data structure.
Here is what I have tried.
dynamic windData = JsonConvert.DeserializeObject(resultWindAPI); //resultWindAPI is the JSON presented below.
string windEntries = windData.forecasts.wind.days[0].entries;
dynamic windEntryData = JsonConvert.DeserializeObject(windEntries);
//find closest wind time to get most recent data
int min = int.MaxValue;
DateTime now = new DateTime();
dynamic currentWindEntry = windEntryData[0];
foreach(dynamic entry in windEntryData)
{
DateTime thisDateTime = entry.dateTime;
if (Math.Abs(thisDateTime.Ticks - now.Ticks) < min)
{
min = (int)thisDateTime.Ticks - (int)now.Ticks;
currentWindEntry = entry;
}
}
//Do something with the currentWindEntry
Here is an example of the JSON I am trying to parse.
According to the error message
string windEntries = windData.forecasts.wind.days[0].entries;
is the problem.
You already have access to the entries via the dynamic variable before so just assign it.
dynamic windEntryData = windData.forecasts.wind.days[0].entries;

Passing date as string - prevent json.net from parsing date

I have a Web API middle layer which consumes an API which exposes a field which carries a timestamp as string (the field is string and it contains a value like "2016-05-31T14:12:45.753Z").
The proxy classes in the middle tier are generated using Visual Studio from Swagger endpoint and under the hood the object is deserialized using Json.NET.
I can see that the field was received as string (that's good):
inputObject {{ "When": "2016-05-31T14:12:45.753Z" }} Newtonsoft.Json.Linq.JToken {Newtonsoft.Json.Linq.JObject}
However, even though the target field is string the value of inputObject["When"] is a parsed as a timestamp.
inputObject["When"] {31/05/2016 14:12:45} Newtonsoft.Json.Linq.JToken {Newtonsoft.Json.Linq.JValue}
Then
JToken whenValue = inputObject["When"];
if (whenValue != null && whenValue.Type != JTokenType.Null)
{
this.When = ((string)whenValue);
}
In the end this.When is a string with value 31/05/2016 14:12:45.
Is there an option to prevent json.net from parsing the date and then casting it to string again?
Please remember that this transformation happens in auto generated code so I'm looking for some way of decorating the field on the server side which would make Swagger mark it somehow and then the generated classes would avoid the deserialize/serialize issue.
Something like:
[JsonProperty("This really is a string, leave it alone")]
public string When { get; private set; }
(Answering my own question)
I needed a solution quickly and this is my temporary solution, for the record.
I format the date as
"When": "2016-05-31 14:12:45"
and not
"When": "2016-05-31T14:12:45.753Z"
This prevents it from being interpreted. The front end (javascript) code knows that timestamps from the API are UTC and it appends 'Z' before transforming the timestamp to local time and formatting for display, e.g:
<td>{{vm.prettyDateTimeFormat(item.StatusDate+'Z')}}</td>
The ctrl code:
vm.prettyDateTimeFormat = function (dateString)
{
var momentDate = moment(dateString, "YYYY-MM-DD HH:mm:ssZZ");
if (typeof(momentDate) === "undefined" || (!momentDate.isValid()))
{
return dateString;
}
//The format needs to be sortable as it ends up in the grid.
var nicePrettyDate = momentDate.format('YYYY-MM-DD HH:mm:ss');
return nicePrettyDate;
}
As far as I don't like this solution it carried us through the demo. This issue is obviously in the back log now to be addressed properly.
[JsonIgnore]
public string When { get; private set; }

ODP.NET: Oracle date formatting to "output-only" formats

I'd like to use Oracle date formatting in C#, such as in to_char(date, format), without database connection nor writing my own format interpreter.
Sample application (I'm using Oracle Data Provider for .NET):
namespace OracleDateToCharTest
{
using System;
using Oracle.DataAccess.Client;
using Oracle.DataAccess.Types;
class Program
{
/// <param name="fmt"> Oracle-like format string. </param>
public static string OracleDateToChar(DateTime date, string fmt)
{
//// preparing format for ToString()
OracleGlobalization og = OracleGlobalization.GetThreadInfo();
string prevFormat = og.DateFormat;
og.DateFormat = fmt;
try
{
//// converting to OracleDate
OracleDate odacDate = new OracleDate(date);
//// setting format for ToString()
OracleGlobalization.SetThreadInfo(og);
return odacDate.ToString();
}
catch (OracleTypeException ex)
{
if (ex.Number == 1820)
{
//// described issue
}
throw;
}
finally
{
og.DateFormat = prevFormat;
OracleGlobalization.SetThreadInfo(og);
}
}
static void Main(string[] args)
{
var x = OracleDateToChar(DateTime.Now, "mm-dd-yyyy");
var y = OracleDateToChar(DateTime.Now, "mm-dd-yyyy HH24:Mi:ss");
var z = OracleDateToChar(DateTime.Now, "IW"); //// exception
}
}
}
It works well with formats like "mm-dd-yyyy", "mm-dd-yyyy HH24:Mi:ss", but unfortunately it doesn't work with "output-only" formats like "IW" (output-only formats are formats that you can specify in TO*_DATETIME funcitons according to Table 9-4 on http://docs.oracle.com/cd/B28359_01/olap.111/b28126/dml_commands_1029.htm).
When I call for example
OracleDateToChar(DateTime.Now, "IW")
I get ORA-01820 format code cannot appear in date input format exception in ToString() line.
I'd understand if I got this error in ToDate() method, but in ToString() it seems to be a bug in ODP.NET.
Question: Is there a way to implement OracleDateToChar method that can handle output-only formats? (assuming that calling select to_char(:date, :fmt) from nvl; from oracle database is not an option)
The point about that Oracle documentation is that it applies to DATE_FORMAT which is part of the Oracle language. Therefore you can only execute it as a PL/SQL statement which is why you cannot get it to work client side: IW is not a valid format mask for ODP.Net globalization as far as I know. In fact the ODP globalization DateFormat defaults to whatever you have in NLS_DATE_FORMAT locally which is a full date format string, whereas IW is for getting the week of the year rather than for formatting a date itself. As far as I know, nothing in the .Net framework will recognise that Oracle-specific string, so in order for it to work you would need to issue a command to Oracle and get the result back, as per the example on that page:
CONSIDER mydatetime
DATE_FORMAT MON-RRRR-DD-HH24
That seems like a lot of overkill to change a date format. There are some good alternative siggestions which are client-side .Net in this SO answer
Further Reading
The Oracle docs for the Oracle Date Structure (OracleDate) ToString() method notes that
The returned value is a string representation of the OracleDate in the
format specified by the thread's OracleGlobalization.DateFormat
property
(My emphasis). The definition for this can be found here. A useful list of allowed format strings for NLS_DATE_FORMAT, and therefore by extension OracleDate.ToString, can be found here.

Providing DateTime values in OData

I'm currently writing a special client application to allow our unit tests to work with an OData interface using the XML structure for atom feeds.
All seems to be working properly, but i'm running into trouble when I need to pass a DateTime value as property.
I've written the following code that extracts the DateTime value from the property of the object and stores it in a specific format:
private static void GenerateProperty<T>(StringBuilder xml, T obj, PropertyInfo info)
{
// Extract the information about the property if it contains a value.
if (info.GetValue(obj, null) == null) return;
string type = info.GetGetMethod().ReturnType.ToString().Split('.').Last();
string value = info.GetValue(obj, null).ToString();
if (type == "DateTime")
value = ((DateTime)info.GetValue(obj, null)).ToString("yyyy-mm-ddThh:mm:ss");
if (type == "Boolean") value = value.ToLower();
// Append the property to the generated XML.
xml.Append(type.ToLower().Equals("string") ?
string.Format("<d:{0}>{1}</d:{0}>", info.Name, value) :
string.Format("<d:{0} m:type=\"Edm.{1}\">{2}</d:{0}>", info.Name, type, value));
}
The code is heavy on reflection, but that's beside the point. The values returned by this code for a DateTime are in the following format: 2011-49-13T11:49:41Z
However, i'm receiving the following error from my OData Service:
Error processing request
stream. Error encountered in converting the value from request payload
for property 'Created' to type 'System.DateTime', which is the
property's expected type. See inner exception for more
detail.
The string '2011-49-13T11:49:41Z' is not a valid AllXsd
value.
System.FormatException
at System.Xml.XmlConvert.ToDateTime(String s,
XmlDateTimeSerializationMode dateTimeOption)
 at
System.Data.Services.Parsing.WebConvert.StringToPrimitive(String text,
Type targetType)
 at
System.Data.Services.Serializers.PlainXmlDeserializer.ConvertValuesForXml(Object
value, String propertyName, Type typeToBeConverted)
So apparently it doesn't understand the DateTime format, but when I look at the documentation that's posted here: http://www.odata.org/developers/protocols/overview#AbstractTypeSystem
I'd expect it to be valid. Anyone have any experience with this?
yyyy-mm-ddThh:mm:ss
should be
yyyy-MM-ddTHH:mm:ssZ
ToString("O") will solve the problem too.

Categories