Tuesday, June 7, 2016

ASP.Net MVC HTTP GET Controller Action Processing Pattern for Reports or Searches

Scenario


  • Select a month
  • Days of month are displayed on the same view


Controller

[HttpGet]
public ActionResult Index(ReportPageSelectionModel model, string msg)
{
String preSelectedMonth = null;
try
{
ViewBag.Msg = msg;

if (model.DisplayResults == false)
{
model.MonthList = ReportPageModelFactory.GetMonthList();
return View(model);
}
else
{
preSelectedMonth = model.SelectedMonth;
model.MonthList = ReportPageModelFactory.GetMonthList();
ReportPageResultModel resultModel =
ReportPageModelFactory.GetResultsModel(model.SelectedMonth);
ViewBag.Result = resultModel;
return View(model);
}
}
catch (Exception ex)
{
return RedirectToAction("Index", new { Msg = GetInnerMostException(ex).Message, SelectedMonth = preSelectedMonth });
}
}

Exception GetInnerMostException(Exception ex)
{
if (ex.InnerException == null)
return ex;
return GetInnerMostException(ex.InnerException);
}

View

@model ReportPageSelectionModel
@using ReportPage.Models

@{
    ViewBag.Title = "Report Page";
}

<div>
    <h3>Criteria Selection</h3>

    @using (Html.BeginForm("Index", "Home", FormMethod.Get))
    {
        <div class="form-horizontal">

            @Html.ValidationSummary(true, "", new { @class = "text-danger" })

            <div class="form-group">
                <div class="control-label col-md-3"><strong>@Html.LabelFor(model => model.SelectedMonth)</strong></div>
                <div class="col-md-9">
                    <div class="form-control-static">
                        @Html.DropDownListFor(model => model.SelectedMonth, Model.MonthList)
                    </div>
                </div>
            </div>

            <div class="form-group">
                <div class="col-md-offset-4 col-md-8">
                    <input type="hidden" name="DisplayResults" value="true" />
                    @Html.ActionLink("Reset", "Index", null, new { @class = "btn btn-default" })
                    <input type="submit" value="Go" class="btn btn-primary" />
                </div>
            </div>
        </div>
    }

    @if (@ViewBag.Msg != null)
    {
        <div class="alert alert-danger">
            <a href="#" class="close" data-dismiss="alert" aria-label="close">&times;</a>
            <strong>@ViewBag.Msg</strong>
        </div>
    }

</div>

<hr />

@{
    var result = @ViewBag.Result as ReportPageResultModel;
}

@if (result != null)
{
    <div>
        <h3>Result</h3>
        @foreach(var day in result.Result)
        {
            <p>@day</p>
        }
    </div>
}

@section scripts
{
    <script>
        $(function () {
            $("#SelectedMonth").change(function () {
                $("form").submit();
            });
        });
    </script>
}

Models

public class ReportPageSelectionModel
{
[DisplayName("Month")]
[Required]
public string SelectedMonth { get; set; }
public List<SelectListItem> MonthList { get; set; }
public bool DisplayResults { get; set; }
}

public class ReportPageResultModel
{
public DateTime SelectedMonth { get; set; }
public List<string> Result { get; set; }
}


Model Factories

static public class ReportPageModelFactory
{
static public ReportPageResultModel GetResultsModel(string selectedMonthStr)
{
var model = new ReportPageResultModel();
model.SelectedMonth = DateTime.Parse(selectedMonthStr);
model.Result = new List<string>();
for (int i=1; i<= DateTime.DaysInMonth(model.SelectedMonth.Year, model.SelectedMonth.Month); i++)
{
DateTime day = new DateTime(model.SelectedMonth.Year, model.SelectedMonth.Month, i);
model.Result.Add(day.ToString("dddd MMMM d, yyyy"));
}
return model;
}

static public List<SelectListItem> GetMonthList()
{
var monthList = new List<SelectListItem>();
for (int i = 1; i <= 12; i++)
{
DateTime month = new DateTime(DateTime.UtcNow.Year, i, 1);
monthList.Add(
new SelectListItem()
{
Text = String.Format("{0}  {1}", month.Year, month.ToString("MMMM")),
Value = month.ToString()
});
}
return monthList;
}
}