Attributes in MVC (Part 2)

Attributes in ASP DOT NET MVC (Part 2)

There are many attributes in ASP DOT NET MVC that can be applied to ASP.NET MVC model or its properties. In our previous article, we discussed the following attributes in ASP DOT NET MVC, with examples. 

1. Display

2. DisplayName

3. DisplayFormat

4. ScaffoldColumn

5. DataTypeAttribute, 

6. DisplayColumnAttribute  

In this article, I will discuss the use of the following attributes in ASP DOT NET MVC application.

7. UIHint

8. HiddenInput

9. ReadOnly

Opening a page in the new browser window in asp.net MVC application:

Let’s discuss how we will open the URL in a new window. Along the way, let’s see how to use UIHint attribute.

Please read Attribute in MVC Part – 1 article before proceeding to this article. We will be using the same example that we started in our last article.

Changes to ModifyEmployee.cs class file in the Models folder
namespace AttributesInMVC.Models
{
    [MetadataType(typeof(EmployeeMetaData))]
    public partial class Employee
    {
    }

    public class EmployeeMetaData
    {
        [DataType(DataType.Url)]
        public string PersonalWebSite { get; set; }
    }
}
Modify the Details action method of EmployeeController as shown below
namespace AttributesInMVC.Controllers
{
    public class EmployeeController : Controller
    {
        public ActionResult Details(int id)
        {
            EmployeeDBContext dbContext = new EmployeeDBContext();
            Employee employee = dbContext.Employees.Single(x => x.Id == id);
            return View(employee);
        }
    }
}
Changes to Details.cshtml view
@model AttributesInMVC.Models.Employee
@{
    ViewBag.Title = "Details";
}
@Html.DisplayForModel()

At this point, build the application and navigate to http://localhost:61449/Employee/Details/1. When we click on the personal website link, the target page will open in the same window.

If you want the page to open in a new window,

Right click on “Views” folder, and add “Shared” folder if it does not exists. 

Then again, Right click on the “Shared” folder, and add “DisplayTemplates” folder. 

Next, Right click on DisplayTemplates folder, and add a view. Set “Url” as the name.

Copy and paste the following code in Url.cshtml view

<a href=”@ViewData.Model” target=”_blank”>@ViewData.Model</a>

That’s it. Build the application and click on the link. Notice that, the page is now opened in a new window. The downside of this approach is that, from now on all the links, will open in a new window. To overcome this, follow these steps.

1. Rename Url.cshtml to OpenInNewWindow.cshtml
2. Decorate “PersonalWebSite” property in EmployeeMetaData class with UIHint attribute and specify the name of the template to use. In our case, the name of the template is “OpenInNewWindow”.

namespace AttributesInMVC.Models
{
    [MetadataType(typeof(EmployeeMetaData))]
    public partial class Employee
    {
    }

    public class EmployeeMetaData
    {
        [DataType(DataType.Url)]
        [UIHint("OpenInNewWindow")]
        public string PersonalWebSite { get; set; }
    }
}

So, UIHint attribute is used to specify the name of the template to use to display the data field. 

Hiddeninput and readonly attributes in MVC:

HiddenInput attribute is useful when we want to render a property using input type=hidden. This attribute is extremely useful, when we don’t want the user to see or edit the property, but we need to post the property value to the server when the form is submitted, so the correct record can be updated. HiddenInput is present in System.Web.Mvc namespace.

ReadOnly attribute is present in System.ComponentModel namespace. As the name suggests, this attribute is used to make a property readonly. Please note that, we will still be able to change the property value on the view, but once we post the form the model binder will respect the readonly attribute and will not move the value to the property.  We can also, make the property of a class readonly simply, by removing the SET accessor.  

Changes to ModifyEmployee.cs file used in the demo. Notice that Id property is decorated with HiddenInput attribute and EmailAddress is decorated with ReadOnly attribute.

namespace AttributesInMVC.Models
{
    [MetadataType(typeof(EmployeeMetaData))]
    public partial class Employee
    {
    }

    public class EmployeeMetaData
    {
        // Id property is hidden and cannot be changed
        [HiddenInput(DisplayValue = false)]
        public int Id { get; set; }

        // EmailAddress is read only
        [ReadOnly(true)]
        [DataType(DataType.EmailAddress)]
        public string EmailAddress { get; set; }

        [ScaffoldColumn(true)]
        [DataType(DataType.Currency)]
        public int? Salary { get; set; }

        [DataType(DataType.Url)]
        [UIHint("OpenInNewWindow")]
        public string PersonalWebSite { get; set; }

        [DisplayAttribute(Name = "Full Name")]
        public string FullName { get; set; }

        [DisplayFormat(DataFormatString = "{0:d}")]
        public DateTime? HireDate { get; set; }

        [DisplayFormat(NullDisplayText = "Gender not specified")]
        public string Gender { get; set; }
    }
}
Changes to EmployeeController.cs file
using System.Web.Mvc;
using AttributesInMVC.Models;
using System.Data.Entity;

namespace AttributesInMVC.Controllers
{
    public class EmployeeController : Controller
    {
        public ActionResult Details(int id)
        {
            EmployeeDBContext dbContext = new EmployeeDBContext();
            Employee employee = dbContext.Employees.Single(x => x.Id == id);
            return View(employee);
        }

        public ActionResult Edit(int id)
        {
            EmployeeDBContext dbContext = new EmployeeDBContext();
            Employee employee = dbContext.Employees.Single(x => x.Id == id);

            return View(employee);
        }

        [HttpPost]
        public ActionResult Edit(Employee employee)
        {
            if (ModelState.IsValid)
            {
                EmployeeDBContext dbContext = new EmployeeDBContext();
                Employee employeeFromDB = dbContext.Employees.Single(x => x.Id == employee.Id);

                // Populate all the properties except EmailAddrees
                employeeFromDB.FullName = employee.FullName;
                employeeFromDB.Gender = employee.Gender;
                employeeFromDB.Age = employee.Age;
                employeeFromDB.HireDate = employee.HireDate;
                employeeFromDB.Salary = employee.Salary;
                employeeFromDB.PersonalWebSite = employee.PersonalWebSite;

                dbContext.Entry(employeeFromDB).State = EntityState.Modified;
                dbContext.SaveChanges();
                return RedirectToAction("Details", new { id = employee.Id });
            }
            return View(employee);
        }
    }
}
Create Edit.cshtml view and copy and paste the following code
@model AttributesInMVC.Models.Employee
@{
    ViewBag.Title = "Edit";
}

<div style="font-family:Arial">
    @using (Html.BeginForm())
    {
        @Html.EditorForModel()
        <br />
        <br />
        <input type="submit" value="Save" />
    }
</div>

Run the application and navigate to http://localhost:61449/Employee/Edit/1 and see everything is working as expected

In the next article, I will discuss Data Annotations in ASP.NET MVC

SUMMARY:

In this article, I try to explain the Attributes in ASP DOT NET MVC application to format the data with real-time examples. I hope this article will help you with your need. I would like to have your feedback. Please post your feedback, question, or comments about this article.

Leave a Reply

Your email address will not be published. Required fields are marked *