C#: Wrong DateTime format passed to front end - javascript

So I am returning a date value from my backend API.
This is my model:
public class Sales {
....
public DateTime DateCreated {get;set;}
}
I return it from my Controller:
[System.Web.Http.HttpGet]
public async Task<Sales> GetSales() {
.....
Sales s = await GetSalesForTheUser();
return s;
}
The DateTime value returned by the Controller is missing the Z at the end of it.
The returned value is: 2021-07-27T05:23:41.937 this is wrong because when I parsed it in the Javascript, it is treated as local date time. When I added Z at the end of it (2021-07-27T05:23:41.937Z) then this is right. The date parsing from the Javascript is giving me the correct value.
How can I fix the correct parsing value from my backend (C#)?

It sounds like the problem is within your DateTime object's Kind, and not the serialization.
If the DateTime.Kind is either Local or Unspecified, serializing this in ISO8601 will omit the timezone information (in your case Z, which indicates UTC).
To fix this, first start by trying to specify the kind of your DateTime before returning the data. See here how: https://learn.microsoft.com/en-us/dotnet/api/system.datetime.specifykind?view=net-5.0.
If that works, inspect your service, and see if you are correctly interpreting the data returned to populate the property Sales.DateCreated, and ensure this is in UTC.

I recommend using NewtonJson:
Add the package to your project
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="..." />
and you can achieve it by adding some configurations to your Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
...
// Configure controllers.
services.AddControllers()
.AddNewtonsoftJson(options =>
{
options.SerializerSettings.Converters.Add(new IsoDateTimeConverter()
{
DateTimeFormat = "yyyy-MM-ddTHH:mm:ss.fffZ"
});
});
...
}

If you want to change it on the backend, then create another property in
your Sales class like "DataCreatedFormated" of type string and public string DateCreatedFormated => DateCreated.ToString(format); where "format" is one from this article.
I suggest 'u' format.

Related

How to pass table of objects using query string?

i need to share some shipment information in my .NET Core 3.1 API project. I've designed an endpoint which returns a collection of objects which satisfy provided filtering conditions contained in SearchResultsDto object. The working principle of filtering mechanism is simple. On the client side, the user selects a property, and provides some value for it. The user may want to filter the table using one, two, or even more properties. So my controller method needs to take a collection of filters (pairs property-filter value) as a parameter. Here's my method, and Filter class definition:
[HttpGet]
public async Task<ActionResult<SearchResultsDto>> GetShipmentAsync([FromQuery] ICollection<Filter> filters,
[FromQuery] int page,
[FromQuery] int pageCapacity,
[FromQuery] DateTime dateTimeInfimum,
[FromQuery] DateTime dateTimeSupremum,
[FromQuery] bool withPodOnly) =>
Ok(await QueryBus
.SendAsync<GetShipmentQuery, SearchResultsDto>(new GetShipmentQuery
{
Page = page,
PageCapacity = pageCapacity,
DateTimeInfimum = dateTimeInfimum,
DateTimeSupremum = dateTimeSupremum,
WithPodOnly = withPodOnly,
Filters = filters
}));
public class Filter
{
public string PropertyName { get; set; }
public string FilterValue { get; set; }
}
How to correctly pass an array of Filter objects using the query string? Is it good approach to use query string for such a behavior? If not, how should i design my endpoint? How to serialize JavaScript objects, and send it using axios, in a proper way, using GET method?
I've already tried something like that:
https://localhost:44348/api/shipment?filters=[propertyName=materialReleaseReceipt&filterValue=WZ]&page=1&pageCapacity=4&dateTimeInfimum=2012-04-23T18:25:43.511Z&dateTimeSupremum=2012-04-23T18:25:43.511Z&withPodOnly=true
But it doesn't work. Filters collection is not parsed correctly.
If you want to pass the data via query string, you can pass it like below,
https://localhost:44385/weatherforecast?filters[0].Id=1&filters[1].Id=2
Just write the querystring like below:
https://localhost:44348/api/shipment?[0].propertyName=materialReleaseReceipt&[0].filterValue=WZ&page=1&pageCapacity=4&dateTimeInfimum=2012-04-23T18:25:43.511Z&dateTimeSupremum=2012-04-23T18:25:43.511Z&withPodOnly=true
For more details of model binding, you can refer to the doc

Time string to date object conversion js angularJS

I am getting following string from REST api,
20160220
I want to make it 20/02/2016
I am using angularJS. So I will require a filter.
I have tried following
app.filter('myDateFilter', function() {
return function(input) {
var st = input;
var pattern = /(\d{4})(\d{2})(\d{2})/;
var date = new Date(st.replace(pattern, '$1-$2-$3'));
return date;
}
});
And in html I have used
<td>
{{t["due-date"] | myDateFilter}}
</td>
This returns 2016-02-20T00:00:00.000Z
Regular expression issue? Can you kindly give me proper code which should have been used instead to generate 20/02/2016.
Naively converting a Date into a string results in the output you are seeing:
console.log(new Date()) // "2016-09-02T15:19:07.921Z"
Instead, make sure you format the date into a string manually before returning it. E.g. toLocaleDateString() converts the Date into a string, taking into account the browser's locale:
console.log(new Date().toLocaleDateString()) // "09/02/2016"
What you are doing is converting a String to a Date() object, which seems right to me. If you try to show your Date() object in your view, what you get is the default date format.
In order to customize the format in which your Date() object is showing, you need to chain another filter to your custom filter. In this case you need to use date filter: https://docs.angularjs.org/api/ng/filter/date
You would only need to add it to your template, like this:
<td>
{{t["due-date"] | myDateFilter | date : 'dd/MM/yyyy'}}
</td>
This way date filter will take as input the Date() object returned by your custom myDateFilter filter and produce a String representing that object as output.
This is a nice example of how angular filters and filter chaining are supposed to be used.

Laravel Timestamp Format / JavaScript Date

I've looked around, but haven't been able to find a clear way of returning Laravel timestamps / datetimes in a particular format. It doesn't really matter to me how it's saved in the database, but when I'm pulling the data, I'd like to format it so that it can be parsed by JavaScript. Does someone know of a good way that doesn't involve having to create multiple accessors?
Edit: To add more detail, I'm actually using AngularJS and would like the date returned in a format so that it can be understood by Angular and its date filter. With the current format, the date filter doesn't work because it can't parse the date, from what I can tell.
To define an accessor, create a getFooAttribute method on your model where Foo is the "camel" cased name of the column you wish to access.
So, you should define an accessor for the test_date (or anything else) attribute. The accessor will automatically be called by Eloquent when attempting to retrieve the value of test_date.
(In the example I'll define it in the User model)
<?php
namespace App;
use Carbon\Carbon;
class User extends Model {
protected $table = 'users';
public function getTestDateAttribute($date) {
//What format do you store in db?
$storedformat = createFromFormat('Y-m-d H:i:s', $date);
//What format would you like to show?
$customformat = $storedformat->format('Y.m.d. H:i:s');
return $customformat;
}
}
Then you'll see the following format by default:
$user = User::find(1);
$user->test_date; //2015.11.12. 8:50:20
If you'd like to write simplier code, you should use Traits.
Let's define the DateTrait in App\DateTrait.php file:
<?php
trait DateTrait {
public function getTestDateAttribute($date) {
//What format do you store in db?
$storedformat = createFromFormat('Y-m-d H:i:s', $date);
//What format would you like to show?
$customformat = $storedformat->format('Y.m.d. H:i:s');
return $customformat;
}
}
Then use it every model where you'd like to format the test_date column.
<?php
namespace App;
use Carbon\Carbon;
class User extends Model {
use App\DateTrait;
...
}
In your view just do something like this:
$variable->created_at->format('m-d-y')
This page here may be useful for getting familiar with Carbon dates and how you can use and format them.
Regarding the parsing of them to a format Javascript can interpret, perhaps you could do something like this - assuming it is coming from an eloquent object you have pulled in to a view or something like that:
{{ (new Carbon\Carbon($dataPassedIn->created_at))->format('F d, Y H:ia') }}
Which would return a date like this September 02, 2015 09:43am, although I'm not sure of the exact format you would need for parsing in to javascript.

cannot parse json serialized string with mongo db object id as well as "\"

I have a controller, which will return an json serialized string in a Get operation:
data='[{"user":"CORP\\\\test","id":55cca31dd40238220c11d5a7}]'
However, in my angular JS layer, the json parse cannot work:
JSON.parse(data)
(program):1 Uncaught SyntaxError: Unexpected token c
I tried and turns out it is the returned string should be:
data='[{"user":"CORP\\\\\\\\test","id":"55cca31dd40238220c11d5a7"}]'
(there are two more \, and there should be double quote for "id").
The strange thing is, I get the json string from .NET class:
var serializer = new JavaScriptSerializer();
return serializer.Serialize(obj);
And, below is the model class:
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public ObjectId Id { get; set; }
[BsonElement("User")]
public string User;
Anybody know how to resolve this issue to make the json parse in js code work?
To get the ObjectID to have quotes around it, I believe you need to change the type of the ID property to string as shown in this post.

create json string on client side

I am trying to create the JSON string / object that is equivalent to the following data on the server side. can somebody help?
Public Shared Function GetData() As List(Of Employee)
Dim list As New List(Of Employee)()
Dim newEmployee As New Employee()
newEmployee.EmployeeID = "1"
newEmployee.FirstName = "Sridhar"
newEmployee.Title = "Programmer"
newEmployee.BirthDate = "8/10/1979"
newEmployee.TitleOfCourtesy = "Programmer"
list.Add(newEmployee)
Return list
End Function
Employee is a class with the properties EmployeeId, FirstName, Title, Birthdate, TitleOfCourtesy.
Thanks,
sridhar.
Keep in mind that in Javascript there is no concept of a class, only objects. This also carries over into JSON. Look at this:
{"Employee" :
{
"EmployeeID":"1",
"FirstName":"Sridhar",
etc...
}
}
If you look at the first line, the "Employee" symbol does absolutely nothing for the JSON. Remember that we're dealing with ONLY objects.
Thats why this works, like you said.
[
{"EmployeeID":1,
"LastName":"Duggireddy",
"FirstName":"Sridhar",
"Title":"Programmer",
"TitleOfCourtesy":"Programmer",
"BirthDate":new Date(303091200000)}
]
To make this programatically, declare your employee objects, and just add them into an array, like so:
var employees = [];
employees.push(employee1); // you would use a loop, of course
employees.push(employee2);
...
var jsonString = parser.toJSON(employees); // or whatever you use.
That should give you a list of objects. Always ignore the class in JSON... .NET during the deserialization will attempt to coerce the object into that particular class. You only have problems if this fails - maybe because a variable is missing or of the wrong type.
Why not just use JSON.NET and let it handle encoding/decoding for you?
It will look like
{"Employee" :
{
"EmployeeID":"1",
"FirstName":"Sridhar",
etc...
}
}
Reference
I believe multiple instances of Employee in the JSON would look like this:
{"Employee" :
{
"EmployeeID":"1",
"FirstName":"Sridhar",
etc...
},
{
"EmployeeID":"2",
"FirstName":"Joe",
etc...
}
}
Maybe that is what you need?
There's a good jQuery plugin for JSON. It lets you go from a JavaScript object to JSON very easily.
http://code.google.com/p/jquery-json/

Categories