Arnold Zahrneinder
Arnold Zahrneinder

Reputation: 5200

Bind attribute does not have `Exclude`, is there an work around?

In ASP.Net Core MVC, the Bind attribute seems to not have the Exclude property anymore. Assuming I have 20 properties in my model, and I only want to exclude a single filed from the model for the edit function for example, it will be really inconvenient to type the name of the 19 properties in order to exclude that single field.

The point of the question is to find if Microsoft has added any other attribute for this purpose or there's something hidden from my view that can do this.

Upvotes: 5

Views: 3051

Answers (2)

Grimm
Grimm

Reputation: 791

I am not exactly sure where you want to exclude that single field. If you have an action method that gets a parameter of the type of a viewmodel class containing 20 properties and you want to exclude one of those properties from model binding you can use [BindNever] annotation on that property (please have a look at Model Binding).

Thus your action method gets a viewmodel with that annotated property always being null - a user cannot pass a value for that property because it won't be processed for model binding.

Upvotes: 0

rocky
rocky

Reputation: 7696

Similarly to BindAttribute, you have to implement the IPropertyFilterProvider interface.

Something like this:

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)]
    public class ExcludeBindAttribute : Attribute, IModelNameProvider, IPropertyFilterProvider
    {
        private static readonly Func<ModelMetadata, bool> _default = (m) => true;

        private Func<ModelMetadata, bool> _propertyFilter;

        public string[] Exclude { get; }

        public string Prefix { get; set; }

        public ExcludeBindAttribute(params string[] exclude)
        {
            var items = new List<string>();
            foreach (var item in exclude)
            {
                items.AddRange(SplitString(item));
            }

            Exclude = items.ToArray();
        }

        public string Name
        {
            get { return Prefix; }
        }

        public Func<ModelMetadata, bool> PropertyFilter
        {
            get
            {
                if (Exclude != null && Exclude.Length > 0)
                {
                    if (_propertyFilter == null)
                    {
                        _propertyFilter = (m) => !Exclude.Contains(m.PropertyName, StringComparer.Ordinal);
                    }

                    return _propertyFilter;
                }
                else
                {
                    return _default;
                }
            }
        }

        private static IEnumerable<string> SplitString(string original)
        {
            if (string.IsNullOrEmpty(original))
            {
                return Array.Empty<string>();
            }

            var split = original.Split(',').Select(piece => piece.Trim()).Where(piece => !string.IsNullOrEmpty(piece));

            return split;
        }
    }

Upvotes: 1

Related Questions