DateTime field internal format - asp.net-core

I have an ASP.NET Core MVC 1.0 app and inside of it a model that contains a DateTime field:
[Display(Name = "Date of Delivery"), DataType(DataType.Date)]
public DateTime? DateOfDelivery { get; set; }
In my Details.cshtml I refer to this field as usual:
#Html.DisplayFor(model => model.DateOfDelivery)
Depending on where I am, the output of this field differs! If I am testing on my local machine, the output is:
20.03.2017
on my on Azure deployed Website, it is:
3/20/2017
These different formats bring me into big trouble, as I am using a datepicker to fill the field in my Create/Edit controllers.
I also tried to set the date format explicit:
[DisplayFormat(DataFormatString = "{0:dd.MM.yyyy}", ApplyFormatInEditMode = true), Display(Name = "Date of Delivery"), DataType(DataType.Date)]
public DateTime? DateOfDelivery { get; set; }
This displayed an uniform date (20.03.2017) on both, local machine and Azure. But still the inputs that are accepted differ. Local:
20.03.2017
And on Azure:
03.20.2017
What can I do to ensure, that the accepted dateformat on both, my local machine and also on Azure, are the same? I already read a lot of Stackoverflow questions regarding date topics, but none was able to help me.

You can use #Html.TextBoxFor(model => model.DateOfDelivery, "{0:dd.MM.yyyy}") as in this post post

Related

Mudblazor DatePicker binding works one way only

I have been trying to bind mudblazor datepicker to a DateTime property using Date.
<MudDatePicker Label="Start Date" Date="#StartDate" />
<MudTextField Label="SelectedDate" #bind-Value="#StartDate" />
<MudText Typo="Typo.h3">Selected Date is: #StartDate</MudText>
#code
{
public DateTime StartDate { get; set; }
public string DateString { get; set; }
}
I have tried this code on their site and in visual studio
The code will update the Date Picker and my Text output when leaving the text field, this is normal behavior. However, I want to change the Text based on my selection of Date picker. I have tried binding to date and value. both don't reflect the selection I have made.
I have checked the documentation on their site and there is nothing on how to handle binding beyond what I am doing.
If any one knows how to bind Date picker in mudblazor please help.
Thanks
for anyone interested here is the answer:
A Date picker in Mudblazor will only bind to a nullable DateTime, and I have to use #bind-Date. So my sample code that should work looks like this:
<MudDatePicker Label="Start Date" #bind-Date="#StartDate" />
<MudTextField Label="SelectedDate" #bind-Value="#StartDate" />
<MudText Typo="Typo.h3">Selected Date is: #StartDate</MudText>
#code
{
public DateTime? StartDate { get; set; }
}
I was having a similar issue with MudDateRangePicker.
I found that I could use a nullable or a non-nullable DateRange variable but if I wanted to get the currently selected Start & End dates from a callback function, I would have to call the DateRangePicker.Close() method before I checked the dates.
Just FYI if anyone else is looking at this issue.

DateTime Field is not showing dateTime picker on MVC page [duplicate]

I am trying to populate #Html.EditorFor helper. I have created a view model with the below property
[DataType(DataType.Date, ErrorMessage="Date only")]
[DisplayFormat(DataFormatString = "{0:dd/MM/yy}", ApplyFormatInEditMode = true)]
public DateTime? YearBought { get; set; }
and my helper is set up as below (a)
#Html.ValidationMessageFor(m => m.YearBought)
#Html.EditorFor(model => model.YearBought, new { #type = "date" })
I have also tried (b)
#Html.ValidationMessageFor(m => m.YearBought)
#Html.EditorFor(model => model.YearBought.Value.Date)
Using the above format (a) nothing is displayed. Using the above format (b) 12/05/2014 00:00:00 is displayed in textbox format.
I am trying to achieve a datepicker format without a time displayed
I have reviewed several other questions but cant see what i've done different.
When I look in my database, the value is save as 2014-05-12 and when I am saving the value the EditorFor helper generates the required input facility
questions reviewed
first second third....the list goes on
EDIT
just opened the console in chrome dev tools and so this message
The specified value "12/05/14" does not conform to the required format, "yyyy-MM-dd"
I thought DisplayFormat(DataFormatString = "{0:dd/MM/yy}" was defining how to display my date?
You need to use the ISO format when using type="date"
[DataType(DataType.Date, ErrorMessage="Date only")]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime? YearBought { get; set; }
This will display the date in the browsers culture.
Note there is no need to add #type = "date". The EditorFor() method will add that because of the DataType attribute. Note also that type="date" is only supported in Chrome (FireFox and IE will just generate a normal textbox)
If you do want to display the format dd/MM/yyyy in a standard textbox then you can use
#Html.TextBoxFor(m => m.YearBought, "{0:dd/MM/yyyy}")
As it says in Stephen's answer, you have to make your formats match between the tags in your model to what is shown in the View, and it should be of the yyyy-MM-dd (ISO) format, regardless of how you actually want to display the date:
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
// .... your namespace .... your class....
[DisplayName("Year Bought")]
[DataType(DataType.Date, ErrorMessage="Date only")]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime? YearBought { get; set; }
And he's right, because we have [DataType(DataType.Date)], we don't need #type = date in our HtmlAttributes on the View.
Where my answer differs from his is how to actually apply the value from the Model to the control on the View. Since YearBought is a Nullable<DateTime>, we have to set it with its value a certain way, using .Value:
#Html.EditorFor(model => model.YearBought,
new { htmlAttributes = new { #class = "form-control datepicker",
#Value = Model.YearBought.Value.Date.ToString("yyyy-MM-dd") } })
Paying close attention to set the .ToString("yyyy-MM-dd"). It's not going to display in the box like that, though - at least for me - probably because my U.S. Regional settings on my computer take over and display it as MM/dd/yyyy regardless. This might confuse some, but it's better to just "do" and not worry about it.
If YearBought was just a straight DateTime instead of a DateTime?, it would be without the .Value:
#Html.EditorFor(model => model.YearBought,
new { htmlAttributes = new { #class = "form-control datepicker",
#Value = Model.YearBought != null ?
Model.YearBought.Value.Date.ToString("yyyy-MM-dd") : null } })
I would make your view model's YearBought property a String for the easiest manipulation. The server can format the date, it can do the parsing on postback, and you can still use the DataType.Date data annotation for jQuery validation. This also ensures that the display value will be exactly what you want prior to being submitted to the view.
Alternative to the HTML type attribute, you can use an EditorTemplate in MVC to put the markup, CSS, and JS needed to render a custom editor for a known C# datatype like DateTime.
Here is a walkthrough for creating a custom 'EditorTemplate' in MVC (although not for a Date data type, but concept is the same)

MVC fields not required but user being told they are

Title says it all. The model does not require the StartDate field but on POST I'm told it's required. It's one of several search fields, each one optional. Due to that, I'm not checking IsModel.Valid so the search works anyway, but the message shows up onscreen. If I set, in the view, #Html.ValidationSummary(true), that hides the message but the field still turns red.
Also, I do have a check to make sure EndDate is later than StartDate, so I need the messages for errors /requried fields to show up, just not when there ISN'T an error.
Here's the code:
MODEL (Partial)
[Display(Name = "Start Date")]
[DataType(DataType.Date)]
public DateTime StartDate { get; set; }
[Display(Name = "End Date")]
[GreaterThanOrEqualTo("StartDate", ErrorMessage = "End Date must be later than Start Date")]
[DataType(DataType.Date)]
public DateTime EndDate { get; set; }
VIEW (partial)
#using (Html.BeginForm()){
#Html.ValidationSummary(false)
<table>
<tr>
<td>
#Html.DisplayNameFor(m => m.StartDate)
#Html.TextBox("StartDate", "", new { #class = "datefield" })
etc.
SHARED/DISPLAY TEMPLATES
#model Nullable<DateTime>
#(Model != null ? string.Format("{0:M/d/yyyy}", Model) : string.Empty)
SHARED/EDITOR TEMPLATES
#model Nullable<DateTime>
#{
DateTime dt = DateTime.Now;
if (Model != null)
{
dt = (System.DateTime) Model;
}
#Html.TextBox("", String.Format("{0:M/d/yyyy}", dt.ToShortDateString()), new { #class = "datefield", type = "date" })
}
Some of these editors are to make a pop-up calendar work, btw.
I've tried turning on/off various things and one way or another, it still says the date fields are required. Any ideas? Thanks.
Easy way to remove validation is make int Null-able, I have already tested and it works fine. here is example:
public int? Id { get; set; }
As mentioned in the comments, value types like DateTime, int, decimal, etc. are treated as required if you don't make them nullable.
If the GreaterThanOrEqualTo attribute doesn't come from a library (such as MVC Foolproof Validation), you should let it return true if both Startdate en Enddate are null. Else you woud have to write your own custom validation attribute, but it's not that hard to do.

The data types time and datetime are incompatible in the greater than operator

I'm using the latest NuGet package of Fluent NHibernate (1.3.0.727), but I'm still experiencing an issue I thought was fixed in NHibernate 3.2 (the latest Fluent uses NHib 3.3). The database is SQL Server 2008 on Azure.
When I run a query that compares a .NET TimeSpan with a sql Time field, it throws the following exception:
The data types time and datetime are incompatible in the greater than operator.
Here's a sample query:
TimeSpan ts = new TimeSpan(1, 0, 0);
List<Message> messages = messageRepo.FilterBy(m => m.SendTime > ts).ToList();
Here's my Message class snippet:
public class Message
{
public virtual int Id { get; set; }
[DataType(DataType.Time)]
public virtual TimeSpan? SendTime { get; set; }}
}
And here's the relevant mapping details:
public class MessageMap : ClassMap<Message>
{
public MessageMap()
{
Table("Message");
LazyLoad();
Id(x => x.Id).GeneratedBy.Identity().Column("MessageID");
Map(x => x.SendTime).Column("SendTime").CustomType("TimeAsTimeSpan");
}
}
I've searched all over and tried everything I can find or think of. Maybe I'm just missing something obvious? Thanks for the help.
Turns out that Fluent's MsSql2008 configuration is setting the NHibernate database driver to one that doesn't handle the TimeAsTimeSpan properly. Manually setting the Driver to Sql2008ClientDriver fixes the problem. See line 4 below:
var rawConfig = Fluently.Configure()
.Database(
MsSqlConfiguration.MsSql2008.ConnectionString(x => x.FromConnectionStringWithKey("ConnectionString"))
.Driver("NHibernate.Driver.Sql2008ClientDriver")
)
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<SiteUserMap>())
.BuildConfiguration();
TimeSpan can hold several days, so it's compatible with DateTime, not Time. Time only contains the time of day. So I think you should not use the DataType attribute for your property - at least not DataType.Time.

How to filter Azure logs, or WCF Data Services filters for Dummies

I am looking at my Azure logs in the WADLogsTable and would like to filter the results, but I'm clueless as to how to do so. There is a textbox that says:
"Enter a WCF Data Services filter to limit the entities returned"
What is the syntax of a "WCF Data Services filter"? The following gives me an InvalidValueType error saying "The value specified is invalid.":
Timestamp gt '2011-04-20T00:00'
Am I even close? Is there a handy syntax reference somewhere?
This query should be in the format:
Timestamp gt datetime'2011-04-20T00:00:00'
Remembering to put that datetime in there is the important bit.
This trips me up every time, so I use the OData overview for reference.
Adding to knightffhor's response, you can certainly write a query which filters by Timstamp but this is not recommended approach as querying on "Timestamp" attribute will lead to full table scan. Instead query this table on PartitionKey attribute. I'm copying my response from other thread here (Can I capture Performance Counters for an Azure Web/Worker Role remotely...?):
"One of the key thing here is to understand how to effectively query this table (and other diagnostics table). One of the things we would want from the diagnostics table is to fetch the data for a certain period of time. Our natural instinct would be to query this table on Timestamp attribute. However that's a BAD DESIGN choice because you know in an Azure table the data is indexed on PartitionKey and RowKey. Querying on any other attribute will result in full table scan which will create a problem when your table contains a lot of data.The good thing about these logs table is that PartitionKey value in a way represents the date/time when the data point was collected. Basically PartitionKey is created by using higher order bits of DateTime.Ticks (in UTC). So if you were to fetch the data for a certain date/time range, first you would need to calculate the Ticks for your range (in UTC) and then prepend a "0" in front of it and use those values in your query.
If you're querying using REST API, you would use syntax like:
PartitionKey ge '0<from date/time ticks in UTC>' and PartitionKey le '0<to date/time in UTC>'."
I've written a blog post about how to write WCF queries against table storage which you may find useful: http://blog.cerebrata.com/specifying-filter-criteria-when-querying-azure-table-storage-using-rest-api/
Also if you're looking for a 3rd party tool for viewing and managing diagnostics data, may I suggest that you take a look at our product Azure Diagnostics Manager: /Products/AzureDiagnosticsManager. This tool is built specifically for surfacing and managing Windows Azure Diagnostics data.
The answer I accepted helped me immensely in directly querying the table through Visual Studio. Eventually, however, I needed a more robust solution. I used the tips I gained here to develop some classes in C# that let me use LINQ to query the tables. In case it is useful to others viewing this question, here is roughly how I now query my Azure logs.
Create a class that inherits from Microsoft.WindowsAzure.StorageClient.TableServiceEntity to represent all the data in the "WADLogsTable" table:
public class AzureDiagnosticEntry : TableServiceEntity
{
public long EventTickCount { get; set; }
public string DeploymentId { get; set; }
public string Role { get; set; }
public string RoleInstance { get; set; }
public int EventId { get; set; }
public int Level { get; set; }
public int Pid { get; set; }
public int Tid { get; set; }
public string Message { get; set; }
public DateTime EventDateTime
{
get
{
return new DateTime(EventTickCount, DateTimeKind.Utc);
}
}
}
Create a class that inherits from Microsoft.WindowsAzure.StorageClient.TableServiceContext and references the newly defined data object class:
public class AzureDiagnosticContext : TableServiceContext
{
public AzureDiagnosticContext(string baseAddress, StorageCredentials credentials)
: base(baseAddress, credentials)
{
this.ResolveType = s => typeof(AzureDiagnosticEntry);
}
public AzureDiagnosticContext(CloudStorageAccount storage)
: this(storage.TableEndpoint.ToString(), storage.Credentials) { }
// Helper method to get an IQueryable. Hard code "WADLogsTable" for this class
public IQueryable<AzureDiagnosticEntry> Logs
{
get
{
return CreateQuery<AzureDiagnosticEntry>("WADLogsTable");
}
}
}
I have a helper method that creates a CloudStorageAccount from configuration settings:
public CloudStorageAccount GetStorageAccount()
{
CloudStorageAccount.SetConfigurationSettingPublisher(
(name, setter) => setter(RoleEnvironment.GetConfigurationSettingValue(name)));
string configKey = "Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString";
return CloudStorageAccount.FromConfigurationSetting(configKey);
}
I create an AzureDiagnosticContext from the CloudStorageAccount and use that to query my logs:
public IEnumerable<AzureDiagnosticEntry> GetAzureLog(DateTime start, DateTime end)
{
CloudStorageAccount storage = GetStorageAccount();
AzureDiagnosticContext context = new AzureDiagnosticContext(storage);
string startTicks = "0" + start.Ticks;
string endTicks = "0" + end.Ticks;
IQueryable<AzureDiagnosticEntry> query = context.Logs.Where(
e => e.PartitionKey.CompareTo(startTicks) > 0 &&
e.PartitionKey.CompareTo(endTicks) < 0);
CloudTableQuery<AzureDiagnosticEntry> tableQuery = query.AsTableServiceQuery();
IEnumerable<AzureDiagnosticEntry> results = tableQuery.Execute();
return results;
}
This method takes advantage of the performance tip in Gaurav's answer to filter on PartitionKey rather than Timestamp.
If you wanted to filter the results by more than just date, you could filter the returned IEnumerable. But, you'd probably get better performance by filtering the IQueryable. You could add a filter parameter to your method and call it within the IQueryable.Where(). Eg,
public IEnumerable<AzureDiagnosticEntry> GetAzureLog(
DateTime start, DateTime end, Func<AzureDiagnosticEntry, bool> filter)
{
...
IQueryable<AzureDiagnosticEntry> query = context.Logs.Where(
e => e.PartitionKey.CompareTo(startTicks) > 0 &&
e.PartitionKey.CompareTo(endTicks) < 0 &&
filter(e));
...
}
In the end, I actually further abstracted most of these classes into base classes in order to reuse the functionality for querying other tables, such as the one storing the Windows Event Log.