Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

In MVC Core Passing Custom Attribute from Model Class to HTML Element e.g.:Input Masking

0.00/5 (No votes)
9 May 2018 1  
Passing custom attribute from Model Class in MVC ASP NET Core and built HTML atrribute accordingly into HTML element, Best Practice Input Masking

Introduction

I was trying to find a way passing customized attribute values from Model Class in MVC ASP NET Core and built HTML attribute accordingly into HTML element. This process is important as one of the examples.

Create Input Masking by Passing the Masking info through Model Class instead of directly adding into HTML individually one by one !

I was able to do it through MVC 4 or 5 in one of the good examples, see this link: Input Masking in MVC 4 using Data Annotation. However in MVC Core, I have not yet found any article!

Background

Before showing how to pass the custom attribute from model class and create the HTML Attribute, let's have a brief description including some references to the following:

Input Masking: I am using JQuery Plugins. For more information on this link, please have a look at Masked Input Plugin as I am using this component for my example.

Attribute: Powerful method of associating metadata, or declarative information, with code (assemblies, types, methods, properties, and so forth). More information with this link: Attribute usage (C#) I am using below to provide mask information to the model class like [HTMLMaskAttribute(name="mask",value="(999) 999-9999"].

IDisplayMetadataProvider: An interface used to provide DisplayMetadata which is in turn a metadata representation of a model type, property or parameter. Link - IDisplayMetadataProvider Interface

Steps Taken

<script src="jquery.js" type="text/javascript"></script>
<script src="jquery.maskedinput.js" type="text/javascript"></script>

and then add this script inside the view as the following:

<script type="text/javascript">
       $(function () {
           $('[mask]').each(function (e) {
               $(this).mask($(this).attr('mask'));
           });
       });
   </script>
@model Product
@{ ViewBag.Title = "New Product";
    Layout = "_Layout";}

    <script type="text/javascript">
        $(function () {
            $('[mask]').each(function (e) {
                $(this).mask($(this).attr('mask'));
            });
        });
    </script>

<form asp-action="Create" method="Post">

    <div asp-validation-summary="All" class="text-danger"></div>
    <input type="hidden" asp-for="ProductID" />
    <div class="form-group">
        <div><span asp-validation-for="ProductName" class="text-danger"></span></div>
        <label asp-for="ProductName"></label>
        <input type="text" class="form-control" asp-for="ProductName" />
    </div>
  
    <div class="form-group">
        <div><span asp-validation-for="Phone1" class="text-danger"></span></div>
        <label asp-for="Phone1"></label>
        <input type="text" class="form-control" asp-for="Phone1" />
    </div>
  
    <div class="form-group">
        <div><span asp-validation-for="OverallRate" class="text-danger"></span></div>
        <label asp-for="OverallRate"></label>
        <input type="text" class="form-control" asp-for="OverallRate" />
    </div>

</form>
  1. Create Custom Attribute:
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
        public sealed class HTMLMaskAttribute : Attribute
        {
            public HTMLMaskAttribute () { }
            public HTMLMaskAttribute (string name, object value)
            {
                if (name == null)
                {
                    throw new ArgumentNullException("name");
                }
                Name = name;
                Value = value;
            }
    
            public string Name { get; private set; }
            public object Value { get; private set; }
        }
  2. Create custom DisplayMetadataProvider by implementing the interface IDisplayMetadataProvider, this provider will read the new attribute from the model class.
    public class CustomMetadataProvider : IDisplayMetadataProvider
       {
           public CustomMetadataProvider() { }
    
           public void CreateDisplayMetadata(DisplayMetadataProviderContext context)
           {
               if (context.PropertyAttributes != null)
               {
    
                   foreach (object propAttr in context.PropertyAttributes)
                   {
                       HTMLMaskAttribute addMetaAttr = propAttr as HTMLMaskAttribute;
                       if (addMetaAttr != null)
                       {
                           context.DisplayMetadata.AdditionalValues.Add
                                         (addMetaAttr.Name, addMetaAttr.Value);
                       }
                   }
               }
           }
       }
    
  3. In Startup class, register CustomMetadataProvider in the configureServices method:
    public void ConfigureServices(IServiceCollection services)
            {
                .
                .
                . 
                services.AddMvc().AddMvcOptions(opts => {
                   
                    opts.ModelMetadataDetailsProviders.Add(new CustomMetadataProvider());
                }) ;
                .
                .
                .
             }
  4. Create Model Class and add the new custom attribute "mask":
       public class Product
        {
            public int ProductID { set; get; }
            
            public string ProductName { set; get; }
            public string LogoURL { set; get; }
            [HTMLMaskAttribute("mask", "9")] //number only
            public int ProductRate { set; get; }
            [HTMLMaskAttribute("mask", "(999) 999-9999")] //phone format 
            public string Phone1 { set; get; }
           
        }
  5. Create controller and pass the product model to the view:
    public class ProductController : Controller
      {
         //Actions before
          public ViewResult Create()
          {
              Product _product = new Product ();
              return View(_product );
          }
      //Actions After
      }
    
  6. Download the Masked Input Plugin and include the jQuery and masked input JavaScript files to your specific view page or to your _Layout.cshtml page:
  7. Create View "Create.cshtml":
  8. Run the application and notice the html attribute mask has been added for both location in Phone1 and OverallRate:

    also looking at the viewsource, you will notice the mask:

    <input name="Phone1" class="form-control valid" id="Phone1" 
    
     aria-invalid="false" type="text" value="(123) 456-7890" mask="(999) 999-9999">

Points of Interest

The interesting of this article is to show in ASP Core mainly how to pass the attribute from Model class into HTML element programmatically using one useful example "Input Mask".

Comparing with previous version of MVC such as 3 or 4 in MVC Core, you don't need to modify the String.cshtml file and just can be done programmatically in C#.

The Masked plugin used was just an example. You can use some other plugins..

History

  • May 2018: Submitted

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here