Tuesday, December 18, 2012

DateTime EditorTemplates and DefaultModelBinder

In order to use EditorTemplates with ASP.NET MVC 3 and Razor you need to do the following:
1. Create a folder named EditorTemplates in Views\Shared.
2. Add a new MVC3 View Page (Razor)

Inside the cshtml file write the code for the template:


@model System.DateTime?
@* <div class="editor-label">
    @Html.Label("")
</div>*@
<div class="editor-field">
    @Html.TextBox("",
    String.Format(@"{0:dd.MM.yyyy}",
        (Model.HasValue && Model.Value > new DateTime(1,1,1) )? Model.Value.Date : DateTime.Today),
                    new { @class = "editor-field" }
                 )
</div>

<script type="text/javascript">
    $(document).ready(function () {
        $("#@ViewData.ModelMetadata.PropertyName").datepicker({
            changeMonth: true,
            changeYear: true,
            dateFormat: "dd.mm.yy",
            firstDay: 1 // starts on monday
        });
    });
</script>


In my model I had the DateTime fields as not nullable and therefore I always seemed to receive the date 01/01/01. If my model had no value defined, the textbox would show the date 01/01/01. To overcome this I added the condition that Model.Value > new DateTime(1,1,1).


The problem with the code above was that it returned an invalid date if the computer that was accessing the site had a different format of the date (eg.: MM/dd/yyyy). The "cure" for this was to override the BindProperty in a class that inherited from DefaultModelBinder:



public class DateFixModelBinder :  DefaultModelBinder
    {

        protected override void BindProperty(ControllerContext controllerContext,
            ModelBindingContext bindingContext,
            System.ComponentModel.PropertyDescriptor propertyDescriptor)
        {

            if (propertyDescriptor.PropertyType == typeof(DateTime))
            {
                var model = bindingContext.Model;
                PropertyInfo property = model.GetType().GetProperty(propertyDescriptor.Name);
                DateTime date = DateTime.Today.Date;

                try
                {

                    var value = bindingContext.ValueProvider.GetValue(propertyDescriptor.Name);
                    if (value != null)
                    {
                        date = DateTime.ParseExact(value.AttemptedValue, "dd.MM.yyyy", null);
                        property.SetValue(model, date, null);

                    }
                }
                catch (Exception)
                {

                    property.SetValue(model, date, null);
                }

            }
            else
            {
                base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
            }


        }


Also in Global.asax, in Application_Start,  you need to write the following code:

 ModelBinders.Binders.DefaultBinder = new DateFixModelBinder();

Saturday, September 29, 2012

Dynamically add HTML markup to ASP.NET page

Sometimes you just might need to add dynamic HTML markup to your ASP.NET pages. I had to do the same thing and here I will show you how I did it.

First I created a div in my ASP.NET page like this:

<div id="myDiv" runat="server"></div>
The important things to note here are:
1. We need a name for the div, in this case "myDiv".
2. The attribute runat = "server". This attribute signifies that the control is a server control and the enclosed controls can be accessed by server scripts. If this attribute was missing, the server would have treated the line of code as a simple line of text.

Next thing to do we will write code in C# in the page load event. The full code looks like this:


protected void Page_Load(object sender, EventArgs e)
        {

            LiteralControl myList = new LiteralControl();
            System.Web.UI.Control myDiv = (System.Web.UI.Control)this.Page.FindControl("myDiv");

            StringBuilder sb = new StringBuilder(); //needs using System.Text on top of the page
            sb.Append("<ul>"); //the start of the list
            for (int i = 0; i < 4; i++)
            {
                sb.Append("<li>Item ");
                sb.Append(i.ToString());
                sb.Append("</li>");

            }

            sb.Append("</ul>"); //the end of the list

            myList.Text = sb.ToString();

            this.myDiv.Controls.Add(myList);

        }

So here we instantiate a LiteralControl whose text property will take the new HTML markup that we need on the page.

Then we search the page with the FindControl method of the Page that takes as parameter the name of the div where the new HTML will reside.

I created the HTML markup using a StringBuilder object. This class is very useful when working with strings because of the better memory management it has over the String class when concatenating.

The rest of the code is pretty clear.

Wednesday, September 26, 2012

Alternating color for rows or columns in SSRS

I needed to display some reports with alternating colors for columns today. The report was a matrix report that had a column group that showed the months of the year.

After selecting the column go to properties and click on Fill -> Background color -> Expression



In the expression box type the following:

=iif(Fields!MonthNumber.Value mod 2,"Transparent","LightGrey")

 The same thing can be achieved for the rows. Instead of selecting the column, select the row of the table and follow the same steps.

Hope it will be usefull!