In my code I have the following:
viewModel.Note.Modified = DateTime.Now;
viewModel.Note.ModifiedBy = User.Identity.Name;
and in my view:
[DisplayName("Modified")]
public DateTime Modified { get; set; }
[DisplayName("Modified By")]
public string ModifiedBy { get; set; }
Could I just have my code change ModifiedBy and then have some code that runs in the ViewModel that changes the date of Modified when the Modified by is changed?
The way to do this will depend on how much logic you want in your view. If you don't mind some logic there, you can do something like this:
[DisplayName("Modified")]
public DateTime Modified { get; set; }
private string m_ModifiedBy
[DisplayName("Modified By")]
public string ModifiedBy {
get { return m_ModifiedBy; }
set{ m_ModifiedBy = value; Modified = DateTime.Now; }
}
If you want the logic in your ViewModel, you can do something like this: ( assuming that viewModel is a class variable )
public void SetModifiedBy(string modifiedBy) {
viewModel.Note.Modified = DateTime.Now;
viewModel.Note.ModifiedBy = modifiedBy;
}
Then you would just call SetModifiedBy(User.Identity.Name) and both values would be updated.
If viewModel.Note is a reference to a NoteViewModel instance, then you can use the following:
public class NoteViewModel{
private DateTime? m_Modified;
private string m_ModifiedBy;
// note that you do not need the DisplayNameAttribute, because the default
// display name is the property name
public DateTime Modified {
get { return m_Modified ?? DateTime.Now; }
}
[DisplayName("Modified By")]
public string ModifiedBy {
get { return m_ModifiedBy ?? string.Empty; }
set {
if(value!=null) {
m_ModifiedBy = value;
m_Modified = DateTime.Now;
}
}
}
}
Then in your "code" (I'm guessing you meant the controller?), you can just do:
viewModel.Note.ModifiedBy = User.Identity.Name;
and you will have the intended result.
Side Note: Depending on the audience of your application, you may want to consider using DateTime.UtcNow for localization purposes. DateTime.Now will return the current DateTime on the server, which is dependent on the server's location. If you are displaying this data to the user, it is likely that you will want to either (a) specify the time zone, or (b) localize the time to the time zone of the client machine
Related
I have a C# Model that contains a birthday. The birthday field takes the birthday from a separate API in the DateTime format. I've been trying to change this to a String instead, and I want to do it with Getters/Setters, if possible.
I get an error for ToString() when trying to do this. Error states "cannot convert from "string" to "System.IFormatProvider". I've tried lots of other variants of this and I just can not get something to work. I want to be able to achieve it via the Getters/Setters.
public class PersonLookUpModel
{
public DateTime? DateOfBirth { get; set; }
public string? _dateOfBirthString;
public string? DateOfBirthString {
get => DateOfBirth;
set => _dateOfBirthString = value.ToString("MMMM dd"); }
}
Here you go.
public class PersonLookupModel
{
public DateTime DateOfBirth{get;set;}
public string DOBString => DateOfBirth.ToString("MMM dd");
}
This is what ended up working:
public DateTime? DateOfBirth { get; set; }
public string _dobString;
public string DOBString {
get => _dobString = DateOfBirth?.ToString("MMMM dd");
set => _dobString = value; }
I have the following ViewModel in my app and there is two BirthDate property (with / without time). When using set { } without body I encounter "Not using the value means that the accessor ignores the caller's intent which could cause unexpected results at runtime.". Then I added a private property and update set as set { birthDateWithTime = value; }. However, this time birthDateWithTime private property not sees to be used. Is there any mistake regarding to implementation below? I want to use both property separately and do not want to convert in JavaScript or code.
public class DemoViewModel
{
public int Id { get; set; }
public DateTime BirthDate { get; set; }
private string birthDateWithTime;
public string BirthDateWithTime {
get { return BirthDate.ToString("dd/MM/yyyy - HH:mm"); }
set { birthDateWithTime = value; }
}
}
#Gabriel Llorico answer is correct. or maybe you can try another one.
private DateTime _birthDate;
public DateTime BirthDate{
get{
return _birthDate;
}
set{
this._birthDate = value;
this.BirthDateWithTime = this._birthDate.ToString("dd/MM/yyyy - HH:mm");
}
}
public string BirthDateWithTime{get;set;}
try this if it is solely dependent on BirthDate
public string BirthDateWithTime
{
get
{
return BirthDate.ToString("dd/MM/yyyy - HH:mm");
}
}
Or just use a body-property style.
public string BirthDateWithTime => BirthDate.ToString("dd/MM/yyyy - HH:mm");
If you need to set BirthDateWithTime, just set in the BirthDate property, so both are updated.
Ok, so maybe I'm just tired or something but I can't seem to figure out why this keeps happening.
The code below is called every day for a data point in a database I have.
When I print to the console for debugging, it simply prints out as:
NamespaceName.SharePrices
Not sure what is going on.
public void OnData(TradeBars data)
{
decimal price = data["IBM"].Price;
DateTime today = data["IBM"].Time;
//--------------Below works fine.
if (today.Date >= nextTradeDate.Date)
{
MarketOnOpenOrder("IBM", 50);
Debug("Purchased Stock");
nextTradeDate = today.AddDays(1);
MarketOnOpenOrder("IBM", -25);
}
var derpList = new SharePrices { theDate = today, sharePrice = price };
List<SharePrices> newList = new List<SharePrices>();
newList.Add(derpList);
newList.ForEach(Console.WriteLine);
}
}
public class SharePrices
{
public DateTime theDate { get; set; }
public decimal sharePrice { get; set; }
}
Please excuse my naming conventions. This is just a wireframe for a personal project.
//----------Edit
Thanks for the help guys. I guess what I wasn't understanding is why it was working in my TestClass I wrote just playing with fake data, and when the real implementation came it didn't work:
public static void FindWindowDays()
{
DateTime currentDate = DateTime.Now;
var dates = new List<DateTime>();
for (var dt = currentDate.AddDays(-windowDays); dt <= currentDate; dt = dt.AddDays(1))
{
dates.Add(dt);
}
var ascending = dates.OrderByDescending(i => i);
foreach (var datesyo in ascending)
{
Console.WriteLine(datesyo);
}
}
This seemed to work fine printing the DateTime to console without converting to string. But when I added the second element, it stopped working. That's where I got confuddled.
C# doesn't know anything about the SharePrices other than the class name. If you want it to display something specific, you will need to override the ToString() method like so:
public override string ToString()
{
return "SharePrice: " + theDate.ToString() + ": " + sharePrice.ToString();
}
Of course, you can format it however you like, that is the beauty of it. If you only care about the price and not the date, only return the sharePrice.
You should override ToString() for your class in format as you want, for example like this:
public class SharePrices
{
public DateTime theDate { get; set; }
public decimal sharePrice { get; set; }
public override string ToString()
{
return String.Format("The Date: {0}; Share Price: {1};", theDate, sharePrice);
}
}
By default, without overriding, ToString() returns a string that represents the current object. So that's why you get what you described.
When you call Console.WriteLine on a class, it will call the ToString() method on that class automatically.
If you want to print the details out, you will over need to override ToString() in your class, or call Console.WriteLine with each property you want to print out.
this will work without having to use .ToString()
public class SharePrices
{
public DateTime theDate { get; set; }
public decimal sharePrice { get; set; }
}
SharePrices sp = new SharePrices() { theDate = DateTime.Now, sharePrice = 10 };
var newList2 = new List<SharePrices>();
newList2.Add(sp);
newList2.ForEach(itemX => Console.WriteLine("Date: {0} Sharprice: {1}",sp.theDate, sp.sharePrice));
I have a field in my model class that's coded as follows:
public string CreatedBy
{
get { return _CreatedBy; }
set { _CreatedBy = value; Created = DateTime.Now; }
}
public DateTime? Created { get; set; }
When the CreatedBy field is populated then it fills out the Created date automatically. The problem for me is that if I again set the CreatedBy field (yes it can happen) then the date gets updated with the current date again.
Is there a way that I can make it so the CreatedBy and the Created fields can be populated just once?
Can't you check, within the set, whether there is already a value and simply not set the new value?
Use a backing field and check whether the value has been set already - if so, leave it unchanged:
private DateTime? created;
public DateTime? Created
{
get { return created; }
set { if (created == null) created = value; }
}
Make use of constructor and iniailize the property to defult value you want
public classConstructor()
{
propertyName = defaultValue;
}
Here's a quick way: use the ?? operator. If Created is null, it will go to DateTime.Now.
public string CreatedBy
{
get { return _CreatedBy; }
set { _CreatedBy = value; Created = Created ?? DateTime.Now; }
}
public DateTime? Created { get; set; }
In that case it would probably be best to include CreatedBy in the constructor. This would imply "create-time" semantics:
public string CreatedBy
{
get;
private set;
}
public DateTime? Created
{
get;
private set;
}
public Model(..., string createdBy)
{
this.CreatedBy = createdBy;
this.Created = DateTime.Now;
}
// another option, if you don't like the ctor route
public void AssignCreator(string createdBy)
{
if (this.Created.HasValue) throw new InvalidOperationException();
this.CreatedBy = createdBy;
this.Created = DateTime.Now;
}
Your other option would be to throw an InvalidOperationException in the property setter if Created is non-null.
When creating a class what is the syntax to define a public property for that class as a DateTime type rather than string?
If you want a date object, with class-controlled formatting, you need two properties:
public DateTime DateField { get; set; }
// a read only string
public String DateFieldString {
get { return DateField.ToString(/* your format */); }
}
EDIT
ASP.NET: BoundField's DataFormatString property looks to be what you want.
<asp:BoundField
DataField="EventDate"
HeaderText="Event Date"
DataFormatString="{0:MM/dd/yyyy}"/>
Easy as (pumpkin) pie. Happy Thanksgiving!
public class MyClass {
public DateTime MyDate { get; set; }
public string MyFormattedDate { get { return MyDate.ToString(myFormat); } }
}
Something like
public class TestClas
{
DateTime dtDate;
public DateTime DtDate
{
get
{
return dtDate;
}
set
{
dtDate = value;
}
}
}
and to get and set the field you can use
TestClas objDate = new TestClas();
// set date
objDate.DtDate = DateTime.Now;
// get date
DateTime dtCurDate = objDate.DtDate;
Edit
It would be better not to implement the formatting inside the property. Make the formatting inside the gridview. Otherwise if you need another formatting then you would have to create another property.
using System;
public class Customer {
private DateTime createDate;
public DateTime CreateDate {
get { return createDate; }
set { createDate = value; }
}
}