Parse custom JSON string to DateTime Convert in API - c#

My Question is similar to this one (The JSON value could not be converted to System.DateTime), where I am trying to convert an input string to an DateTime. The difference, however, is that the input string cannot be changed. I have no choice in it.
[HttpPut("PutBodyToFoodChain")]
public async Task<IActionResult> PutBodyToFoodChain([FromBody] TxMSAGrading body)
{ ... }
What I've tried:
[JsonConverter(typeof(DateFormatConverter), "MM/dd/yyyy hh:mm:ss")]
public DateTime KillDate { get; set; }
Error:
The JSON value could not be converted to System.DateTime
Input String:
{"GradeDate": "08/24/2020 01:36:00", "KillDate" : "08/24/2020 00:00:00", ... }
Additional Information:
I cannot change the model. So it will always be parsed in to be converted to a Date-Time.
There are 500+ fields in the model. I can't explicitly convert every Date-time field.
DateTime fields will always have the same format.

One idea is to defer parsing until after the raw string is captured in your model. This allows deserialization to succeed more reliably and for you to have control over the parsing. For example, an updated model:
public string KillDate { get; set; }
public DateTime KillDateValue => DateTime.TryParse(KillDate, out DateTime parsed) ? parsed : DateTime.MinValue;
public bool KillDateParsed => KillDateValue != DateTime.MinValue;
If parsing succeeds, KillDateParsed will be true and you'll have the parsed value in KillDateValue. DateTime.TryParse can also be provided a specific pattern to match.

Related

Force Xml.Serializer to serialize DateTime as 'hh:mm:ss'

I have generated proxy from the wsdl file and it generated this way.
System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified, **DataType = "time"**, Order = 8)]
public System.DateTime startTime
{
get
{
return this.myTimeField;
}
set
{
this.myTimeField= value;
}
}
See the DataType = "time" here
public partial class MyList
{
private string xfiels;
private System.DateTime MyTimeField;
}
Here the MYTimeField is DateTime field and the datatype field is specified as DataType = "time".
The problem I am facing is that the service expects dates to be formatted as hh:mm:ss and the XSD generated code seems to produce only YYYY-MM-DD hh:mm:ss.
When i modify proxy class datatype to string i am recieving response from the service.
Can i Force Xml.Serializer to serialize DateTime as 'hh:mm:ss' so that i dont want to modify the generated code

Converting value type inside class property

Hi I am having a simple problem, I am trying to convert (value is DateTime and i want to convert it to string) value type inside class to another type, so far i have tried:
private string timestamp;
public string timestamp
{
get => timestamp;
set
{
if (value != timestamp)
{
timestamp = (DateTime)value.ToString("dd'/'MM'/'yyyy HH':'mm':'ss.fff");
}
}
}
But with no luck. Is there a solution for this??
You are converting a string to a string using ToString with a formatter that you would expect on a DateTime, and then you're casting it to a DateTime that has to be assigned to a string.
Obviously, this cannot work.
If you are trying to validate if the new property-value (Value) can be considered as a valid string, then use DateTime.TryParseExact to verify if the given string is a valid DateTime. If so, assign the string to the backing field of the property.
set
{
if (value != timestamp && DateTime.TryParseExact(value,
"dd'/'MM'/'yyyy HH':'mm':'ss.fff",
CultureInfo.CurrentCulture,
DateTimeStyles.None, DateTime out d )
{
timestamp = value;
}
}
You will have to fiddle around a bit with the arguments of the TryParseExact method to see what works in your scenario.

Set format of data for serializer in WCF

I have something like:
[DataContract]
DateTime date;
However, I have specific format of my date: 20170403. How to force WCF serializer to serialize such format ? At this moment it returns validation error. How to do it ?
DataContractSerializer is going to follow the expected XML date format rules for dates, so if the other end isn't expecting that: you simply can't use a date. You'll have to expose it as a string instead:
public DateTime Date {get;set;} // note no serialization attribs
[DataMember(Name="date")]
public string DateString {
get { return Date.WhateverFormattingCodeYouWantHere(); }
set { Date = value.WhateverParsingCodeYouWantHere(); }
}
[Serializable]
[DataContract(IsReference = true)]
public className{
[DataMember]
DateTime date;
}
Hope this will help

JSON.NET Serialize Date

I would like to serialize my date to be in a specific format but I can't get my act together.
I tried building a nice little class but the output gets wrapped in quotes, which doesn't work.
I'd like the JSON to look like this...
{
date : new Date(2013, 8, 30)
}
but I get this...
{
date: "new Date(2013, 8, 30)"
}
my class
public class DateCell : ChartCell
{
[JsonIgnore]
public DateTime Value { get; set; }
[JsonProperty(PropertyName = "date")]
public override object DataValue
{
get
{
return string.Format("new Date({0}, {1}, {2})", this.Value.Year, this.Value.Month - 1, this.Value.Day);
}
}
}
There's a difference between a JavaScript Object and JSON. What you described might be valid in a JavaScript object, but it is not valid JSON. JSON does not allow the representation that you are asking for.
In JSON a value can only be one of the following:
A string, such as "abc"
A number, such as 123 or -12.34
A literal value of true, false, or null
An array of other valid values, such as [1,"a",true]
Another JSON object, such as { a: 1, b: "abc" }
It cannot just be a JavaScript Object, or any other arbitrary JavaScript. See the spec at json.org.
Passing a Date object constructor would not make any sense, as JSON is a general purposed serialization format, and Date is a JavaScript native class. How would you expect non-JavaScript code to interpret this?
While there is no specific date or time format defined by the JSON standard, the de facto standard is the ISO 8601 format. Your DateTime would look something like "2013-09-30T00:00:00". There are other ways to serialize a date, but they are not as uniform or popular.
In JSON.Net, the ISO 8601 format is the default. So you don't need to do anything special other than just to serialize your object with its original properties.
public class DateCell : ChartCell
{
public DateTime Value { get; set; }
}
UPDATE
Since you said in comments that you are passing this to Google Charts, it appears from their reference that they are using a nonstandard format that looks like the Date constructor, but has omitted the new keyword. Why they do this, I'm not sure, but you should be able to modify your original code as follows:
public class DateCell : ChartCell
{
[JsonIgnore]
public DateTime Value { get; set; }
[JsonProperty(PropertyName = "date")]
public override object DataValue
{
get
{
return string.Format("Date({0},{1},{2})", this.Value.Year, this.Value.Month - 1, this.Value.Day);
}
}
}

Format a string to display the Date correctly

I need help converting this string --> 20090727 10:16:36:643 to --> 07/27/2009 10:16:36
The original date and time are being returned by the SynchronizationAgent.LastUpdated() function, which returns a String in the above format.
Original question:preserved for reference
I have this -->
HUD.LastSyncDate = mergeSubscription.SynchronizationAgent.LastUpdatedTime;
Which is setting a property that looks like this -->
public static string LastSyncDate
{
get { return _lastSyncDate; }
set
{
_lastSyncDate = String.Format(CultureInfo.InvariantCulture,"{0:G}", value);
}
}
Unfortunately, with or without the String.Format the date that is displayed looks like this --> 20090727 10:16:36:643
I have tried multiple variations to Format it the way I want. What am I missing?
Based on the below suggestions(Mostly Joel's), I implemented the suggested changes but I am still getting a "String is not a valid DateTime error"
I also tried implementing this -->
HUD.LastSyncDate = DateTime.ParseExact(mergeSubscription.SynchronizationAgent.LastUpdatedTime,"yyyyMMdd HH:mm:ss:fff",CultureInfo.InvariantCulture);
but still nothing.
HUD.LastSyncDate = DateTime.Parse(mergeSubscription.SynchronizationAgent.LastUpdatedTime).ToString("MM/dd/yyyy")
You can put any format string you want there. But it sounds like what you really want is something more like this:
private static DateTime _lastSyncDate;
public static DateTime LastSyncDate
{
get { return _lastSyncDate; }
set { _lastSyncDate = value;}
}
public static string LastSyncDateString
{
get { return LastSyncDate.ToString("MM/dd/yyyy"); }
}
Keep it as a datetime in the background and just use the string property for display.
It appears to me that LastUpdatedTime is actually a string (since you can do the assignment) not a DateTime. In that case, the format applied won't do anything. You'll want to parse the LastUpdatedTime into a DateTime then reformat into the format that you want before assigning it to your string.
DateTime lastUpdated = DateTime.Parse( mergeSubscription.SynchronizationAgent.LastUpdatedTime );
HUD.LastSyncDate = string.Format( "{0:G}", lastUpdated );
public static string LastSyncDate { get; set; }
Note that you may need to use ParseExact instead.
DateTime lastUpdated = DateTime.ParseExact( "yyyyMMdd HH:mm:ss:fff",
...,
CultureInfo.InvariantCulture );
What do you want to do? You get a string, pass it to String.Format() and store it in a string field. Do you want to reformat the string? In this case you have to parse the string back to DateTime and format this value again.
DateTime dateTime;
if (DateTime.TryParse(value, out dateTime))
{
lastSyncDate = String.Format(CultureInfo.InvariantCulture,"{0:G}", dateTime);
}
else
{
HandleInvalidInput(value);
}

Categories