Monday, July 25, 2011

Visual Studio LightSwitch 2011

Secondo Microsoft, VS LightSwitch dovrebbe dare agli sviluppatori la possibilità di creare applicazioni “Business” sia per desktop che anche per “Cloud”.

Creare rapidamente applicazioni Business di alta qualità

imageCon VS LightSwitch dovrebbe essere possibile creare applicazioni personalizzate e soluzioni “off-the-shelf”. Lo sviluppatore potrà utilizzare modelli già configurati e inoltre fornirà una serie di codice già pronti e componenti riutilizzabili per gestire le attività di routine. Tuttavia, sarà anche possibile scrivere codice personalizzato in Visual Basic. NET o in C#. Sarà inoltre possibile distribuire le applicazioni sul desktop, browser o nella “Cloud” evitando in questo modo i lunghi e complicati processi di installazione.

Accesso facile a sistemi e a dati già esistenti

imageLe applicazioni create con LightSwitch supporteranno l'esportazione in Microsoft Office Excel. In questo modo condividere e fare reporting sarà una cosa semplice e rapida. È inoltre sarà possibile connettere differenti sorgenti di dati esistenti (tra cui Microsoft SQL Server, Microsoft SQL Azure, SharePoint, Microsoft Office Access, …) alla vostra applicazione in modo da riutilizzare i processi di raccolta e di analisi dei dati.

image

 

 

 

Per ulteriori informazioni:VS lightswitch

Sunday, July 24, 2011

Putting it all together: ASP.NET MVC, SQLite, NHibernate, Fluent NHibernate & Log4Net

Today, I will explain how to set up a ASP.NET MVC project, which is using NHibernate for accessing a SQLite Database and Fluent NHibernate for configuring NHibernate. In this post I will give you a general overview about the structure of the project and in my future posts I will explain more in detail single its parts.

The sample project which can be downloaded from the following link http://dl.dropbox.com/u/36200417/MvcNhibernate.zip was setup as explained below.

The project is divided in two subprojects:
a)    MVC Web application
b)    DAL (Data Access Layer)

In a real project I would have more layers and subprojects, but for this example I want to keep it simple and therefore I removed the business layer.

First I was referencing all needed dlls:
- fluentnhibernate-NH3.0-binary-1.2.0.694
- log4net
- NHibernate-3.0.0.GA-bin
- SQLite-1.0.66.0-binaries

Afterwards I was generating a Database with the following command:sqlite3 test.db.

Copying the test.db file to the App_Data folder and adding the following connection string allows Asp.Net to access the SqLite Database.

<connectionStrings>
  <add name="SqLiteCon" connectionString="data source=|DataDirectory|test.db;" />
</connectionStrings>

Let’s now investigate on the structure of the project:

Project DAL:
/DAO: Data Access Objects provide abstract interfaces to a persistence medium like a database
/DAO/Interface: Interfaces for DAOs
/DAO/Implementation: Concrete implementation that provides access to the database with NHibernate. Note: BasicNhDAO<T, EntityKey> is a base class that provides basic functions (=CRUD). For every entity a DAO object exists, that is responsible for persisting the entity.
/Entities: Plain objects for encapsulating data.
/Entities/Interface: Interfaces for the plain objects
/Entities/Implementation:
/Mapping: FluentNHibernate Mappings, which are containing information how to map entities to tables of a database.
/SessionStorage: small framework for managing the NHibernate Session.

Project MvcNhibernate:
/App_Data: contains the SqLite database file
/Controllers: MVC Controllers. SqLiteController contains the logic for this example.
/Views/SqLite: MVC Views that are interesting for this example.

Thursday, July 21, 2011

ASP.NET MVC 3.0: CheckBoxListFor

Salve sviluppatori! È passato diverso tempo dal mio ultimo blog in italiano, perciò eccovi un metodo assolutamente utile per chi di voi sviluppa applicazioni web con ASP.NET MVC. Il metodo, che oggi vi propongo, serve per mostrare una lista di caselle di controllo (="Checkboxes"). Ricapitolando nel "Controller" vengono preparati i dati che verranno incorporati in un oggetto (="Model"), che poi verranno passati ed elaborati da una "View". Il metodo, che oggi vi presento, verrà utilizzato nella "View" ed estende la classe "HtmlHelper".

public static MvcHtmlString CheckBoxListFor<TModel, TKey, TValue>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, IDictionary<TKey, TValue>>> expForAvailableItems, Expression<Func<TModel, IList<TKey>>> expForSelectedKey)
{
    return CheckBoxListFor(htmlHelper, expForAvailableItems, expForSelectedKey, x => Convert.ToString(x), x => Convert.ToString(x), null, null);
}

public static MvcHtmlString CheckBoxListFor<TModel, TKey, TValue>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, IDictionary<TKey, TValue>>> expForAvailableItems, Expression<Func<TModel, IList<TKey>>> expForSelectedKey, Expression<Func<TValue, string>> expForValueToString, Expression<Func<TKey, string>> expForKeyToString, IDictionary<String, Object> htmlAttributesForListDiv = null, IDictionary<String, Object> htmlAttributesForItemDiv = null)
{
    //the name for the checkbox 
    string name = ExpressionHelper.GetExpressionText(expForSelectedKey);
    string HtmlName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
    if (String.IsNullOrEmpty(HtmlName))
    {
        throw new NullReferenceException("HtmlName is null");
    }

    //available items
    IDictionary<TKey, TValue> availableItems = expForAvailableItems.Compile().Invoke(htmlHelper.ViewData.Model);

    //selected items
    IList<TKey> selectedItems = expForSelectedKey.Compile().Invoke(htmlHelper.ViewData.Model);

    //convert value to string function
    Func<TValue, string> funcValueToString = expForValueToString.Compile();

    //convert key to string function
    Func<TKey, string> funcKeyToString = expForKeyToString.Compile();

    //Convert to checkboxlist
    TagBuilder listDiv = new TagBuilder("div");
    listDiv.MergeAttributes(htmlAttributesForListDiv, true);

    StringBuilder listItemsBuilder = new StringBuilder();
    // Define items
    // Loop through items
    Int32 index = 0;
    foreach (var item in availableItems)
    {
        // Define div
        TagBuilder inputdiv = new TagBuilder("div");
        inputdiv.MergeAttributes(htmlAttributesForItemDiv, true);

        // Define input 
        TagBuilder input = new TagBuilder("input");
        if (selectedItems.Contains(item.Key))
            input.MergeAttribute("checked", "checked");
        input.MergeAttribute("id", String.Concat(name, index));
        input.MergeAttribute("name", name);
        input.MergeAttribute("type", "checkbox");
        input.MergeAttribute("value", funcKeyToString(item.Key));

        // Define label
        TagBuilder label = new TagBuilder("label");
        label.MergeAttribute("for", String.Concat(name, index));
        label.SetInnerText(funcValueToString(item.Value));

        // Add item
        inputdiv.InnerHtml = String.Format("{0}{1}", input.ToString(TagRenderMode.SelfClosing), label.ToString(TagRenderMode.Normal));
        listItemsBuilder.Append(inputdiv.ToString(TagRenderMode.Normal));
        index++;
    }

    // Return list
    listDiv.InnerHtml = listItemsBuilder.ToString();
    return MvcHtmlString.Create(listDiv.ToString());
}

Nel "Controller" come già accennato prima vengono preparati i dati. Nel "Model" devono esistere un dizionario del tipo IDictionary<TKey, TValue> e una IList<TKey>. Il dizionario contiene tutti gli possibili elementi che verranno mostrati come caselle di controllo (="checkboxes"); la lista contiene le chiavi delle caselle di controllo selezionate.

[HttpGet]
[Authorize]
public ActionResult Edit()
{
    DataModel model = new DataModel();
    model.AvailableItems = DAO.GetAvailableItems().ToDictionary(x => x.ID, x => x.Desc);
    model.SelectedItems = DAO.GetSelectedItems().ToList(x => x.ID);
    return View(model);
}

Nella "View" per mostrare le caselle di controllo (="Checkboxes") basta chiamare la funzione ("CheckBoxListFor") e passare ad essa il dizionario e la lista che si trovano nel "Model". Non dimenticatevi di importare il "Namespace"!

<%@ Import Namespace="CuMvcApi.Helpers.HTML" %>

<%: Html.CheckBoxListFor(x=>x.AvailableItems, y=>y.SelectedItems) %>

Spero, che vi sia piaciuto questo articolo e che vi sia utile per il vostro lavoro!

Wednesday, July 20, 2011

VS 2010 SP1 + Web Standards Update

Ein echter Webentwickler sollte die zwei Visual Studio 2010 Aktualisierungen sofort installieren! Vor allem diese Aktualisierungen sind sehr wichtig für diejenigen die HTML5 entwickeln!

Visual Studio 2010 SP1:
http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=23691

Web Standards Update for Microsoft Visual Studio 2010 SP1:
http://visualstudiogallery.msdn.microsoft.com/a15c3ce9-f58f-42b7-8668-53f6cdc2cd83

Sunday, March 6, 2011

A useful ASP.NET MVC HTML extension method for rendering a DropDownList

I really like ASP.NET MVC, but understanding the usage of the DropDownListFor HTML helper method is not trivial. Therefore I decided to simplify it by introducing the following HTML extension methods for rendering a DropDownList. The idea is that the data for a dropdownlist is encapsulated in an IDictionary object.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Linq.Expressions;
using System.Diagnostics.CodeAnalysis;
using System.Web.Routing;
using System.Web.Mvc.Html;

namespace My.Helpers.HTML
{
    public static class CuSelectExtensions
    {
        /// <summary>
        /// returns an HTML select element for an IDictionary 
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="htmlHelper"></param>
        /// <param name="funcForDict">a function that returns an IDictionary</param>
        /// <param name="expForSelectedKey">a expression which returns the selected Key of the IDictionary</param>
        /// <returns></returns>
        public static MvcHtmlString DropDownListFor<TModel, TKey, TValue>(this HtmlHelper<TModel> htmlHelper, Func<TModel, IDictionary<TKey, TValue>> funcForDict, Expression<Func<TModel, TKey>> expForSelectedKey)
        {
            return htmlHelper.DropDownListFor(expForSelectedKey, funcForDict.Invoke(htmlHelper.ViewData.Model).ToSelectList(expForSelectedKey.Compile().Invoke(htmlHelper.ViewData.Model)));
        }

        /// <summary>
        /// Converts a dictionary to a SelectList
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dictionary"></param>
        /// <returns></returns>
        public static SelectList ToSelectList<TKey, TValue>(this IDictionary<TKey, TValue> dictionary)
        {
            //call with default value
            return dictionary.ToSelectList(default(TKey));
        }

        /// <summary>
        /// Converts a dictionary to SelectList
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dictionary"></param>
        /// <param name="selectedItem"></param>
        /// <returns></returns>
        public static SelectList ToSelectList<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey selectedItem)
        {
            return new SelectList(dictionary, "Key", "Value", selectedItem);
        }
    }
}


Emphasizing the importance to divide view model from data model is fundamental for creating a good MVC project. Keeping in mind this aspect you will notice the importance and the goodness of the extension methods I introduced above.
Let’s suppose we have the following data model and we want to render a form for collecting this kind of data.


public class Address
{
    public virtual int? ID { get; set; }
    public virtual State State { get; set; }
    public virtual string Province { get; set; }
    public virtual string City { get; set; }
    public virtual string Street { get; set; }
    public virtual string PostCode { get; set; }
}

public class State
{
    public virtual int? ID { get; set; }
    public virtual string Desc { get; set; }
}

Then our view model will look like this:


public class AddressView
{
    public IDictionary<int, string> AvailableStates { get; set; }
    public int SelectedState { get; set; }
    public string Province { get; set; }
    public string City { get; set; }
    public string Street { get; set; }
    public string PostCode { get; set; }
}

In the following controller, which access the Business-Logic (BL) for retrieving the Address object and which again is built on top of the DataAccess-Logic (DAL), we convert an Address object into an AddressView object and we pass it to a View for rendering it. For simplifying this example I am going to hide the implementation of the BL and DAL.


public ActionResult Edit(int id)
{
    Address ad = AddressBL.GetByID(id);
    IList<State> states = StateBL.GetAll();
    //Convert datamodel to viewmodel
    AddressView av = new AddressView();
    av.AvailableStates = states.ToDictionary(x => x.ID, x => x.Desc);
    dv.selectedState = ad.State.ID;
    av.Province = ad.Province
    // . . .
    return View(av);
}

Finally, using our proposed implementation for DropDownlistFor in a view is very easy. It is enough to specify an IDictionary object and a Key for the selected element. Here is an example:


<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" Inherits="ViewPage<AddressView>" %>

<%@ Import Namespace="My.Helpers.HTML" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
    <%: Html.DropDownListFor(x => x.States, x => x.AvailableStates)%>
</asp:Content>

Sunday, February 6, 2011

Second part: MVC.net & jqGrid

Let’s start by explaining how to include jqGrid (http://www.trirand.com/blog/) in your views. First you need to download and unzip jqGrid and jQueryUI (http://jqueryui.com/). I placed them in the root folder (jquery-ui-1.8.7.custom, jquery.jqGrid-3.8.2) of my project. Afterwards you need to reference them in the header of your web page.

<%--css for UI--%>
<link rel="stylesheet" type="text/css" media="screen" href="<%:Url.Content("~/jquery-ui-1.8.7.custom/css/ui-lightness/jquery-ui-1.8.7.custom.css") %>" />
<%--css for grid--%>
<link rel="stylesheet" type="text/css" media="screen" href="<%:Url.Content("~/jquery.jqGrid-3.8.2/css/ui.jqgrid.css") %>" />
<%-- jquery scripts --%>
<script src="<%:Url.Content("~/jquery.jqGrid-3.8.2/js/jquery-1.4.2.min.js") %>" type="text/javascript"></script>
<%-- ui scripts --%>
<script src="<%:Url.Content("~/jquery-ui-1.8.7.custom/js/jquery-ui-1.8.7.custom.min.js") %>" type="text/javascript"></script>
<%-- grid scripts --%>
<script src="<%:Url.Content("~/jquery.jqGrid-3.8.2/js/i18n/grid.locale-en.js") %>" type="text/javascript"></script>
<script src="<%:Url.Content("~/jquery.jqGrid-3.8.2/js/jquery.jqGrid.min.js") %>" type="text/javascript"></script>

Including following code should render the jqGrid on your page.

<table id="grid">
</table>
<div id="pager">
</div>
<script type="text/javascript">
    jQuery(document).ready(function () {
        jQuery("#grid").jqGrid({
            url: "/JqGrid/GridData",
            datatype: 'json',
            mtype: 'POST',
            colNames: ['Start Time', 'End Time', 'Date', 'Description', 'Notes'],
            colModel: [
            { name: 'FromTime', sortable: true, editable: true, edittype: 'text', width: 80 },
            { name: 'ToTime', sortable: true, editable: true, edittype: 'text', width: 80 },
            { name: 'Date', search: true, editable: true, edittype: 'text', width: 80 },
            { name: 'Description', search: true, editable: true, edittype: 'text', width: 200 },
            { name: 'Notes', sortable: true, editable: true, edittype: 'text', width: 150}],
            pager: jQuery('#pager'),
            rowNum: 10,
            rowList: [5, 10, 20, 50, 100, 200, 500, 1000],
            sortname: 'Date',
            sortorder: "desc",
            height: "100%",
            viewrecords: true,
            scrollOffset: 0,
            caption: 'Sample'
        });

        jQuery("#grid").jqGrid('navGrid', '#pager',
            { edit: true, add: true, del: true, search: true },
            { url: "/JqGrid/Edit", width: 'auto', closeAfterEdit: true, beforeShowForm: function (formid) { $("#Date").datepicker({ dateFormat: 'dd.mm.yy', showButtonPanel: true }); } },
            { url: "/JqGrid/Create", width: 'auto', closeAfterAdd: true, beforeShowForm: function (formid) { $("#Date").datepicker({ dateFormat: 'dd.mm.yy', showButtonPanel: true }); } },
              { url: "/JqGrid/Delete" },
            { closeAfterSearch: true, closeOnEscape: true, multipleSearch: true });
    });
</script>

Let’s explain now some parts:

url: "/JqGrid/GridData" -> tells where the grid should retrieve the data
colNames: ['Start Time', 'End Time',..] '-> column names
colModel: [{ name: 'FromTime' ...}] –> describes the data

To be more precise data is formatted as json. For example:
"cell":["00:00","02:00","06.02.2011","Element0",""]
where the element 1 (ex. 00:00) of cell items corresponds to the item 1 of the colNames and colModel items. 

Finally, we are going to investigate how data is retried from a controller. This part is quite simple you just need to have the data in a list object. At that moment you will have an extension method which encapsulate sorting, filtering and paging functionality. It is just enough to call JqGridDataModelConvert and to specify which properties of the objects contained in the list corresponds to the colModel. Moreover the property has to be wrapped by an object of GridCell, which encapsulate compare and string serialization and deserialization logic. Most of the time you will use BasicGridCell<T>, but it is also possible to extend the wrapper with custom code.

Example:

public virtual ActionResult GridData(GridSettings jqGridSettings)
{
    JqGridDataModel data = Data.JqGridDataModelConvert(columns =>
    {
        columns.Add("FromTime", ev => new BasicGridCell<string>(ev.FromTime));
        columns.Add("ToTime", ev => new BasicGridCell<string>(ev.ToTime));
        columns.Add("Date", ev => new DateTimeGridCell(ev.Date) { Format = "dd.MM.yyyy" });
        columns.Add("Description", ev => new BasicGridCell<string>(ev.Description));
        columns.Add("Notes", ev => new BasicGridCell<string>(ev.Notes));
    }, ev => new BasicGridCell<int>(ev.ID), jqGridSettings);
    return Json(data);
}

Programming is fun!!

Saturday, February 5, 2011

First part: MVC.net & jqGrid

This is the first part of a series of posts in which I am going to explain my solution for a fully functional data table with sorting, searching, filtering and paging functionalities. For reaching my goal I am using ASP.NET MVC 2.0 with jQuery (http://jquery.com/)and the jqGrid (http://www.trirand.com/blog/)plugin. I was browsing the internet looking for a solution, but I was not able to find a complete working solution. To be more precise I found some solution, but they were always buggy with common errors for example using simple string sorting for all data types. Basically, this examples were using string comparison, which for example is not evaluating  correctly on dates or on integers. A concrete example: Given numbers from 1 to 15 the sorted result would be 1,10,11,12,13,14,15,2,3,4,5,6,7,8,9.

Today I would like only to publish the sample project, to explain how to set up and to show how to use it. In the near future I will also explain more in detail some tricky parts of my solution. Today I would like only to publish the sample project, to explain how to set up and to show how to use it. In the near future I will also explain more in detail some tricky parts of my solution.

The project can be downloaded by the following url:
http://cid-a8f4afb63c503b89.office.live.com/self.aspx/.Public/MvcJqGrid.zip
It is enough to unzip and to start the solution.

Have fun to investigate about my approach!