7

In a C# controller, I have a function defined with an optional parameter which is set to default to null (see code example below). The first time the page loads, the function is called and the filter is passed in as an initialized object, despite the default value being null. I would like it to be null the first time the page loads. Is there a way to do this?

public ActionResult MyControllerFunction(CustomFilterModel filter = null)
{
    if (filter == null)
         doSomething(); // We never make it inside this "if" statement.

    // Do other things...
}

This action is resolved by the following route definition:

routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "Project", action = "Index", id = UrlParameter.Optional } // Parameter defaults
        );
10
  • Are you calling it with an argument? You probably aren't call it in a way that allows the default parameter. Commented Jul 23, 2014 at 19:46
  • @BradleyDotNET, TimSchemelter, it's a MVC action, the method is called by the MVC framework, not by user code Commented Jul 23, 2014 at 19:49
  • 1
    What does your route definition look like? Commented Jul 23, 2014 at 19:51
  • @ThomasLevesque is right. It's a MVC action. So, it's called upon loading the page. I'm not sure where the CustomFilterModel object is getting initialized or how to stop it from doing so. Commented Jul 23, 2014 at 19:52
  • 2
    I don't see a very easy way to do this without a custom model binder. You can possibly accept a string, check if the string is null or empty, then deserialize it yourself. Or maybe there's some property that must always be there? Such as filter.Id? Commented Jul 23, 2014 at 20:31

2 Answers 2

5

The default model binder (DefaultModelBinder) will create an instance of CustomFilterModel and then attempt to fill the object with data from the request. Even if the default model binder finds no properties of your model in the request it will still return the empty model, hence you will never get a null object for your parameter. There seems to be nothing in the source [1] that will return a null model.

[1] https://github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/System.Web.Mvc/DefaultModelBinder.cs

Sign up to request clarification or add additional context in comments.

Comments

0

Here is the replacement for DefaultModelBinder:

public class OptionalClassInstanceBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        bindingContext.FallbackToEmptyPrefix = false;
        return base.BindModel(controllerContext, bindingContext);
    }
}

[ModelBinder(typeof(OptionalClassInstanceBinder))]
public class CustomFilterModel
{
    ...
}

Beware though that with the binder in place you have to prefix the parameter name to any inner property, e.g. ?filter.range=1 instead of ?range=1.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.