Epplus: How to make "LoadFromCollection" use [DisplayFormat()] attributes in model - c#

I have an ActionResult (in an MVC 5 website) that successfully uses Epplus to export a data set to an Excel document.
In the ActionResult code block, I use code like this to format the column as a short date. WIthout this code, the date column appears as int values.
// format date columns as date
worksheet.Column(6).Style.Numberformat.Format =
DateTimeFormatInfo.CurrentInfo.ShortDatePattern;
However, in the Model, I already have this defined as an attribute. It works great on the View page, but doesn't format the column as a short date -- hence, the code shown above.
[Column(TypeName = "date")]
[DisplayName("Exit Date")]
**[DisplayFormat(DataFormatString = "{0:d}")]**
public DateTime ExitDate { get; set; }
To provide further context, I load my worksheet from a collection.
worksheet.Cells["A5"].LoadFromCollection(Collection: exportQuery, PrintHeaders: true);
Is there a way that I can extend LoadFromCollection so that that the worksheet not only loads the Collection content, but also the formatting attributes that exist in the model? The "DisplayName" attributes are collected, so is there a way to also collect "DisplayFormat" attributes without having to write separate code?

EPPlus unfortunately didn't implement support for DisplayFormat.
The library is open source, so you can find the full implementation of LoadFromCollection and its overloads on codeplex
To answer you question: I'm afraid you will have to write separate code for this.

Related

Create a custom method that reads Excel columns as is

I have a property set below for which I need to ingest data from an Excel report with a column name of ENTRY NUMBER. Looking for a custom method that can take in a string so I can assign the spreadsheet name to property below.
public string EntryNumber { get; set; }
I tried looking into libraries similar to Xml.Seralization in that it uses XmlAttribute(nameof()) to differ the property name in the class to what is on the actual xml file and then apply it to an xlsx context.

EF: Is it OK to use default value for the created date property?

I want to set the CreatedDate column to the current datetime whenever a new row is inserted, so I made it like this:
public DateTime CreateDate { get; set; } = DateTime.Now;
I tested it and it works just fine, Is this a practical approach? I saw many articles achieve the same with so much code and using fluent API, no one mentioned this simple method?
That depends on what you want to accomplish.
I saw many articles achieve the same with so much code and using fluent API,
Most of those articles will be about adding default values at the database level. You're not doing that. If you insert a row into your table using plain SQL, and don't specify a value for CreatedDate, you'll get an error.
With what you're doing, CreatedDate always needs to be specified in SQL when inserting. But Entity Framework will always specify it in the SQL when inserting, and completely ignore any default value set at the database level.
So if that's what you want -- the default value only gets applied when creating objects through C# -- then what you're doing is totally fine. It may also be written as setting the value from inside the class's constructor.
#Alex Kozlowski raises a good comment though, which is that DateTime.Now may not be the value you expect to be inserted. It depends on which system is running the code. The time zone may be different from your server's, or the clock may be out of sync.
Yes. This feature was added in c# version 6 onwards. This will work from c#-6 onwards only. And that's why you won't find it in many articles.

Define dateTime format in xsd

At my work we load excel files and save them in the database.
This is basically the flow:
We import data into a DataSet from an Excel file, where each sheet is loaded into its own DataTable inside the DataSet. After populating the DataDet, i want to validate the data inside the DataSet, let's say the first DataTable. I get xml from the DataTable by using WriteXml() method of the DataTable class and load this xml into an XDocument. I then use the Validate() method of the XDocument class with a predefined xsd, which is loaded into a XmlSchemaSet object.
The problem is that the data in the excel is stored in a format that is different from the format of dateTime in xsd.
We get Excel files with datetime columns formatted like thie: '12/01/2015 12:44:45', whereas the dateTime format in xsd should be like this: '2015-01-12T12:44:45'
Is it possible to define custom dateTime format in an xsd file?
For example, instead of '2015-01-12T12:44:45', I would like it to be '12/01/2015 12:44:45', so my xml element would look like this:
<createDate>12/01/2015 12:44:45>/createDate>
In addition, i wouldn't mind if the time part would be ignored altogether.
In addition, another custom xsd format i need is like this: 378,216.00
Is it possible to define it in my xsd file?
Here is this code where we do the validation of the xml, retrieved from the datatable
public string[] ValidateExcelFromXsdFile(string schemaUri)
{
_validationErrors.Clear();
var schemas = new XmlSchemaSet();
schemas.Add("", schemaUri);
var doc = XDocument.Parse(GetXml(_dataSetFromExcel.Tables[0]));
doc.Validate(schemas, (sender, args) => _validationErrors.Add(args.Message));
return _validationErrors.ToArray();
}
You can define a pattern for strings in the format 'dd/mm/yyyy hh:mm:ss' using a regular expression, but the resulting value won't be an xs:dateTime, and checking for full validity (leap years etc) is a bit of a nightmare (it can be done, but leads to a regular expression that's about a mile long).
A better solution here might the transform-then-validate pattern, where you preprocess the input document (into standard XSD format) before validating it. You can even do some of the validation during the preprocessing phase if you choose.
The Saxon schema processor has an preprocess facet which allows you to declare some rearrangement of a value prior to schema processing, which is exactly what you need here (for both your use cases), but unfortunately it's not standard.
Check this site - there you have DateTime data type http://www.w3schools.com/schema/schema_dtypes_date.asp
Also Date and Time Data Types paragraph will allows you to adjust the rule to your needs.

How to save time only without the date using ASP.NET MVC 5 Data Annotation "DataType.Time?

My Model Class looks like this:
[DataType(DataType.Time)]
public DateTime Time {get; set;}
When I run it, I have a cool an HTML 5 Input Type in Time. When I save the data, the value in my database looks like this:
7/11/2014 1:00AM
It automatically saves the current date. I just wanna have the time saved. I'm trying to create a reservation system.
[DataType(DataType.Time)]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:HH:mm}")]
public DateTime Hour { get; set; }
In that case you need to store that as a string. You cannot separate Time from Date using BCL (Base Class Library) of .Net. They cannot exist as independent entities.
However youcan have a workaround to save Time in a TimeSpan object using this Representing Time (not date and time) in C#
Similar question gives a series of answers you might like, How do I represent a time only value in .NET? but the
However the overriding question is what type you should set the time to in your db, and this question Best way to store time (hh:mm) in a database gives more
The following will give you a string representation from your DateTime, but read the other questions and answers, and you might want to save in a format other than string to make it easier to evaluate queries...
DateTime.Now.ToString("t");
[DisplayFormat(DataFormatString = "{0:t}")]
public DateTime Time {get; set;}
will display only the time
For reference Follow :
MSDN Reference
Just change the data type as as string in database then you can save your time.

Storing the RecordString with the FileHelper Class

We are using FileHelpers 2.0 in our project. I have my record defined and have the data being imported correctly. After getting my array of generic objects:
var engine = new FileHelperEngine<UserRecord>();
engine.ErrorManager.ErrorMode = ErrorMode.SaveAndContinue;
UserRecord[] importedUsers = engine.ReadFile(_filepath);
After getting the records that errored due to formatting issues, I am iterating through the importedUsers array and doing validation to see if the information being imported is valid.
If the data is not valid, I want to be able to log the entire string from the original record from my file.
Is there a way to store the entire "RecordString" in the UserRecord class when the FileHelperEngine reads each of the records?
We do that often at work handling the BeforeRead event and storing it in a field mOriginalString that is marked this way:
[FieldNotInFile]
public string mOriginalString;
You must use the last version of the library from here:
http://teamcity.codebetter.com/repository/download/bt65/20313:id/FileHelpers_2.9.9_ReleaseBuild.zip
Cheers

Categories