Object reference not set to an instance of an object

Dec 2, 2011 at 4:21 PM

Im trying to get validation working, but I get this error for these attributes  (I wont even start trying to get clientside validation working)

[GreaterThan("Policy.StartDate", ErrorMessage = "The cancellation date can't be less than the policy start date")]

[LessThan("MaxCancellationDate", ErrorMessage = "The cancellation date can't be more than 30 days in the future")]

 

the same method using non foolproof version works ok

 

what am i doing wrong ?

Object reference not set to an instance of an object

[NullReferenceException: Object reference not set to an instance of an object.]
   Foolproof.ContingentValidationAttribute.GetDependentPropertyValue(Object container) +74
   Foolproof.ContingentValidationAttribute.IsValid(Object value, Object container) +49
   Foolproof.<Validate>d__1.MoveNext() +125
   System.Web.Mvc.<Validate>d__5.MoveNext() +315
   System.Web.Mvc.DefaultModelBinder.OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext) +136
   System.Web.Mvc.DefaultModelBinder.BindComplexElementalModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Object model) +60
   System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +1048
   System.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +280
   System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) +257
   System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor) +109
   System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +314
   System.Web.Mvc.Controller.ExecuteCore() +105
   System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +39
   System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +7
   System.Web.Mvc.<>c__DisplayClass8.<BeginProcessRequest>b__4() +34
   System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +21
   System.Web.Mvc.Async.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _) +12
   System.Web.Mvc.Async.WrappedAsyncResult`1.End() +59
   System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +44
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +7
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8681230
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

Dec 2, 2011 at 4:33 PM

I'm pretty sure the problem is going to be with "Policy.StartDate". Foolproof won't reflect into your encapsulated Policy object - although that would be a pretty cool feature. 

Dec 2, 2011 at 4:37 PM

So how do i tell it what to compare against ?  I cant hard code a value because it will change for each client.  I have a standard .net  attribute that inherits from validationAttribute and that works perfectly.

 I only started to look into the foolproof stuff because i couldnt get clientside validation working with custom validators, i thought would be easier

Dec 2, 2011 at 4:46 PM

You are doing it right, but Foolproof only looks for the value of a dependent property on the same object. You are trying to compare to a value on about encapsulated object. If the StartDate was on the same object and your annotation looked like [GreaterThan("StartDate")], it would likely work just fine.

Consider moving the StartDate property to the parent object or create a custom validator.

Dec 2, 2011 at 4:54 PM

ah, ok.  I thought this would be able to do that easily, its just standard object notation.  I created my own and it works ok, but I cant get clientside validation to work

 

public sealed class DateGreaterThanAttribute : ValidationAttribute
    {
        private DateTime _date;

        public DateGreaterThanAttribute(string date)
            : base()
        {
            _date = CustomValidators.ParseTimeInterval(date);
         
        }

        public override bool IsValid(object value)
        {
            if (value == null)
            {
                return true;
            }
            DateTime dateValue = (DateTime)value;
            return (dateValue > _date);
        }
    }

Dec 2, 2011 at 5:00 PM
Well, it might be easy. The great thing about open source is you can download the code, add the feature, and submit the patch!

On Fri, Dec 2, 2011 at 10:54 AM, misuk11 <notifications@codeplex.com> wrote:

From: misuk11

ah, ok. I thought this would be able to do that easily, its just standard object notation. I created my own and it works ok, but I cant get clientside validation to work

public sealed class DateGreaterThanAttribute : ValidationAttribute
    {
        private DateTime _date;

        public DateGreaterThanAttribute(string date)
            : base()
        {
            _date = CustomValidators.ParseTimeInterval(date);
         
        }

        public override bool IsValid(object value)
        {
            if (value == null)
            {
                return true;
            }
            DateTime dateValue = (DateTime)value;
            return (dateValue > _date);
        }
    }

Read the full discussion online.

To add a post to this discussion, reply to this email (foolproof@discussions.codeplex.com)

To start a new discussion for this project, email foolproof@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com




--
Nick Riggs
Dec 2, 2011 at 5:03 PM

I created a property in the main object

 

public DateTime? PolicyStartDate { get; set; }

 

and set its value in the constructor.

 

I then changed the validator to

 

[GreaterThan("PolicyStartDate", ErrorMessage = "The cancellation date can't be less than the policy start date")]

 

and got exactly the same error.  I even hard coded a date string and its the same

 

Dec 2, 2011 at 5:07 PM

What version of MVC?

Dec 6, 2011 at 12:04 PM

Ive managed to get a bit further with this problem now, Im able to check an entered value against a dynamic value at runtime using reflection.  Serverside works ok, but the clientside code doesnt work.

 

Ive followed the example here

http://www.nickriggs.com/posts/client-side-model-aware-validation/

heres my attribute

public class DateIsGreaterThanAttribute : ModelAwareValidationAttribute
    {
        //this is needed to register this attribute with foolproof's validator adapter
        static DateIsGreaterThanAttribute() { Register.Attribute(typeof(DateIsGreaterThanAttribute)); }

        private string _propertyName;
        //propertyName is the name of the property to compare against in the class containing the attribute
        //eg  policyStartDate
        public DateIsGreaterThanAttribute(string propertyName) : base()
        {
            _propertyName = propertyName;
        }
        

        public override bool IsValid(object value, object container)
        {
            //use reflection to get at the underlying value of the specified class property
            PropertyInfo propertyInfo = container.GetType().GetProperty(_propertyName);
            object inspectionValue = propertyInfo.GetValue(container, null);
            if (inspectionValue == null || value == null)
            {
                return true;
            }
            DateTime dateLower = (DateTime)inspectionValue;//the date we compare against
            DateTime dateHigher = (DateTime)value;//the date entered
            return (dateHigher > dateLower);
        }
    }

this works perfectly serverside, but this code wont work clientside

Sys.Mvc.ValidatorRegistry.validators["DateIsGreaterThan"] = function (rule) 
    {
        return function (value, context) 
        {
            var dependentProperty = foolproof.getId(context.fieldContext.elements[0], "PolicyStartDate");
            var dependentValue = document.getElementById(dependentProperty).value;
            if (value == "Software Developers") 
            {
                if (dependentValue == "IT Department")
                    return true;
                else
                    return context.validation.fieldErrorMessage;
            }
            return true;
        };
    };

Ive left some of the existing code in just for now while im testing it, Ill replace that once i get some sort of basic functionality.  This line is never reached

 

var dependentProperty = foolproof.getId(context.fieldContext.elements[0], "PolicyStartDate");

the example states

“RoleValidInDepartmentAttribute” was the name of our attribute, so when we are registering our client validator with the ValidatorRegistry, just drop the “Attribute” part

so I assumed this line would work
Sys.Mvc.ValidatorRegistry.validators["DateIsGreaterThan"] = function (rule) 

Do I have to register this in global.asax myself ?  I thought this line took care of that

static DateIsGreaterThanAttribute() { Register.Attribute(typeof(DateIsGreaterThanAttribute)); }

any idea what im doing wrong ?
Dec 6, 2011 at 2:42 PM

A change from MVC 2 to MVC 3 required validator names to be lower-case. Try this instead:

Sys.Mvc.ValidatorRegistry.validators["dateisgreaterthan"] = function (rule) 

I'm assuming you are using MVC 3. 

Dec 6, 2011 at 2:55 PM

its mvc2

Dec 6, 2011 at 3:05 PM

we are on mvc2  .net 3.5.  I made the change to lower case and it works, not sure whats going on there

Dec 6, 2011 at 3:07 PM
Maybe it was MVC 1 to 2. I lose track. :) Glad it's working for you.

On Tue, Dec 6, 2011 at 9:05 AM, misuk11 <notifications@codeplex.com> wrote:

From: misuk11

we are on mvc2 .net 3.5. I made the change to lower case and it works, not sure whats going on there

Read the full discussion online.

To add a post to this discussion, reply to this email (foolproof@discussions.codeplex.com)

To start a new discussion for this project, email foolproof@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com




--
Nick Riggs