csharp

Using JQuery DataTables , Entity Framework (EF) and Dynamic LINQ in conjunction


The Problem

Few months ago I started using DataTables (A plugin for JQuery in order to create neat tables in HTML). However, I noticed that twice I wrote code kind of similar for addressing the same issue. Thus with this project I’d like to set a base for extensible code which deals with the common request and response work related to DataTable API. The goal is to quickly provide an endpoint which provides data compatible with DataTable data source.
All the filtering, sorting and projection should happen at server side.

For this solution I’ll use the following components:
DataTables see https://www.datatables.net/
Dynamic LINQ see http://dynamiclinq.azurewebsites.net/

My project is inspired by https://github.com/kendo-labs/dlinq-helpers. Kendo Grid is a very robust table for HTML.

Remarks

– Filtering logic has not been taking into consideration, mainly because I didn’t find a common mechanism for receive filter information at server side. If this is a requirement, I will consider to mimic Kendo UI protocol for sending filtering information.
– Order and Search have been implemented
– Implementations for Array of Array and Array of Objects have been provided, however the developer is responsible of calling the proper methods.

The Solution

First of all The idea is to create an extensible module. At this time the filtering logic is pending to really have a useful. Thus I will start by showing the code of the DataTables module. The following code holds the models used by the model these classes are basically POCOS to be used to receive or send information.

using System.Runtime.Serialization;

namespace DataTables.Models
{
    /// <summary>
    /// Holds the information required for a given column
    /// </summary>
    [DataContract]
    public class ColumnRequest
    {
        /// <summary>
        /// Specific search information for the column
        /// </summary>
        [DataMember(Name = "search")]
        public SearchRequest Search { get; set; }

        /// <summary>
        /// Column's data source, as defined by columns.data.
        /// </summary>
        [DataMember(Name = "data")]
        public string Data { get; set; }

        /// <summary>
        /// Column's name, as defined by columns.name.
        /// </summary>
        [DataMember(Name = "name")]
        public string Name { get; set; }

        /// <summary>
        /// Flag to indicate if this column is search-able (true) or not (false). This is controlled by columns.searchable.
        /// </summary>
        [DataMember(Name = "searchable")]
        public bool? Searchable { get; set; }

        /// <summary>
        /// Flag to indicate if this column is orderable (true) or not (false). This is controlled by columns.orderable.
        /// </summary>
        [DataMember(Name = "orderable")]
        public bool? Orderable { get; set; }

    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;

namespace DataTables.Models
{
    /// <summary>
    /// 
    /// </summary>
    [DataContract]
    public class SearchRequest
    {
        /// <summary>
        /// Search value
        /// </summary>
        [DataMember(Name = "value")]
        public string Value { get; set; }

        /// <summary>
        /// true if the search value should be treated as a regular expression for advanced searching, false otherwise. 
        /// </summary>
        [DataMember(Name = "regex")]
        public bool Regex { get; set; }

        public virtual string Operator { get; set; }

        public SearchRequest()
        {
            Operator = @"contains";
        }

        private static readonly IDictionary<string, string> operators = new Dictionary<string, string>
        {
            {"eq", "="},
            {"neq", "!="},
            {"lt", "<"},
            {"lte", "<="},
            {"gt", ">"},
            {"gte", ">="},
            {"startswith", "StartsWith"},
            {"endswith", "EndsWith"},
            {"contains", "Contains"},
            {"doesnotcontain", "Contains"}
        };

        public virtual string ToExpression(DataTableRequest request)
        {
            if (Regex)
                throw new NotImplementedException("Regular Expression is not implemented");

            string comparison = operators[Operator];
            List<string> expressions = new List<string>();
            foreach (var searchableColumn in request.Columns.Where(c => c.Searchable.HasValue && c.Searchable.Value))
            {
                if (Operator == "doesnotcontain")
                {
                    expressions.Add(string.Format("!{0}.ToString().{1}(\"{2}\")", searchableColumn.Data, comparison, Value));
                }
                else if (comparison == "StartsWith" || comparison == "EndsWith" || comparison == "Contains")
                {
                    expressions.Add(string.Format("{0}.ToString().{1}(\"{2}\")", searchableColumn.Data, comparison, Value));
                }
                else
                {
                    expressions.Add(string.Format("{0} {1} \"{2}\"", searchableColumn.Data, comparison, Value));
                }
            }
            return string.Join(" or ", expressions);
        }
    }
}

using System.Runtime.Serialization;

namespace DataTables.Models
{
    /// <summary>
    /// Contains the information about the sort request
    /// </summary>
    [DataContract]
    public class OrderRequest
    {
        /// <summary>
        /// Indicates the orientation of the sort "asc" for ascending or "desc" for desc
        /// </summary>
        [DataMember(Name = "dir")]
        public string Dir { get; set; }

        /// <summary>
        /// Column which contains the number of column which requires this sort.
        /// </summary>
        [DataMember(Name = "column")]
        public int? Column { get; set; }

        public string ToExpression(DataTableRequest request)
        {
            return string.Concat(request.Columns[Column.Value].Data, " ", Dir);
        }
    }
}


using System.Collections;
using System.Runtime.Serialization;

namespace DataTables.Models
{
    /// <summary>
    /// Encapsulates a Data Table response format
    /// </summary>
    /// <typeparam name="TData"></typeparam>
    [DataContract]
    public class DataTableResponse 
    {
        /// <summary>
        /// The draw counter that this object is a response to - from the draw parameter sent as part of the data request. Note that it is strongly recommended for security reasons that you cast this parameter to an integer, rather than simply echoing back to the client what it sent in the draw parameter, in order to prevent Cross Site Scripting (XSS) attacks.
        /// </summary>
        [DataMember(Name = "draw")]
        public int? Draw { get; set; }

        /// <summary>
        /// The data to be displayed in the table. 
        /// <remarks>
        /// This is an array of data source objects, one for each row, which will be used by DataTables. 
        /// Note that this parameter's name can be changed using the ajax option's dataSrc property.
        /// </remarks>
        /// </summary>
        [DataMember(Name = "data")]
        public IEnumerable Data { get; set; }

        /// <summary>
        /// Total records, before filtering (i.e. the total number of records in the database)
        /// </summary>
        [DataMember(Name = "recordsTotal")]
        public int? RecordsTotal { get; set; }

        /// <summary>
        /// Total records, after filtering (i.e. the total number of records after filtering has been applied - not just the number of records being returned for this page of data).
        /// </summary>
        [DataMember(Name = "recordsFiltered")]
        public int? RecordsFiltered { get; set; }

        /// <summary>
        /// Optional: If an error occurs during the running of the server-side processing script, you can inform the user of this error by passing back the error message to be displayed using this parameter. Do not include if there is no error.
        /// </summary>
        [DataMember(Name = "error")]
        public string Error { get; set; }
    }
}

using System.Collections.Generic;
using System.Runtime.Serialization;

namespace DataTables.Models
{
    /// <summary>
    /// This class holds the minimum amount of information provided by DataTable to perform a request on server side.
    /// </summary>
    [DataContract]
    public class DataTableRequest
    {
        /// <summary>
        /// Column data request description
        /// </summary>
        [DataMember(Name = "columns")]
        public List<ColumnRequest> Columns { get; set; }

        /// <summary>
        /// Column requested order description
        /// </summary>
        [DataMember(Name = "order")]
        public List<OrderRequest> Order { get; set; }

        /// <summary>
        /// Global search value. To be applied to all columns which have search-able as true.
        /// </summary>
        [DataMember(Name = "search")]
        public SearchRequest Search { get; set; }

        /// <summary>
        /// Paging first record indicator. This is the start point in the current data set (0 index based - i.e. 0 is the first record).
        /// </summary>
        [DataMember(Name = "start")]
        public int? Start { get; set; }

        /// <summary>
        /// Number of records that the table can display in the current draw. It is expected that the number of records returned will be equal to this number, unless the server has fewer records to return. 
        /// </summary>
        [DataMember(Name = "length")]
        public int? Length { get; set; }

        /// <summary>
        /// Draw counter. This is used by DataTables to ensure that the Ajax returns from server-side processing requests are drawn in sequence by DataTables (Ajax requests are asynchronous and thus can return out of sequence). 
        /// This is used as part of the draw return parameter. 
        /// </summary>
        [DataMember(Name = "draw")]
        public int? Draw { get; set; }
    }
}

They way I have decided to implement logic is through extension methods.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic;
using DataTables.Models;

namespace DataTables.Extensions
{
    public static class IQueryableExtensions
    {
        /// <summary>
        /// Computes a DataTables response based on the request. This response is compatible with an array of arrays
        /// </summary>
        /// <remarks>
        /// This response is compatible with an array of arrays
        /// </remarks>
        /// <typeparam name="TEntity">Entity to be returned in the data</typeparam>
        /// <param name="query">Initial data source. It will be part of the response after computations</param>
        /// <param name="request">Holds information about the request</param>
        /// <param name="getEntityFieldNamesFunc">Function which provides a sequence of fields of the entity to be used</param>
        /// <param name="getEntityAsEnumerableFunc">Function which converts an entity to an array</param>
        /// <returns></returns>
        public static DataTableResponse GetDataTableResponse<TEntity>(this IEnumerable<TEntity> query, DataTableRequest request,
            Func<TEntity, IEnumerable<string>> getEntityFieldNamesFunc, Func<TEntity, System.Collections.IEnumerable> getEntityAsEnumerableFunc)
        {
            // When using Arrays set the columns data before performing operations.
            SetColumnData(request, getEntityFieldNamesFunc);

            var response = GetDataTableResponse(ref query, request);

            // Converts the result compatible with an array (required by default for DataTables)
            response.Data = query.Select(getEntityAsEnumerableFunc);
            return response;
        }

        /// <summary>
        /// Computes a DataTables response based on the request. This response is compatible with an array of objects.
        /// </summary>
        /// <remarks>
        /// This response is compatible with an array of objects.
        /// </remarks>
        /// <typeparam name="TEntity">Entity to be returned in the data</typeparam>
        /// <param name="query">Initial data source. It will be part of the response after computations</param>
        /// <param name="request">Holds information about the request</param>
        /// <returns></returns>
        public static DataTableResponse GetDataTableResponse<TEntity>(this IEnumerable<TEntity> query, DataTableRequest request)
        {
            // When using Arrays set the columns data before performing operations.
            var response = GetDataTableResponse(ref query, request);

            // Converts the result compatible with an array (required by default for DataTables)
            response.Data = query;
            return response;
        }

        private static DataTableResponse GetDataTableResponse<TEntity>(ref IEnumerable<TEntity> query, DataTableRequest request)
        {
            var response = new DataTableResponse();
            // Setting up response
            response.Draw = request.Draw;
            response.RecordsTotal = query.Count();

            // sorting
            query = query.OrderBy(string.Join(",", request.Order.Select(o => o.ToExpression(request))));

            // search
            if (request.Search != null && !string.IsNullOrEmpty(request.Search.Value))
            {
                query = query.Where(request.Search.ToExpression(request));
            }

            // filtering


            // Counting results
            response.RecordsFiltered = query.Count();

            // Returning page (subset of filtered records)
            if (request.Start.HasValue && request.Start.Value > 0)
                query = query.Skip(request.Start.Value);
            if (request.Length.HasValue && request.Length.Value >= 0)
                query = query.Take(request.Length.Value);
            return response;
        }

        private static void SetColumnData<TEntity>(DataTableRequest request, Func<TEntity, IEnumerable<string>> func)
        {
            SetColumnData(request, func(default(TEntity)).ToArray());
        }

        private static void SetColumnData(DataTableRequest request, params string[] fields)
        {
            for (int index = 0; index < fields.Length && index < request.Columns.Count; index++)
            {
                var fieldIndex = 0;
                if (int.TryParse(request.Columns[index].Data, out fieldIndex))
                    request.Columns[index].Data = fields[fieldIndex];
            }
        }
    }
}

The previous code takes advantage Dynamic LINQ to compute queries, and using as input the request information. With the previous code in place, we can use in our Controller the following code:

using DataTableSample.Services;
using DataTables.Models;
using DataTableSample.Models;
using System.Linq.Dynamic;
using DataTables.Extensions;

namespace DataTableSample.Controllers
{
    public class EmployeesController : ApiController
    {
        private CompanyModel db = new CompanyModel();

        // GET: api/Employees
        public async Task<IHttpActionResult> GetEmployees([FromUri]DataTableRequest request)
        {
            var isUsingArrayOfArrays = request.Columns.Where(c => { var n = 0; return int.TryParse(c.Data, out n); }).Any();
            var response = isUsingArrayOfArrays
                ? db.Employees.AsNoTracking().AsQueryable().GetDataTableResponse(request, GetEntityFieldNames, GetEntityAsEnumerable)
                : db.Employees.AsNoTracking().AsQueryable().GetDataTableResponse(request)
                ;
            return Json(response);
        }

        /// <summary>
        /// Converts the Entity to a sequence of values (an Array)
        /// </summary>
        /// <param name="e"></param>
        /// <returns></returns>
        private System.Collections.IEnumerable GetEntityAsEnumerable(Employee e)
        {
            yield return e.FirstName;
            yield return e.LastName;
            yield return e.Position;
            yield return e.Office;
            yield return e.StartDate;
            yield return e.Salary;
        }

        /// <summary>
        /// Provides the name of the Columns used in the Array
        /// </summary>
        /// <param name="e"></param>
        /// <returns></returns>
        private IEnumerable<string> GetEntityFieldNames(Employee e)
        {
            yield return nameof(e.FirstName);
            yield return nameof(e.LastName);
            yield return nameof(e.Position);
            yield return nameof(e.Office);
            yield return nameof(e.StartDate);
            yield return nameof(e.Salary);
        }
    }
}

The last portion of code is

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.9/css/jquery.dataTables.min.css" />
    <meta charset="utf-8" />
</head>
<body>
    <h1>Using Objects</h1>
    <table id="example1" class="display" cellspacing="0" style="width:100%;">
        <thead>
            <tr>
                <th>First name</th>
                <th>Last name</th>
                <th>Position</th>
                <th>Office</th>
                <th>Start date</th>
                <th>Salary</th>
            </tr>
        </thead>
        <tfoot>
            <tr>
                <th>First name</th>
                <th>Last name</th>
                <th>Position</th>
                <th>Office</th>
                <th>Start date</th>
                <th>Salary</th>
            </tr>
        </tfoot>
    </table>
    <h1>Using Arrays</h1>
    <table id="example2" class="display" cellspacing="0" style="width:100%;">
        <thead>
            <tr>
                <th>First name</th>
                <th>Last name</th>
                <th>Position</th>
                <th>Office</th>
                <th>Start date</th>
                <th>Salary</th>
            </tr>
        </thead>
        <tfoot>
            <tr>
                <th>First name</th>
                <th>Last name</th>
                <th>Position</th>
                <th>Office</th>
                <th>Start date</th>
                <th>Salary</th>
            </tr>
        </tfoot>
    </table>
</body>
</html>
<script src="Scripts/jquery-1.7.js"></script>
<script src="Scripts/DataTables/jquery.dataTables.js"></script>
<script type="text/javascript">
    $(document).ready(function () {
        $('#example1').DataTable({
            "processing": true,
            "serverSide": true,
            "ajax": "api/Employees",
            "columns": [
                { "data": "FirstName" },
                { "data": "LastName" },
                { "data": "Position" },
                { "data": "Office" },
                { "data": "StartDate" },
                { "data": "Salary" }
            ]
        });

        $('#example2').DataTable({
            "processing": true,
            "serverSide": true,
            "ajax": "api/Employees"
        });
    });
</script>

By running the application the two tables will be populated, one of them will be using Array of Arrays and the second will be using an Array of objects.

The full source code can be downloaded from:
https://github.com/hmadrigal/playground-dotnet/tree/master/MsWebApi.DataTables

Cheers,
Herb

Advertisements

Generating like-JIRA tickets using Entity Framework (EF6) and MS SQL (TSQL)


The problem

We have a Master/Detail relationship with two entities, and we want to identify detail records by using a friendly ID. The friendly ID is based on a master code (which it is specified in the Master Table) and a Detail Number (which works like a counter on each given master code). For example

Master Table ( When IsAutoGen is 1, then Details should auto generate an friendly ID using the AutoGenPrefix)

Id          IsAutoGen AutoGenPrefix
----------- --------- -------------
1           1         GRPA
2           1         GRPB
5           0         NULL

Detail table AutoGenPreix-AutoGenNumber identify uniquely each ticket by providing a friendly-auto-Incremental Id.

Id          MasterId    AutoGenPrefix AutoGenNumber
----------- ----------- ------------- -------------
361         1           GRPA          1
362         2           GRPB          1
363         5           NULL          1
364         1           GRPA          2
365         2           GRPB          2
366         5           NULL          2
367         1           GRPA          3
368         2           GRPB          3

Remarks

Certainly this problem may have many different solutions. For example it is technically possible to do all the computations only using C# and Entity Framework, thread locks and database transactions to support concurrency. However by doing it so, the developer will be responsible for dealing with concurrency, it will lock the database for longer periods since changes happens at business logic layer. Thus, this approach attempts to delegate the concurrency handling task to the database engine and reduce the lock time when possible. This solution is very particular to Entity Framework and Microsoft SQL, although ORMs and Triggers are concepts available in most of the platforms nowadays.

The solution

Just in case, you have skipped the test before, I encourage you to read the remarks. That said, First lets create our sample tables by using the following T-SQL script:

CREATE TABLE [dbo].[Master] (
    [Id]            INT         IDENTITY (1, 1) NOT NULL,
    [IsAutoGen]     BIT         CONSTRAINT [DF_Master_IsAutoGen] DEFAULT ((0)) NOT NULL,
    [AutoGenPrefix] VARCHAR (5) NULL,
    CONSTRAINT [PK_Master] PRIMARY KEY CLUSTERED ([Id] ASC)
);
GO
CREATE TABLE [dbo].[Detail] (
    [Id]            INT         IDENTITY (1, 1) NOT NULL,
    [MasterId]      INT         NOT NULL,
    [AutoGenPrefix] VARCHAR (5) NULL,
    [AutoGenNumber] INT         NULL,
    CONSTRAINT [PK_Detail] PRIMARY KEY CLUSTERED ([Id] ASC),
    CONSTRAINT [FK_Detail_Master] FOREIGN KEY ([MasterId]) REFERENCES [dbo].[Master] ([Id])
);
GO

As simple as two tables, in order to establish a master-detail relationship. Now with the same ease, lets see the suggested trigger:

CREATE TRIGGER  [dbo].[Insert_Detail_ReadableId]
ON [dbo].[Detail]
INSTEAD OF INSERT
AS
BEGIN
   SET NOCOUNT OFF;
	INSERT INTO [Detail] ([MasterId],[AutoGenPrefix], [AutoGenNumber])
	SELECT 
		I.[MasterId] AS [MasterId],
		M2.AutoGenPrefix AS [AutoGenPrefix],
		ISNULL(ROW_NUMBER() OVER(ORDER BY I.[Id]) + M.[AutoGenNumber],1) AS [AutoGenNumber]
	FROM INSERTED  I
	LEFT JOIN [Master] M2 ON I.[MasterId] = M2.[Id]
	LEFT JOIN (
		SELECT 
			[MasterId],
			MAX(ISNULL([AutoGenNumber],0)) AS [AutoGenNumber]
		FROM [AutoGenDB].[dbo].[Detail]
		GROUP BY [MasterId]
	) M ON I.[MasterId] = M.[MasterId]

	SELECT [Id] FROM [Detail] WHERE @@ROWCOUNT > 0 AND [Id] = SCOPE_IDENTITY();
END

Notice that the trigger is responsible of performing the INSERT since it has been configured to be INSTEAD OF INSERT. The triggers uses the INSERTED variable to hold a table with all the records that should have been inserted. Thus the application performs a INSERT INTO using as data source the INSERTED table, the inserted max AutoGenNumber per AutoGenPrefix and a row number to be added to the Max AutoGenNumber.
Pay attention to the last line, which returns the inserted ID, this is required by Entity Framework to detect as successful the INSERT operation (see StackOverflow | OptimisticConcurrencyException — SQL 2008 R2 Instead of Insert Trigger with Entity Framework or StackOverflow | error when inserting into table having instead of trigger from entity data framework )

This is all we need in the TSQL level. Every time we attempt to INSERT a new record, right after the INSERT request, our code will perform the inserted by computing some additional data.

In our C# code, I’ll assume we’re using an EDMX file and using DB first approach. Thus, we usually only update our DbContext by updating our models from Visual Studio (VS).

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AutoGenDB
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var context = new AutoGenDB.AutoGenDBEntities())
            {
                // if master table is empty, then it inserts some master records.
                if (!context.Masters.Any())
                {
                    for (int masterIndex = 0; masterIndex < 5; masterIndex++)
                    {
                        var isAutoGenEnabled = masterIndex % 2 == 0;
                        var newMaster = new Master { IsAutoGen = isAutoGenEnabled, AutoGenPrefix = isAutoGenEnabled ? "GRP" + Convert.ToChar((masterIndex % 65) + 65) : default(string) };
                        context.Masters.Add(newMaster);
                    }
                    context.SaveChanges();
                }

                // Inserts some details on different groups
                List<Detail> details = new List<Detail>();
                List<Master> masters = context.Masters.AsNoTracking().ToList();
                for (int i = 0; i < 100; i++)
                {
                    var masterId = masters[i % masters.Count].Id;
                    details.Add(new Detail() { MasterId = masterId });
                }
                context.Details.AddRange(details);
                context.SaveChanges();

                // Prints 10 auto generated IDS
                foreach (var master in context.Masters.AsNoTracking().Take(3))
                    foreach (var detail in master.Details.Take(5))
                        Console.WriteLine(master.IsAutoGen ? "Ticket:{0}-{1}" : @"N/A", detail.AutoGenPrefix, detail.AutoGenNumber);
            }
            Console.ReadKey();
        }
    }
}

The previous C# code inserts some records and prints the information generated by the Trigger. At this point there is only one missed component.
If we run the code as it is. The application won’t load the auto generated values, this is because Entity Framework does not know that these columns were populated. An option is to instruct Entity Framework about when it should reload the entities. The following code, decorates the Detail class with an IDetail interface which can be used in the DbContext to identify the entity type that should be reloaded.

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AutoGenDB
{
    interface IDetail
    {
        int? AutoGenNumber { get; set; }
        string AutoGenPrefix { get; set; }
        int Id { get; set; }
        Master Master { get; set; }
        int MasterId { get; set; }
    }

    public partial class AutoGenDBEntities : DbContext
    {
        public override int SaveChanges()
        {
            var entriesToReload = ChangeTracker.Entries<IDetail>().Where(e => e.State == EntityState.Added).ToList();
            int rowCount = base.SaveChanges();
            if (rowCount > 0 && entriesToReload.Count > 0)
                entriesToReload.ForEach(e => e.Reload());
            return rowCount;
        }

    }

    public partial class Detail : AutoGenDB.IDetail
    {

    }
}

Please notice how the subclass of the DbContext is overriding the SaveChanges method in order to request to reload the instances of IDetail. Reloading entities may or may not be desirable in depending on the application.
With these overrides, the DbContext will know when a given entity should be reloaded.

As usual the code sample can be check at https://github.com/hmadrigal/playground-dotnet/tree/master/MsDotNet.EntityFrameworkAndTriggers

Pivot ( or Panorama ) Index Indicator


Hello,

The Problem:

Creating a pivot (or panorama) indicator could be a challenging task. The control should:

  • Indicate in which item of the collection you are looking at
  • Let you tap on a given item and navigate in the panorama to that given item
  • Let you customize the look and feel of the items.

The Solution: A Second thought

Sounds like the perfect scenario for a custom control, and in some of the cases it is. However, after some minutes thinking about this idea, I realized that the ListBox supports most of these requirements but only one pending task: it has to interact properly with the Panorama or Pivot.  Thus, the current solution uses a ListBox (Custom Styles and Templates) for modifying the look and file, and prepares a behavior (more specifically a TargetedTriggeredAction<T1,T2> ) for letting the ListBox interact with a index based collection (e.g. Pivot, Panorama, ListBox, etc … ).

A behavior …  (What’s that?)

Well with XAML a bunch of new concepts arrived to .NET development world. One in particular which is very useful is a behavior . You can think about a behavior like a encapsulated functionality that can be reused on different context under the same type of items.  The most popular behavior i guess it is EventToCommand which can be applied to any FrameworkElement and it maps the Loaded Event to a Command when implementing a View Model.

Thus, since We have a ListBox already in place, we only want it to behave synchronized with a Pivot or Panorama. Thus, the external control will be a parameter for our behavior.

    [TypeConstraint(typeof(Selector))]
    public class SetSelectedItemAction : TargetedTriggerAction
    {
        private Selector _selector;

        protected override void OnAttached()
        {
            base.OnAttached();

            _selector = AssociatedObject as Selector;
            if (_selector == null)
                return;
        }

        protected override void OnDetaching()
        {
            base.OnDetaching();
            if (_selector == null)
                return;
            _selector = null;
        }

        protected override void Invoke(object parameter)
        {
            if (_selector == null)
                return;

            if (Target is Panorama)
                InvokeOnPanorama(Target as Panorama);
            if (Target is Pivot)
                InvokeOnPivot(Target as Pivot);
            if (Target is Selector)
                InvokeOnSelector(Target as Selector);
        }

        private void InvokeOnSelector(Selector selector)
        {
            if (selector == null)
                return;
            selector.SelectedIndex = _selector.SelectedIndex;
        }

        private void InvokeOnPivot(Pivot pivot)
        {
            if (pivot == null)
                return;
            pivot.SelectedIndex = _selector.SelectedIndex;
        }

        private void InvokeOnPanorama(Panorama panorama)
        {
            if (panorama == null)
                return;
            panorama.DefaultItem = panorama.Items[_selector.SelectedIndex];
        }

The idea is that you should be able to sync other elements by just dropping this behavior on a ListBox and setting up few properties, for example:

<ListBox
            x:Name="listbox"
			HorizontalAlignment="Stretch" Margin="12" VerticalAlignment="Top"
            SelectedIndex="{Binding SelectedIndex,ElementName=panorama,Mode=TwoWay}"
            ItemsSource="{Binding PanoramaItems}"
            ItemsPanel="{StaticResource HorizontalPanelTemplate}"
            ItemContainerStyle="{StaticResource ListBoxItemStyle1}"
            ItemTemplate="{StaticResource IndexIndicatorDataTemplate}"
            >
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="SelectionChanged">
                    <local:SetSelectedItemAction TargetObject="{Binding ElementName=panorama}"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </ListBox>

The behaviors can take more responsibility other than keep sync the selected item in one way. However my design decision was to use other mechanisms for keeping sync the indexes. (e.g. you could appreciate a TwoWay binding using SelectedIndex Property of the Target Pivot or Panorama).

Also, the ListBox has bound a list of items (empty items) just for being able to generate as much items as the Panorama has. This is other logic that may be moved to the behavior (however in my two previous attempts it didn’t work that well).

Here is the code sample, of this simple behavior and how ti keeps sync with the Panorama.

https://github.com/hmadrigal/playground-dotnet/tree/master/MsWinPhone.ParanoramaIndex

The following screenshot shows an indicator in the top/left corner where you can see the current tab of the Panorama that is being shown. Moreover, the user can tap on a given item to get directly to that selected tab.

Panorama_Index_Indicator

Cheers
Herb

Custom Configuration files in .NET


Hi,

I would like to share some ideas about how to deal with configuration files on .NET. I am sure that there should be many options for implementing configuration files. Some are more likely to better than others and others may depend on the platform (e.g. mobile, desktop, cloud, etc..)  In particular I’ll explain an approach that should be working for your Web Application and for your Desktop application.

The problem:

We want to quickly create a configuration file, since we foresee that our application will have a good amount of settings.

Solution:

I’ll take advantage of the default .NET mechanism for configuration files. It’s plenty flexible and quite extensible. The major drawback is that you’ll have to write code, and sometimes a not-so-easy code. Alternatively you can relay on the existent section handlers, and try to use them when possible.

A brief talk about configuration files

.NET configuration files supports hierarchies and they are extensible. Almost all the cases with defaults is fairly enough, for creating custom sections there I will be explaining three approaches, but certainly there are more. The decision of which approach to take it will depend of how much time you have and also if the team has the will and chance for installing at least the Configuration Section Designer. 

1) Create Custom Section Handler with Code Snippets

This is the simplest one, it’s basically get code snippets of how to create sections for the SectionHandler class. Then you are more likely to have many property of similar times (probably primitive types) but it can safe time for producing the class and understand it. I won’t be providing samples for this.

2) Using the Custom Section Designer from CodePlex at https://csd.codeplex.com/

This is my favorite, but unfortunately it demands that you will have to install a Visual Studio Extension for opening configuration section projects. The best of this approach is that you can get:

  • XSD validation + intelisense
  • XSD Documentation
  • Ease to modify content.
  • etc…

First get proper installer for the extension https://csd.codeplex.com/. Then create a configuration section project (these projects outputs a dll), by conversion these projects end with “.Configuration” for example “MyApp.Configuration” will be dll project that loads the configuration section. In our sample it is provided a project called: ConfigurationFileSample.Configuration

Image

The previous screenshot exemplifies a Section in which it has been defined a Element called Mappings, which is a collection of Mapping elements. By following the instructions at https://csd.codeplex.com/wikipage?title=Defining%20new%20types&referringTitle=Usage you will easily create this configuration. The magic arrive when you are typing these values into visual studio (or any XML editor that supports XSD validation property).

Once you are done designing your configuration file. You save and compile. If it success then add a configuration file to your main project, and also add a reference to the configuration file project. for referencing our custom section we do it into the configSections element. For example:


<!-- NOTE: In here a custom section is specified, this section has been created by writing code--></pre>
<section></section>
<pre>

Visual studio will enable help toltips and XSD validation for you. As you can see in the following screenshot

ConfigurationTooltip

For loading configuration files in code, after adding the reference to the dll, the app can use an static helper of simply use the GetSection method.

For example for loading the section using the default instance:

// NOTE: It is also possible to load the default custom section
Console.WriteLine("\nLoading default Minestrone thru singleton!");
var minestroneSection = Minestrone.MinestroneSection.Instance;
PrintMinestrone(minestroneSection);

Or also you could load a specific section:

// NOTE: You could ask for a given custom section
Console.WriteLine("\nLoading Minestrone by manually specifying a section: minestroneSection");
var minestroneSection = ConfigurationManager.GetSection("minestroneSection") as Minestrone.MinestroneSection;
PrintMinestrone(minestroneSection);

3) Using one of the build in Section Handlers
As I mentioned you also could you the built-in Sectionhandlers from .NET framework There is a list of them at the end of this page: http://msdn.microsoft.com/en-us/library/system.configuration.configurationsection.aspx (basically all the subclasses of System.Configuration.ConfigurationSection )

For example for referencing it into the configuration file:


    <!-- NOTE:This custom section uses .NET framework sections instead, see http://msdn.microsoft.com/en-us/library/system.configuration.configurationsection.aspx for a list of the classes available into the framework --></pre>
<section></section>
<pre>

and for loading it from code:

// NOTE: Loads a custom section, but it uses a .NET built-in class
            Console.WriteLine("\nLoading a ApplicationSettings using a built-in .NET type. (more at http://msdn.microsoft.com/en-us/library/system.configuration.configurationsection.aspx ) ");
            var myConfigSection = ConfigurationManager.GetSection("myConfigSection") as System.Collections.Specialized.NameValueCollection;
            for (int appSettingIndex = 0; appSettingIndex < myConfigSection.Count; appSettingIndex++)
            {
                Console.WriteLine(string.Format("Key:{0} Value:{1}", myConfigSection.AllKeys[appSettingIndex], myConfigSection[appSettingIndex]));
            }
            Console.WriteLine("\n\n PRESS ANY KEY TO FINISH! ");
            Console.ReadKey();

We are almost there, but WAIT!!!!

I know that at this time I haven’t shown how to specify section. Well basically because you can provide the details of the section inline into the same file or specifcying an external file using the configSource attribute (which is available for any custom section).

For example see how the minestroneSection is defined in an external file, and how myConfigSection  is written inline into the configuration file. There are advantages of each approach (e.g. when you want to apply XSLT transformations you may want to apply transformations to a simple file rather than a long and complex XML) o perhaps you may have a config file per environment (e.g. minestrone.debug.config…,)

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <!-- NOTE: In here a custom section is specified, this section has been created by writing code-->
    <section name="minestroneSection" type="Minestrone.MinestroneSection, ConfigurationFileSample.Configuration, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>

    <!-- NOTE:This custom section uses .NET framework sections instead, see http://msdn.microsoft.com/en-us/library/system.configuration.configurationsection.aspx for a list of the classes available into the framework -->
    <section name="myConfigSection" type="System.Configuration.AppSettingsSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />

  </configSections>
  <myConfigSection>
    <add key ="ALPHA" value="1|1"/>
    <add key ="BETA" value="1|1"/>
    <add key ="GAMA" value="1|1"/>
  </myConfigSection>

  <!-- NOTE: Loading section from a external file-->
  <minestroneSection configSource="minestroneSection.config" />

  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
</configuration>

I hope this is good enough for setting up quickly custom configuration files in your .NET projects.
The sample is at https://github.com/hmadrigal/playground-dotnet/tree/master/MsDotNet.CustomConfigFile and please remember to install the Custom Section Designer if you want to take the option for more detailed configuration file.

Regards,
Herber

Previewing Microsoft Office Documents and PDF in WPF using a Preview Handler Host


Hi,

I had recently to implement a mechanism for showing documents into a WPF application. The very first solution was to start a new process using the path of the selected file. The only condition for this to work it’s that the file extension should have been previously registered to be opened with an specific application. A drawback is that the document is shown by an external application that we are not able to handle (at all or at least easily).

Then the client decided showing documents by embedding them into the application. So, I started researching about how to display Portable documents, Word documents, Excel documents into a WPF application. Finally after some research I got to a nice solution which will display many documents formats with the only condition of having the proper software installed into the PC where the application is gonna run.

The Problem
Showing a office document (XLS, DOC, XLSX, DOCX) or portable document (PDF) into a WPF APP.

Remarks
This is not a bullet proof solution, but it is kind extensible for brave developers. The relays on the installed Preview Handlers. For example for visualizing Microsoft Office documents you will have to have installed Microsoft Office in the computer where the application is going to run. It’s the same case for PDF files, where you need to have a Preview Handler installed.
Moreover, the technology of Preview Handler has been built using native code, in order to embedded into a WPF application the app will be hosting WinForm content, this introduces a different set of restrictions about the interaction of the control once it has been instantiated.

The Solution
Preview Handlers is a technology added into Windows Vista, and it’s meant to readonly quick preview of files. It’s available on Windows Explorer
Enabling Previews in Windows Vista Folders
The Microsoft article [1] about Preview Handlers has an utility application which lists the available preview handlers in your system. Moreover after some research, I found the first implementation in [2] which was using Windows Forms and C# for development. Finally I found a more elaborated solution from Coding4Fun [3]. Since this point the solution for WPF was straightforward because it was only matter of loading a WinForm contro into WPF by using Interop components.

1) Grab the code from http://c4fdevkit.codeplex.com/ project. To use the Preview Handler Host you will need only two projects.
/Preview Handlers/Source/VCS/PreviewHandlerFramework
/Preview Handlers/Source/VCS/PreviewHandlerHost

Compile them and the create a new WPF project. The codeplex project hasn’t been updated in awhile, thus you’re more likely to have to update the solution file to a new version of visual studio.

2) Add to your WPF application (or library) a reference to WindowsFormIntegration library. This will allow the application to host WinForm controls. Also add System.Windows.Forms since it will be required by the Preview Handler libraries.

3) The use the WindowsFormsHost tag to embed the PreviewHandlerHostControl as the follwing XAML shows:


        <button></button>

            <C4F_DevKit_PreviewHandler_PreviewHandlerHost:PreviewHandlerHostControl x:Name="previewHandlerHostControlInstance" />

4) Finally our C# code that for our sample is quite simple. We just select a file and let the PreviewHandlerHost control do the work.

using System;
using System.Windows;

namespace PreviewHandlerWpfApplication
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            var dlg = new Microsoft.Win32.OpenFileDialog();
            if (dlg.ShowDialog().Value)
            {
                previewHandlerHostControlInstance.FilePath = dlg.FileName;
            }
        }
    }
}

Here is an screenshot of my mighty document viewer:

Sample.Word.Document.Capture

Finally the code is available at GitHub https://github.com/hmadrigal/playground-dotnet/tree/master/MsDesktop.PreviewHandlers Have fun!

References

 

 

Adding a static reference into a unity configuration file


Hi,

I’d like to talk about how you can set up your unity configuration file to resolve static references. This is handy depending of the context, for example you would like to register the Path Separator of the file system. This if you’re on unix-based system it’s more likely to be “/” and if you are on a Windows-based system it’s going to be “\”. Certainly you could use configuration files, for this purpose, this is just an alternative where you could let you application know about specific values without knowing they’re coming from, and you usually do this for test-ability.

For those who does not have enough patience, the source code is at https://github.com/hmadrigal/playground-dotnet/tree/master/MsUnity.TypeConverters

The problem

I’d like to set my Unity Container to take the value from a static field, so I do not have to write code to set up a the container in code and in the configuration file.

 

The Solution

Unity Container is very flexible and moreover extensible. It takes advantage of a pattern called “TypeConverter”, which basically it’s an specialized class which maps from one type to another. Particularly in our case we will be mapping from System.string value to any valid static value by using reflection.

Type converters are used along .NET framework, here is a quick guide of How to: Implement a Type Converter:
http://msdn.microsoft.com/en-us/library/ayybcxe5.aspx

In our case, we will assume that we’re receiving a value of type string which follows the following format:

{member}@{assemblyQualifiedName}

Then, we can reference static fields by using the following syntax:

Version@System.Environment, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

The type converter class that does this work is the following:

 

using System;
using System.ComponentModel;
using System.Reflection;

namespace EntLibUnity.Extensions
{
    /// <summary>
    /// Converts an (formatted) string to a reference of a given static member.
    /// The string uses this format: {member}@{assemblyQualifiedName}
    /// For example:
    ///     Version@System.Environment, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
    /// </summary>
    public class StringToStaticInstanceTypeConverter : TypeConverter
    {
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            return (typeof(string) == sourceType) || base.CanConvertFrom(context, sourceType);
        }

        public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
        {
            string stringValue;
            if (value == null
                || (stringValue = value as string) == null
                || string.IsNullOrEmpty(stringValue)
                || !stringValue.Contains("@")
            )
            {
                return null;
            }

            var stringParts = stringValue.Split('@');
            if (stringParts.Length != 2)
            {
                return null;
            }
            var propertyPath = stringParts[0];
            var propertyPathParts = propertyPath.Split('.');
            var assemblyQualifiedName = stringParts[1];
            // Gets the static member
            var currentClassType = Type.GetType(assemblyQualifiedName, true);
            var currentPropertyInfo = currentClassType.GetProperty(propertyPathParts[0],
                                                                 BindingFlags.Public | BindingFlags.Static |
                                                                 BindingFlags.FlattenHierarchy);
            var currentPropertyValue = currentPropertyInfo.GetValue(null, null);
            // Loops into the path to get a value
            for (var i = 1; i < propertyPathParts.Length; i++)
            {
                currentPropertyInfo = currentClassType.GetProperty(propertyPathParts[i]);
                currentPropertyValue = currentPropertyInfo.GetValue(currentPropertyValue, null);
            }
            return currentPropertyValue ?? base.ConvertFrom(context, culture, value);
        }
    }
}

The second step is to configure our container to recognize the TypeConverter and use it when needed. This is simple, when we’re registering types in the configuration file we have the option of specifying a type converter as you can see in the following sample:

<?xml version="1.0" encoding="utf-8" ?>
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
  <!-- Using Design-Time Configuration: http://msdn.microsoft.com/en-us/library/ff660935(v=PandP.20).aspx#format_config -->
  <!-- The Unity Configuration Schema: http://msdn.microsoft.com/en-us/library/ff660914(v=PandP.20).aspx -->
  <!-- Specifying Types in the Configuration File http://msdn.microsoft.com/en-us/library/ff660933(v=PandP.20).aspx#_Default_Aliases_and-->

  <!-- Setting an alias for our TypeConverter, to prevent using the full type reference -->
  <alias alias="StringToStaticInstanceTypeConverter" type="EntLibUnity.Extensions.StringToStaticInstanceTypeConverter, EntLibUnity.Extensions" />

  <alias alias="IVersionManager" type="EntLibUnity.Infrastructure.IVersionManager, EntLibUnity.UnitySample.ConsoleApp" />
  <alias alias="VersionManager" type="EntLibUnity.UnitySample.VersionManager, EntLibUnity.UnitySample.ConsoleApp" />

  <!-- Default (unnamed) container-->
  <container>
    <register type="IVersionManager" mapTo="VersionManager">
      <constructor>
        <param name="version">
          <!-- In this case we use the expanded version of Param and set the proper typeConverter attribute-->
          <value value="Version@System.Environment, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" typeConverter="StringToStaticInstanceTypeConverter" />
        </param>
      </constructor>
    </register>
  </container>

</unity>

Simple ;-). Finally we only have to use our container as we usually use it. In my case I’ve some extensions to load and configure the container, you can check them by downloading the source code.
Here is the final code of our main application:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Unity;
using EntLibUnity.Extensions;
using EntLibUnity.Infrastructure;

namespace EntLibUnity.UnitySample.ConsoleApp
{
    class Program
    {
        private static IUnityContainer container;

        static void Main(string[] args)
        {
            container =
                new UnityContainer()
                .LoadContainerFromSection()
                .LoadEnterpriseLibraryTypes();

            var versionManager = container.Resolve<IVersionManager>();
            Console.WriteLine(versionManager.Version);
            Console.ReadKey();
        }
    }
}

The source code is at https://github.com/hmadrigal/playground-dotnet/tree/master/MsUnity.TypeConverters

Your comments are welcome,
kind regards,
Herber

Automatic retries using the Transient Fault Handling from Enterprise libraries (EntLib)


Hello,

I was reading about the Transient Fault Handling at http://msdn.microsoft.com/en-us/library/hh680901(v=pandp.50).aspx This is a block of the Enterprise Libraries which is part of the Enterprise Integration Pack for Windows Azure. I haven’t played much with Azure yet, but one part of the documentation took my attention:

When Should You Use the Transient Fault Handling Application Block?
…… (some explanation about when you are using Azure services) ……
You Are Using a Custom Service
If your application uses a custom service, it can still benefit from using the Transient Fault Handling Application Block. You can author a custom detection strategy for your service that encapsulates your knowledge of which transient exceptions may result from a service invocation. The Transient Fault Handling Application Block then provides you with the framework for defining retry policies and for wrapping your method calls so that the application block applies the retry logic.Source: http://msdn.microsoft.com/en-us/library/hh680901(v=pandp.50).aspx#sec10

So, I thought why do I have to write always the retry logic if this is already done ;-).

The problem

We want to write a generic retry mechanism for our application. Moreover we need to support some level of customization thru configuration files.

The solution
Simple let set up the Transient Fault Handling Block (from now on FHB). First of fall you will have to download the libraries, you could do it using NuGet – which by default adds also references to support Windows Azure -. You can remove the Windows Azure DLL if you’re not going to be using Windows Azure in your app.

The FHB lets you specify a error detection strategy as well as retry strategy when you construct the retry policy. Also, a Retry policy support the execution of Action, Funcdelegates or Actionfor async retries.

As part of the configuration process for FHB, it’s required to indicate which errors should be handled by FHB. A mechanism for doing this is by implementing the interface: ITransientErrorDetectionStrategy. In our sample, we only want to retry when a FileNotFoundException is thrown. Thus we have coded the FileSystemTransientErrorDetectionStrategy:

using System;
using System.IO;
using Microsoft.Practices.TransientFaultHandling;

namespace SampleConsoleApplication.TransientErrors.Strategies
{
    public class FileSystemTransientErrorDetectionStrategy : ITransientErrorDetectionStrategy
    {
        #region ITransientErrorDetectionStrategy Members

        public bool IsTransient(Exception ex)
        {
            return ex is FileNotFoundException;
        }

        #endregion
    }
}

Certainly you could implement it by handling any particular exception.
Now we need to define a retry policy. This is done by specifying a retry strategy. The following code example configures a retry policy by providing a retry strategy incremental. Additionally in our sample service.DoSlowAndImportantTask will always fail, so the FHB will retry automatically based on the retry policy.

 private static void RetryPolityUsingCode(IUnityContainer container, IService service, OutputWriterService writer)
        {
            writer.WriteLine("Begin sample: RetryPolityUsingCode");
            // Define your retry strategy: retry 5 times, starting 1 second apart
            // and adding 2 seconds to the interval each retry.
            var retryStrategy = new Incremental(5, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2));

            // Define your retry policy using the retry strategy and the Windows Azure storage
            // transient fault detection strategy.
            var retryPolicy = new RetryPolicy(retryStrategy);

            try
            {
                // Do some work that may result in a transient fault.
                retryPolicy.ExecuteAction(service.DoSlowAndImportantTask);
            }
            catch (Exception exception)
            {
                // All the retries failed.
                writer.WriteLine("An Exception has been thrown:\n{0}", exception);
            }
            writer.WriteLine("End sample: RetryPolityUsingCode");
        }

Additionally it’s possible to specify the retry policy in the configuration file, for example:

<!--?xml version="1.0" encoding="utf-8" ?-->

<section name="RetryPolicyConfiguration" type="Microsoft.Practices.EnterpriseLibrary.WindowsAzure.TransientFaultHandling.Configuration.RetryPolicyConfigurationSettings, Microsoft.Practices.EnterpriseLibrary.WindowsAzure.TransientFaultHandling" requirepermission="true"></section><section name="typeRegistrationProvidersConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Common.Configuration.TypeRegistrationProvidersConfigurationSection, Microsoft.Practices.EnterpriseLibrary.Common"></section>

Please notice that there is a default Retry Strategy indicating that will use “Fixed Interval Retry Strategy”. Our C# code will ask for the RetryManager instance in order to retrieve the Retry Policy and then perform the task.

private static void RetryPolityUsingConfigFile(IUnityContainer container, IService service, OutputWriterService writer)
        {
            writer.WriteLine("Begin sample: RetryPolityUsingConfigFile");
            // Gets the current Retry Manager configuration
            var retryManager = EnterpriseLibraryContainer.Current.GetInstance();

            // Asks for the default Retry Policy. Keep on mind that it's possible to ask for an specific one.
            var retryPolicy = retryManager.GetRetryPolicy();
            try
            {
                // Do some work that may result in a transient fault.
                retryPolicy.ExecuteAction(service.DoSlowAndImportantTask);
            }
            catch (Exception exception)
            {
                // All the retries failed.
                writer.WriteLine("An Exception has been thrown:\n{0}", exception);
            }
            writer.WriteLine("End sample: RetryPolityUsingConfigFile");
        }

The Transient Fault Handling Block a simple and flexible alternative for a well-known task. A automatic retry system, moreover this supports configuration file, so we should be able to change the retry policy just by modifying our configuration file.

Here is an screen shot of the app, which automatically retries calling our mischievous method.

Transient Fault Handling Tries Output Capture

As usual the code sample is at https://github.com/hmadrigal/playground-dotnet/tree/master/MsEntLib.TransientErrorHandling