Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Want to change the Validation attribute at runtime ASP.Net MVC

Want to change the Validation attribute at runtime ASP.Net MVC

Scheduled Pinned Locked Moved C#
helpasp-netcsharparchitecturequestion
15 Posts 3 Posters 19 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • I indian143

    Just checking, is it going to remove all the other Validations that I have put on other classes? Thanks, Abdul Aleem "There is already enough hatred in the world lets spread love, compassion and affection."

    Richard DeemingR Offline
    Richard DeemingR Offline
    Richard Deeming
    wrote on last edited by
    #6

    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

    "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

    I 2 Replies Last reply
    0
    • Richard DeemingR Richard Deeming

      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

      I Offline
      I Offline
      indian143
      wrote on last edited by
      #7

      OK Got it, and you are saying that there is just one risk in it that it can be overridden in the derived classes, understandable, thanks a lot Richard for giving me the information. Thank you very much have a wonderful weekend buddy. Thanks, Abdul Aleem "There is already enough hatred in the world lets spread love, compassion and affection."

      1 Reply Last reply
      0
      • Richard DeemingR Richard Deeming

        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

        I Offline
        I Offline
        indian143
        wrote on last edited by
        #8

        Hi Richard, One last thing, I have created the method in the following way:

        public class CustomModelValidatorProvider : System.Web.Mvc.DataAnnotationsModelValidatorProvider
        {
            protected override IEnumerable GetValidators(System.Web.Mvc.ModelMetadata metadata, ControllerContext context, IEnumerable 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(attributes);
                        var stringLength = newAttributes.OfType().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(Expression\> 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."

        Richard DeemingR 1 Reply Last reply
        0
        • I indian143

          Hi Richard, One last thing, I have created the method in the following way:

          public class CustomModelValidatorProvider : System.Web.Mvc.DataAnnotationsModelValidatorProvider
          {
              protected override IEnumerable GetValidators(System.Web.Mvc.ModelMetadata metadata, ControllerContext context, IEnumerable 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(attributes);
                          var stringLength = newAttributes.OfType().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(Expression\> 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."

          Richard DeemingR Offline
          Richard DeemingR Offline
          Richard Deeming
          wrote on last edited by
          #9

          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

          "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

          I 1 Reply Last reply
          0
          • Richard DeemingR Richard Deeming

            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

            I Offline
            I Offline
            indian143
            wrote on last edited by
            #10

            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."

            Richard DeemingR 1 Reply Last reply
            0
            • I indian143

              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."

              Richard DeemingR Offline
              Richard DeemingR Offline
              Richard Deeming
              wrote on last edited by
              #11

              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

              "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

              I 1 Reply Last reply
              0
              • Richard DeemingR Richard Deeming

                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

                I Offline
                I Offline
                indian143
                wrote on last edited by
                #12

                But still the attributes value in IEnumerable 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.")\]        
                    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 GetValidators(System.Web.Mvc.ModelMetadata metadata, ControllerContext context, IEnumerable 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(attributes);
                                var stringLength = newAttributes.OfType().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;
                
                Richard DeemingR 1 Reply Last reply
                0
                • I indian143

                  But still the attributes value in IEnumerable 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.")\]        
                      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 GetValidators(System.Web.Mvc.ModelMetadata metadata, ControllerContext context, IEnumerable 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(attributes);
                                  var stringLength = newAttributes.OfType().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;
                  
                  Richard DeemingR Offline
                  Richard DeemingR Offline
                  Richard Deeming
                  wrote on last edited by
                  #13

                  I don't know what to suggest. I've tested the code, and it works. :confused: 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

                  "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

                  I 1 Reply Last reply
                  0
                  • Richard DeemingR Richard Deeming

                    I don't know what to suggest. I've tested the code, and it works. :confused: 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

                    I Offline
                    I Offline
                    indian143
                    wrote on last edited by
                    #14

                    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."

                    Richard DeemingR 1 Reply Last reply
                    0
                    • I indian143

                      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."

                      Richard DeemingR Offline
                      Richard DeemingR Offline
                      Richard Deeming
                      wrote on last edited by
                      #15

                      You enable unobtrusive validation for the site in the web.config file:

                      <configuration>
                      <appSettings>
                      <add key="ClientValidationEnabled" value="true"/>
                      <add key="UnobtrusiveJavaScriptEnabled" value="true"/>

                      This should be included by default, but it depends on the template you started with. Creating a MVC 3 Application with Razor and Unobtrusive JavaScript ⇒ Enabling Client-Side Validation[^] I've created a minimal sample project in VS2017 which works as expected; you can download it from OneDrive[^].


                      "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

                      "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups