Sunday, September 30, 2012

Multiple Checkboxes in MVC 3, and Post selection to Controller Action

This article aims to explain - how to provide a multiple selection checkboxes in MVC 3 application, and the way to fetch the selection in an HttpPost contrller action.

Scenario:
A UI should have checkbox for each weekday (Mon to Sun), and when user submits the form, an HttpPost action should be able to fetch selected Weekdays by user.

We will create an Editor Template for this.
Please note this example is in C#.Net and Razor view, but you should easily be able to convert it in VB.Net and ASPX page if your application demands.

Step - 1: Create a Model (i.e. Type)

namespace MyMVC.Models
{
    public class WeekDaySelectionModel
    {
        public string WeekdDayName { get; set; }
        public bool Selected { get; set; }
    }
}

Step - 2: Create a collection of weekday names in your HttpGet action calling your view:

using System.Collections.Generic;
using MyMVC.Models;
[HttpGet]
public ActionResult EditEntry()
        {
            List<WeekDaySelectionModel> _weekDaySelection = new List<WeekDaySelectionModel>();
            _weekDaySelection.Add(new WeekDaySelectionModel { WeekdDayName = "Mon"});
            _weekDaySelection.Add(new WeekDaySelectionModel { WeekdDayName = "Tue"});
            _weekDaySelection.Add(new WeekDaySelectionModel { WeekdDayName = "Wed"});
            _weekDaySelection.Add(new WeekDaySelectionModel { WeekdDayName = "Thu"});
            _weekDaySelection.Add(new WeekDaySelectionModel { WeekdDayName = "Fri"});
            _weekDaySelection.Add(new WeekDaySelectionModel { WeekdDayName = "Sat"});
            _weekDaySelection.Add(new WeekDaySelectionModel { WeekdDayName = "Sun"});

return View("EditEntry", _weekDaySelection);              
}


Step - 3: Create an Editor Template in "..\Views\Shared\EditorTemplates" folder.

File name: WeekDaySelectionModel.cshtml (Make sure the file name is matching with the type name we created in Step 1).

@model MyMVC.Models.WeekDaySelectionModel
<span>
    @Html.HiddenFor(m => m.WeekdDayName)
    @Html.CheckBoxFor(m => m.Selected)
    @Html.LabelFor(m => m.Selected, Model.WeekdDayName)
</span>

Step - 4: Integrate this editor in your view.

File Name: EditEntry.cshtml

@model System.Collections.Generic.List<MyMVC.Models.WeekDaySelectionModel>
@for (int i = 0; i <= Model.SelectedWeekDays.Count - 1; i++)
{
    @Html.EditorFor(m => m.SelectedWeekDays[i])
}

Step - 5: Catching the selection in HttpPost controller action.

When user submits the pages, an HttpPost controller action will automatically receive the model having "Selected" property updated against each weekday name.

[HttpPost]
        public ActionResult EditEntry(System.Collections.Generic.List<WeekDaySelectionModel> _weekDayNames)
        {
            string selectedWeekDayNames = String.Empty;
            for (int i = 0; i <= _weekDayNames.Count - 1; i++)
            {
                if (_weekDayNames[i].Selected == true)
                {
                    if (String.IsNullOrEmpty(selectedWeekDayNames) == false)
                        selectedWeekDayNames += ",";
                    selectedWeekDayNames += _weekDayNames[i].WeekdDayName;
                }
            }
        }


Wednesday, September 12, 2012

Test email functionality in ASP.NET application using "Test Mail Server Tool""


At times we need to test the email functionality in our projects, during development and testing phases, and for that we prefer actual email sending does not take place. 

There are many tools available over internet, I prefer using "Test Mail Server" utility.

You can download it from here.

This article explains the steps to test the email functionality using this utility.

Following is the code extract and steps to check if Test Mail Server tool is working or not.

1) Copy following code in a code-behind (.cs) of your ASPX page in you website application.


System.Net.Mail.SmtpClient _smtpClient = new System.Net.Mail.SmtpClient("localhost", 25);
System.Net.Mail.MailMessage _sampleMail = new System.Net.Mail.MailMessage("sender@gmail.com", "receiver@gmail.com", "Test email - This is working", "This is a test email to check if Send Test Mail utility is working!");
_smtpClient.Send(_sampleMail);

Also make sure, you configure SMTP settings in web.config file, rather than hard-coding it in compiled code, and by doing that we can avoid supplying "localhost" and port number in source code. Its not done in this walkthrough  just to minimize the steps.


2) Make sure you have "Test Mail Server Tool" running on your machine.
3) Also, confirm the port number, and mail storage directory:
(Right-click on running instance of this utility in system tray, and click "Options")

If you want to change the port number, make sure you also change it in the code. (See, the yellow highlighted in Step 1)
4) Run the website, and execute send test mail code.
P.S. Sometimes it takes a while (say, 3-4 minutes) to generate a test email, save and open it. but it will always happen in background by this utility. If this happens, you can still close the browser after email send code is executed, and email will be shown to you once generated.

Saturday, September 8, 2012

Disable Caching for a Controller Action in ASP.NET MVC

At times, we need to disable the caching for some controller actions in our MVC application.
Say for example, there is an "Add Entry" link on your view, and it has a controller action assigned to it.
Clicking on this "Add Entry" link should call an action, and that will eventually load an Entry fill-up screen/ dialog.
Now when user clicks it for the first time it will call the controller action fine. But for next consecutive clicks, it may or may not call controller action and due to which the target dialog/ entry screen will remain prefilled with old data.
This is because of caching. Under some circumstances, browser caches controller actions, and that is why the cached operation is performed rather than the controller action.

To deal with this problem, we need to disable caching of those controller actions. (Its always recommended to disable caching of controller actions that invoke Add/ Edit of entry).

Following is the walkthrough to achieve the same:

1. Create an action filter. To do that create a new class inherited  ActionFilterAttribute class.

public
class NoCache : ActionFilterAttribute
{
   
public override void OnResultExecuting(ResultExecutingContext filterContext)
   
{
        filterContext
.HttpContext.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
        filterContext
.HttpContext.Response.Cache.SetValidUntilExpires(false);
        filterContext
.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
        filterContext
.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
        filterContext
.HttpContext.Response.Cache.SetNoStore();

       
base.OnResultExecuting(filterContext);
   
}
}

2. Decorate your controller action with the action filter class.

[NoCache]
public ActionResult EditEntry(int entryId)
{
..... the controller action code.}

This is what we need to do to disable caching of controller action in ASP.NET  MVC.