GraemeMiller
GraemeMiller

Reputation: 12253

C# Optional Object Action MVC Parameter

Is it possible to specify an object as a parameter in MVC with default values in some way?

E.g.

    public virtual ViewResult Index(RequirementFilters requirementFilters)

I'd like to initialize the values of a couple of parameters on RequirementFilters?

At the moment I am doing

public virtual ViewResult Index(int status=1, bool required =false)

I wanted to create a Filter Object so I could re-use it but I can't figure out way of setting defaults for the object in the Action Parameters.

Thanks

Graeme

Upvotes: 4

Views: 1223

Answers (3)

Ethan Cabiac
Ethan Cabiac

Reputation: 4993

As long as you don't need to change the defaults per action, you can set them in the default constructor of the Model.

Upvotes: 1

Zasz
Zasz

Reputation: 12528

Users sometimes prefer to see the defaults on screen, rather than allowing the system to hide the defaults internally.

A better way of having defaults will be to actually show the defaults on int UI, in the HTML by rendering it with together with the defaults. That way when someone posts the page, the defaults which you pre-rendered is also posted and binded to the model.

So try and see if you can render with defaults whatever for you are rendering and posted to the Index action.

Finally, if you can't do it that way, what is preventing you from initializing the properties with default values in the no-arg constructor while creating the object?

EDIT

Or you can use the C# language feature the null coalescent operator to implement defaults. Look here to read about it.

Upvotes: 1

Jakub Konecki
Jakub Konecki

Reputation: 46008

You could create a custom ActionFilter attribute and create an instance of your Filter Object there. You can provide some properties through the custom attribute.

Here's an example:

public class DefaultQuerySettingsAttribute : ActionFilterAttribute
{
        public string ParameterName { get; set; }
        public Type SettingsType { get; set; }
        public int Rows { get; set; }
        public string SortColumn { get; set; }
        public string SortOrder { get; set; }
        public bool PagingEnabled { get; set; }

        public DefaultQuerySettingsAttribute()
        {
            this.ParameterName = "settings";

            var defaultSettings = new QuerySettings();
            this.Rows = defaultSettings.Rows;
            this.SortColumn = defaultSettings.SortColumn;
            this.SortOrder = defaultSettings.SortOrder;
            this.PagingEnabled = defaultSettings.PagingEnabled;
        }

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            base.OnActionExecuting(filterContext);

            if (filterContext.ActionParameters.ContainsKey(this.ParameterName))
            {
                var querySettings = filterContext.ActionParameters[this.ParameterName] as QuerySettings;

              if (querySettings == null || string.IsNullOrWhiteSpace(querySettings.SortColumn))
                                        filterContext.ActionParameters[this.ParameterName] = this.GetQuerySettings();
            }
       }

        private QuerySettings GetQuerySettings()
        {
            var querySettings = (QuerySettings)Activator.CreateInstance(SettingsType ?? typeof(QuerySettings));
            querySettings.Rows = Rows;
            querySettings.SortColumn = SortColumn;
            querySettings.SortOrder = SortOrder;
            querySettings.PagingEnabled = PagingEnabled;

            return querySettings;
        }
   }

ParameterName is the name of the argument in the action method (requirementFilters in your case). You can also specify actual type that will be instantiated by providing SettingsType.

Upvotes: 4

Related Questions