|
No. It checks that the instance being validated is the specific model class; that the property being validated is the Code property; and it only replaces the StringLength validator on that property.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Hi Richard,
One last thing, I have created the method in the following way:
public class CustomModelValidatorProvider : System.Web.Mvc.DataAnnotationsModelValidatorProvider
{
protected override IEnumerable<System.Web.Mvc.ModelValidator> GetValidators(System.Web.Mvc.ModelMetadata metadata, ControllerContext context, IEnumerable<Attribute> attributes)
{
if (metadata.Model is LookupTable)
{
LookupTable model = metadata.Model as LookupTable;
if (metadata.PropertyName == GetPropertyName(() => model.CodeLength) && (model.CodeLength > 0))
{
var newAttributes = new List<Attribute>(attributes);
var stringLength = newAttributes.OfType<StringLengthAttribute>().FirstOrDefault();
if (stringLength != null)
{
newAttributes.Remove(stringLength);
if (model.CodeLength != 0)
{
newAttributes.Add(new StringLengthAttribute(model.CodeLength)
{
MinimumLength = model.CodeLength,
ErrorMessage = @"The field {{0}} length must be at least {model.CodeLength}."
});
}
attributes = newAttributes;
}
}
}
return base.GetValidators(metadata, context, attributes);
}
public string GetPropertyName<T>(Expression<Func<T>> propertyLambda)
{
var me = propertyLambda.Body as MemberExpression;
if (me == null)
{
throw new ArgumentException("You must pass a lambda of the form: '() => Class.Property' or '() => object.Property'");
}
return me.Member.Name;
}
}
can you please let me know how can I decorate or use it on my Model class, can you please give me that example, I am asking this question because this value is coming as null: metadata.PropertyName, so I am not able to compare with property name. So any help please?
thank you very very much buddy - as I said earlier have a Wonderful weekend with family and friends buddy.
Thanks,
Abdul Aleem
"There is already enough hatred in the world lets spread love, compassion and affection."
-- modified 3-Aug-18 19:53pm.
|
|
|
|
|
You register the provider in Global.asax.cs :
ModelValidatorProviders.Providers.Clear();
ModelValidatorProviders.Providers.Add( new CustomValidatorProvider() );
I'd expect to see the PropertyName set to null for the class-level validation, but I'd expect the method to be called again for each property on the class.
You're currently checking whether the validators are for the CodeLength property; you need to customise the validators for the Code property instead.
if (metadata.PropertyName == GetPropertyName(() => model.Code) && ...
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
ModelValidatorProviders.Providers.Clear();
ModelValidatorProviders.Providers.Add( new CustomValidatorProvider() );
I did this registration in the Global.asax.cs file, in the Application_Start() event.
And even if I changed the Condition to:
if (metadata.PropertyName == GetPropertyName(() => model.Code) && (model.CodeLength > 0))
Still I am getting the metadata.PropertyName null always, can you please suggest me what am I missing?
Just asking am I using any wrong namespace in references?, Because it was saying there is an ambiguous class names and those classes present in both the following namespaces using System.Web.ModelBinding; using System.Web.Mvc;
Am I using any wrong namespace or something like that kind of error, I am not understanding why is it giving metadata.PropertyName as null in all the cases?
Thanks,
Abdul Aleem
"There is already enough hatred in the world lets spread love, compassion and affection."
-- modified 6-Aug-18 13:01pm.
|
|
|
|
|
Sorry, I picked the wrong property to test against. Replace metadata.Model with metadata.Container :
if (metadata.Model is ServiceFunctionCategoryLKP model && metadata.PropertyName == nameof(model.Code) && model.CodeLength >= 0)
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
But still the attributes value in IEnumerable<attribute> attributes coming as null when I already have one Attribute on that class and when I try to expan the attributes collection object, it shows me "Enumeration yielded no results" in the end.
public class LookupTable
{
public int Id { get; set; }
[Required(ErrorMessage = "Code is required.")]<br />
public string Code { get; set; }
[Required(ErrorMessage = "Description is required.")]
public string Description { get; set; }
public int? ForeignKeyId { get; set; }
public string ForeignKeyValue { get; set; }
public DateTime? CreatedDate {get;set;}
public string CreatedBy {get;set;}
public int CodeLength { get; set; }
}
Do I need to add anymore Attributes to the Code Property?, what am I missing here my friend?
Even after I changed my function to have Container instead of Model, still I get null at metadata.PropertyName
Always metadata.PropertyName is coming as null irrespective of any changes I do at if (metadata.PropertyName == GetPropertyName(() => model.Code) && (model.CodeLength > 0))
in the below function and attributes is also coming as null.
protected override IEnumerable<System.Web.Mvc.ModelValidator> GetValidators(System.Web.Mvc.ModelMetadata metadata, ControllerContext context, IEnumerable<Attribute> attributes)
{
if (metadata.Model is LookupTable)
{
LookupTable model = metadata.Container as LookupTable;
if (metadata.PropertyName == GetPropertyName(() => model.Code) && (model.CodeLength > 0))
{
var newAttributes = new List<Attribute>(attributes);
var stringLength = newAttributes.OfType<StringLengthAttribute>().FirstOrDefault();
if (stringLength != null)
{
newAttributes.Remove(stringLength);
if (model.CodeLength != 0)
{
newAttributes.Add(new StringLengthAttribute(model.CodeLength)
{
MinimumLength = model.CodeLength,
ErrorMessage = @"The field {{0}} length must be at least {model.CodeLength}."
});
}
attributes = newAttributes;
}
}
}
return base.GetValidators(metadata, context, attributes);
}
Thanks,
Abdul Aleem
"There is already enough hatred in the world lets spread love, compassion and affection."
|
|
|
|
|
I don't know what to suggest. I've tested the code, and it works.
If you're not putting a static StringLength attribute on the property, you'll need to the if (model.CodeLength != 0) block outside of the if (stringLength != null) block:
if (stringLength != null)
{
newAttributes.Remove(stringLength);
}
if (model.CodeLength != 0)
{
newAttributes.Add(new StringLengthAttribute(model.CodeLength)
{
MinimumLength = model.CodeLength,
ErrorMessage = @"The field {{0}} length must be at least {model.CodeLength}."
});
}
attributes = newAttributes;
But if you're never seeing a value in metadata.PropertyName , then there's something else going on.
I assume you have actually enabled unobtrusive validation?
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
No I have not done this: unobtrusive validation, can you please let me know how to do it only on one particular class and property that I want.
Thanks,
Abdul Aleem
"There is already enough hatred in the world lets spread love, compassion and affection."
|
|
|
|
|
|
|
Assuming that frmPopup is a dialog, you should only show it when you need to use it to communicate something to the user. Use the Form.ShowDialog() method so it does not stay on screen.
|
|
|
|
|
Set the popup forms TopMost property to true and use the Form.Show method instead of Form.ShowDialog
That way, it'll "float" above Form1, and you will still be able to enter data in the Form1 Textbox.
Sent from my Amstrad PC 1640
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
|
You're welcome!
Sent from my Amstrad PC 1640
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
You can set the 'Owner property of the pop-up Form to be the first Form ... which I assume is the Main Form. That will guarantee that when you show the pop-up, it will remain "above" the Main Form.
To get further assistance, I suggest you describe what your goal is in more detail: what is the relation of data the user enters on the Main Form to the what is displayed on the pop-up Form ?
«... thank the gods that they have made you superior to those events which they have not placed within your own control, rendered you accountable for that only which is within you own control For what, then, have they made you responsible? For that which is alone in your own power—a right use of things as they appear.» Discourses of Epictetus Book I:12
|
|
|
|
|
As a beginner in CSharp, how do i differentiate between a class and a method. Thanks
|
|
|
|
|
A class contains constructors, members, properties, and methods.
For example:
class Complex
{
private double real;
private double imag;
public Complex()
{
real = 0.0;
imag = 0.0;
}
public Complex(double x)
{
real = x;
imag = 0.0;
}
public Complex(double x, double y)
{
real = x;
imag = y;
}
public double Real { get; set; }
public double norm()
{
return real * real + imag * imag;
}
};
Freedom is the freedom to say that two plus two make four. If that is granted, all else follows.
-- 6079 Smith W.
|
|
|
|
|
You might want to start with fundamentals. Firts: Google is your friend, i.e. learn to do some independent research.
There's an in-depth Object Oriented Design primer intended just for folks like you at:
Introduction to Object Oriented Programming Concepts (OOP) and More
"Never attribute to malice that which can be explained by stupidity."
- Hanlon's Razor
|
|
|
|
|
Simple: a class starts with <public|private|protected|internal|protected internal> class followed by the class name.
A method starts with <public|private|protected|internal|protected internal> followed by the return type (or void ) then the method name and a pair of brackets containing any parameters.
Plus, a method can only be defined inside a class, and not the other way round.
Sent from my Amstrad PC 1640
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
|
A Class is a something; a Method does something.
A Class is a blue-print for creating a structure: the structures created from a Class definition are instances of the Class.
Classes can contain other Class definitions, Methods, Fields.
A Method can accept parameters when it is invoked.
That's just the start ...
«... thank the gods that they have made you superior to those events which they have not placed within your own control, rendered you accountable for that only which is within you own control For what, then, have they made you responsible? For that which is alone in your own power—a right use of things as they appear.» Discourses of Epictetus Book I:12
|
|
|
|
|
I many projects I have had a similar type of problem that I have not found a good general solution to.
Assuming that I have many different lines on a Canvas that are all organized in the flat storage Canvas.Children but I want these lines to be grouped by the object they are trying to draw. Like all lines in a Ball is grouped together and can be removed by a single checkbox click and at a higher level, I can remove the entire football field etc. The only way I found out to do this was through looping through everything every time I was adding, changing and removing it, basically involving recursion.
Does anyone have some good ideas or practices for solving this?
|
|
|
|
|
I would normally base this type of thing on working with an underlying model using MVVM. Basically, I would have something like a Shape model which contained an ObservableCollection of Lines. All you would need to do then is remove the Shape and clear the Lines collection and the related items would be removed from the screen. Without seeing your code, I can't say whether or not this is feasible with the architecture you currently have in place.
This space for rent
|
|
|
|
|
At the lowest level, I have a class that inherits FrameWorkElement and use drawing visuals to actually render the objects. This is because I don't only have lines but Bezier curves etc. The problem was that I wanted to group things at an arbitrary deep levels
MyDrawingFile
-Road
--Car
---Wheels
----Rims
----Tires
---Lights
-----StopLights
-----HeadLights
---Windows
-House
So if I wanted to disable everything but the House I basically had to traverse all the objects and its children under the ObservableCollection<road> and then manually remove the objects in the Canvas.
I basically set up something like:
public abstract class HierarchyBase : INotifyPropertyChanged
{
private ObservableCollection<HierarchyBase> children = new ObservableCollection<HierarchyBase>();
public ObservableCollection<HierarchyBase> Children
{
get { return children; }
set { children = value; }
}
public string Name { get; set; }
private bool pIsEnabled;
public bool IsEnabled
{
get { return pIsEnabled; }
set { pIsEnabled = value;
StateUpdated();
OnPropertyChanged();
}
}
private bool pIsVisible;
public bool IsVisible
{
get { return pIsVisible; }
set {
pIsVisible = value;
StateUpdated();
OnPropertyChanged();
}
}
private void StateUpdated()
{
if (this is IDrawing)
{
((IDrawing)this).Redraw(IsVisible);
}
foreach (HierarchyBase child in Children)
{
if (!this.IsEnabled || !this.IsVisible)
{
child.IsVisible = false;
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName]string caller = "")
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(caller));
StateUpdated();
}
}
}
But then binding was a big issue, so I thought is somewhat clumsy.
|
|
|
|
|
List<object> Ball = ...
...
Canvas.Children.Add( line );
Ball.Add( line );
...
Ball.ForEach( l => Canvas.Children.Remove( l as UIElement ) );
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|