How to validate values in property? - c#

I have a question. How can i validate my price in property to be positive number, else to throw a new exception.
I have already tried it that way, but still doesn't work:
public decimal Price
{
get
{
{ return this.price; }
}
set
{
if (this.price < 0)
{
throw new ArgumentException("The price should be positive!");
}
else
{
this.price = value;
}
}
}

Now i see, you are checking against the backing field in the setter of the property which has the last value or the default value 0 if it was not yet initialized. Use the value instead:
private decimal price;
public decimal Price
{
get
{
{ return this.price; }
}
set
{
if (value < 0)
{
throw new ArgumentException("The price should be positive!");
}
else
{
this.price = value;
}
}
}

The part this.price is the current value. You need to check the value that is passed in the setter using the value variable.
public decimal Price
{
get
{
{ return this.price; }
}
set
{
if (value < 0)
{
throw new ArgumentException("The price should be positive!");
}
else
{
this.price = value;
}
}
}

Related

set max date value in database model

Hi all I am trying to set max date below
But Modified always returns a null value instant of return max value between ModifiedDate and OfferProductsModified.
public DateTime? Modified { get { return _FinalDate; } set { _FinalDate = value; } }
/// <summary>
/// this are not in offer view model
/// </summary>
[JsonIgnore] public DateTime? _FinalDate;
[JsonIgnore]
public DateTime? FinalDate
{
get
{
if (ModifiedDate < OfferProductsModified)
{
return OfferProductsModified;
}
else
{
return ModifiedDate;
}
}
set
{
if (ModifiedDate < OfferProductsModified)
{
_FinalDate = OfferProductsModified;
}
else
{
//DEFAULT Value.
_FinalDate = value;
}
}
}
How can I return the max value between ModifiedDate and OfferProductsModified ?
Note :- Both ModifiedDate and OfferProductsModified having values (confirm by debugging )

How can i make my business logic only execute once, so it alters the object only once

I have the following business logic:
public decimal Price
{
get {
if (OrderSize == Size.Small)
{
_price = decimal.Multiply(_price, (decimal)0.8);
}
else if (OrderSize == Size.Large)
{
_price = decimal.Multiply(_price, (decimal)1.2);
}
return _price;
}
set {
_price = value;
}
}
The price should be only changed once based on the chosen OrderSize. When this order is retrieved it calculates the price again which is obviously not what i want. What is the best way to make this only execute once?
You're not far off. Don't assign the _price variable again, just return the calculation.
public decimal Price
{
get
{
if (OrderSize == Size.Small)
{
return decimal.Multiply(_price, (decimal)0.8);
}
else if (OrderSize == Size.Large)
{
return decimal.Multiply(_price, (decimal)1.2);
}
else
{
return _price;
}
}
set
{
_price = value;
}
}

DataAnnotations attribute for float.NaN

I am using DataAnnotations for validation of my ViewModel (WPF) so I can control the enable state of some buttons if the user type in a something that is not a float and if the value is outside of a range.
[Range(0, float.MaxValue, ErrorMessage = "StepSize must be more than 0")]
public float StepSize
{
get { return model.StepSize; }
set
{
model.StepSize = value;
RaisePropertyChangedAndRevalidate(nameof(StepSize));
}
}
private void RaisePropertyChangedAndRevalidate(string propertyName)
{
RaisePropertyChanged(propertyName);
if (_fieldBindingErrors == 0)
{
RaisePropertyChanged(nameof(IsValid));
}
}
private int _fieldBindingErrors = 0;
public ICommand RegisterFieldBindingErrors
{
get
{
return new RelayCommand<ValidationErrorEventArgs>(e =>
{
if (e.Action == ValidationErrorEventAction.Added)
{
_fieldBindingErrors++;
}
else
{
_fieldBindingErrors--;
}
RaisePropertyChanged(nameof(IsValid));
});
}
}
public bool IsValid
{
get
{
bool valid = Validator.TryValidateObject(this,
new ValidationContext(this, null, null),
new List<System.ComponentModel.DataAnnotations.ValidationResult>())
&& _fieldBindingErrors == 0;
return valid;
}
}
Problem is, when I convert the the textbox.Text string to a float I have to set the value to something not valid (should work for general cases also when the Range attribute is not in use). So I set the value to float.NaN.
The problem is that NaN seems to be a valid float, and it even passes the Range validation above.
Is there an attribute I could use to validate that the value is not NaN?
Found a solution, I created a custom validation rule instead and applied it in the XAML.
class StepSizeValidationRule : ValidationRule
{
private int _min;
private int _max;
public StepSizeValidationRule()
{
}
public int Min
{
get { return _min; }
set { _min = value; }
}
public int Max
{
get { return _max; }
set { _max = value; }
}
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
float stepSize = 0;
try
{
if (!float.TryParse(value.ToString(), out stepSize))
{
return new ValidationResult(false, "Not a float");
}
}
catch (Exception e)
{
return new ValidationResult(false, "Not a float " + e.Message);
}
if (float.IsNaN(stepSize))
{
return new ValidationResult(false, "Not a float ");
}
if ((stepSize < Min) || (stepSize > Max))
{
return new ValidationResult(false,
"Please enter a stepSize in the range: " + Min + " - " + Max + ".");
}
else
{
return new ValidationResult(true, null);
}
}
}

Set private field within constructor using set validation from property

So.. How do i validate a private instance variable (field) with a property inside of a constructor?
I have this code that works, but I have a strong feeling this is not how it is supposed to be done:
class Account
{
private decimal acctBalance = 0;
public decimal AcctBalance
{
get
{
return acctBalance;
}
set
{
if (acctBalance >= 0)
acctBalance = value;
else
{
Console.WriteLine("Invalid balance, balance set to 0");
acctBalance = 0;
}
}
}
public Account(decimal balance)
{
acctBalance = balance;
AcctBalance = acctBalance;
}
}
I just want to make sure that this is the correct way to do it
thanks!
Your approach is mostly right, although there are a couple of issues. I fixed them and annotated the code with comments where I did.
class Account
{
private decimal acctBalance = 0;
public decimal AcctBalance
{
get
{
return acctBalance;
}
set
{
//modified to check value instead of acctBalance
if (value >= 0)
acctBalance = value;
else
{
Console.WriteLine("Invalid balance, balance set to 0");
acctBalance = 0;
}
}
}
public Account(decimal balance)
{
//redundant! Changing AcctBalance changes acctBalance
//acctBalance = balance;
AcctBalance = balance;
}
}

Set Binding Source DataSource to Generic IList<> Error

If I want to set the DataSource property on a BindingSource to an IList<>, do I need an explicit cast as the following error message says or am I doing something wrong?
interface IView
{
IList<OrderItems> BindingSource { get; set;}
}
public partial class Form1 : Form, IView
{
public Form1()
{
InitializeComponent();
}
private BindingSource _bindingSource;
public IList<OrderItems> BindingSource
{
get { return _bindingSource; }
set
{
_bindingSource.DataSource = value;
dataGridView1.DataSource = _bindingSource;
}
}
}
OrderItems.cs
using System;
using System.Collections.Generic;
namespace Ordering.Data
{
/// <summary>
/// Order object for NHibernate mapped table 'Order'.
/// </summary>
[Serializable]
public class OrderItems
{
#region Member Variables
protected int _id;
protected Customers _customers;
protected string _ordername;
protected DateTime _orderdate;
protected DateTime? _shipdate;
protected string _shipvia;
protected string _shipname;
protected string _shipaddress;
protected string _shipcity;
protected string _shipregion;
protected string _shippostalcode;
protected string _shipcountry;
protected string _status;
protected DateTime? _lastupdate;
protected IList<Products> _products;
#endregion
#region Constructors
public OrderItems() {}
public OrderItems(Customers customers, string ordername, DateTime orderdate, DateTime? shipdate, string shipvia, string shipname, string shipaddress, string shipcity, string shipregion, string shippostalcode, string shipcountry, string status, DateTime? lastupdate)
{
this._customers= customers;
this._ordername= ordername;
this._orderdate= orderdate;
this._shipdate= shipdate;
this._shipvia= shipvia;
this._shipname= shipname;
this._shipaddress= shipaddress;
this._shipcity= shipcity;
this._shipregion= shipregion;
this._shippostalcode= shippostalcode;
this._shipcountry= shipcountry;
this._status= status;
this._lastupdate= lastupdate;
}
public OrderItems(Customers customers, string ordername, DateTime orderdate)
{
this._customers= customers;
this._ordername= ordername;
this._orderdate= orderdate;
}
#endregion
#region Public Properties
public virtual int Id
{
get { return _id; }
set { _id = value; }
}
public virtual Customers Customers
{
get { return _customers; }
set {_customers= value; }
}
public virtual string OrderName
{
get { return _ordername; }
set {
if ( value != null && value.Length > 255)
throw new ArgumentOutOfRangeException("value", value.ToString(), "OrderName cannot contain more than 255 characters");
if (value != this._ordername){_ordername= value;}}
}
public virtual DateTime OrderDate
{
get { return _orderdate; }
set {if (value != this._orderdate){_orderdate= value;}}
}
public virtual DateTime? ShipDate
{
get { return _shipdate; }
set {if (value != this._shipdate){_shipdate= value;}}
}
public virtual string ShipVia
{
get { return _shipvia; }
set {
if ( value != null && value.Length > 255)
throw new ArgumentOutOfRangeException("value", value.ToString(), "ShipVia cannot contain more than 255 characters");
if (value != this._shipvia){_shipvia= value;}}
}
public virtual string ShipName
{
get { return _shipname; }
set {
if ( value != null && value.Length > 255)
throw new ArgumentOutOfRangeException("value", value.ToString(), "ShipName cannot contain more than 255 characters");
if (value != this._shipname){_shipname= value;}}
}
public virtual string ShipAddress
{
get { return _shipaddress; }
set {
if ( value != null && value.Length > 255)
throw new ArgumentOutOfRangeException("value", value.ToString(), "ShipAddress cannot contain more than 255 characters");
if (value != this._shipaddress){_shipaddress= value;}}
}
public virtual string ShipCity
{
get { return _shipcity; }
set {
if ( value != null && value.Length > 255)
throw new ArgumentOutOfRangeException("value", value.ToString(), "ShipCity cannot contain more than 255 characters");
if (value != this._shipcity){_shipcity= value;}}
}
public virtual string ShipRegion
{
get { return _shipregion; }
set {
if ( value != null && value.Length > 255)
throw new ArgumentOutOfRangeException("value", value.ToString(), "ShipRegion cannot contain more than 255 characters");
if (value != this._shipregion){_shipregion= value;}}
}
public virtual string ShipPostalcode
{
get { return _shippostalcode; }
set {
if ( value != null && value.Length > 255)
throw new ArgumentOutOfRangeException("value", value.ToString(), "ShipPostalcode cannot contain more than 255 characters");
if (value != this._shippostalcode){_shippostalcode= value;}}
}
public virtual string ShipCountry
{
get { return _shipcountry; }
set {
if ( value != null && value.Length > 255)
throw new ArgumentOutOfRangeException("value", value.ToString(), "ShipCountry cannot contain more than 255 characters");
if (value != this._shipcountry){_shipcountry= value;}}
}
public virtual string Status
{
get { return _status; }
set {
if ( value != null && value.Length > 255)
throw new ArgumentOutOfRangeException("value", value.ToString(), "Status cannot contain more than 255 characters");
if (value != this._status){_status= value;}}
}
public virtual DateTime? LastUpdate
{
get { return _lastupdate; }
set {if (value != this._lastupdate){_lastupdate= value;}}
}
public virtual IList<Products> Products
{
get { return _products; }
set {_products= value; }
}
#endregion
#region Equals And HashCode Overrides
/// <summary>
/// local implementation of Equals based on unique value members
/// </summary>
public override bool Equals( object obj )
{
if( this == obj ) return true;
if( ( obj == null ) || ( obj.GetType() != this.GetType() ) ) return false;
OrderItems castObj = (OrderItems)obj;
return ( castObj != null ) &&
this._id == castObj.Id;
}
/// <summary>
/// local implementation of GetHashCode based on unique value members
/// </summary>
public override int GetHashCode()
{
int hash = 57;
hash = 27 * hash * _id.GetHashCode();
return hash;
}
#endregion
}
}
Cannot implicitly convert type 'System.Windows.Forms.BindingSource' to 'System.Collections.Generic.IList'. An explicit conversion exists (are you missing a cast?)
return _bindingSource.DataSource as IList<OrderItems>;

Categories

Resources