Development With A Dot

Blog on development in general, and specifically on .NET

  • Entity Framework Pitfalls – Date/Time Operations

    When using Entity Framework, you cannot perform date/time operations as you would normally do in .NET/LINQ to Objects. For instance, the following query throws an exception:

       1: ctx.Projects.Select(x => new { ElapsedTime = DateTime.Now - x.Start }).ToList();

    Instead, you need to use the static methods in SqlFunctions, like DateDiff:

       1: ctx.Projects.Select(x => new { ElapsedTime = SqlFunctions.DateDiff("HOUR", x.Start, DateTime.Now) }).ToList();

    For a full description of DateDiff’s first parameter, refer to http://msdn.microsoft.com/en-us/library/ms189794.aspx.

    If you want to achieve the same result, that is, return a TimeSpan, you need to use LINQ to Objects at the end:

       1: ctx.Projects.Select(x => new { ElapsedTime = SqlFunctions.DateDiff("HOUR", x.Start, DateTime.Now) }).ToList().Select(x => new { ElapsedTime = TimeSpan.FromHours((Double)x.ElapsedTime) }).ToList();

    Read more...

  • NHibernate 4.0

    Recently, the NHibernate team released NH 4.0. You can get it as a NuGet package from https://www.nuget.org/packages/nhibernate, as a ZIP from http://sourceforge.net/projects/nhibernate/ or as source code from https://github.com/nhibernate/nhibernate-core. The full release notes are available at https://github.com/nhibernate/nhibernate-core/blob/master/releasenotes.txt, but here are some highlights.

    One of its most important features is that it no longer needs Iesi.Collections for most common uses: where you would declare a set as Iesi.Collections.Generic.ISet<T>, now you use System.Collections.Generic.ISet<T>. However, if you want to use the order-by attribute of sets, you still need Iesi.Collections, because NHibernate will still use it (LinkedHashSet<T>). All of the public APIs that used Iesi.Collections.Generic.ISet<T> or Iesi.Collections.ISet now use System.Collections.Generic.ISet<T>, this includes all the event handler methods.

    Method SaveOrUpdateCopy of ISession was removed and Merge should be used instead.

    The ManagedWebSessionContext context class was removed and the managed_web alias for XML configuration is no longer supported. Now you should use WebSessionContext and web.

    The Firebird driver was removed and replaced for FirebirdClientDriver. ASA10ClientDriver, ASAClientDriver and SQLiteDriver were removed in favor of SybaseSQLAnywhereDriver, SybaseAsaClientDriver and SQLite20Driver, respectively. A managed ODP.NET driver for Oracle is now available (OracleManagedDataClientDriver).

    Sql2012Dialect was introduced and now properly pages records. Also added Ingres9Dialect. SybaseASADialect (use SybaseSQLAnywhere10Dialect),

    MySQL now supports batching inserts (MySqlClientBatchingBatcher).

    There have also been some breaking changes in the IProjection interface because the IEnhancedProjection interface was removed and its methods moved to IProjection.

    Misspelled class AdoNetWithDistrubtedTransactionFactory is now AdoNetWithDistributedTransactionFactory.

    NHibernate XML configuration on App.config or Web.config now accepts attribute linqtohql.generatorsregistry.

    On mapping by code, you can now specify the class of a one-to-one endpoint (IOneToOneMapper.Class) and an optional table check clause (IClassMapper.Check). Also available are enhanced id generators Enhanced Sequence (Generators.EnhancedSequence) and Enhanced Table (Generators.EnhancedTable). You can now pass a dictionary to IGeneratorMapper.Params, no need to use anonymous types, which is better for dynamic code.

    QueryOver projections now support Math.Round() to round up floating point numbers.

    DefaultIfEmpty is now supported with GroupBy and Distinct is now supported with anonymous types.

    Finally, all static type fields in NHibernateUtil are now declared as their exact type, not a base class, which is better for using in mapping by code.

    Read more...

  • ASP.NET Web Forms Extensibility: Page Parser Filters

    Introduction

    ASP.NET includes a valuable yet not well known extension point called the page parser filter. I once briefly talked about it in the context of SharePoint, but I feel a more detailed explanation is in order.

    A page parser filter is a class with a public parameterless constructor that inherits from PageParserFilter and is registered on the Web.config file, in the pages section, pageParserFilterType attribute. It is called when ASP.NET is compiling a page, the first time it is called, for every page. There can be only one page parser filter per web application.

    Parser

    Why is it a parser? Well, it parses – or, better, receives a notification for - every control declared on the markup of a page (those with runat=”server” or contained inside of), as well as all of the page’s directives (<%@ … %>). The control declarations include all of its attributes and properties, the recognized control type and any complex properties that the markup contains. This allows us to do all kinds of crazy stuff:

    • Inspect, add and remove page directives;
    • Setting the page’s compilation mode;
    • Insert or remove controls or text literals dynamically at specific places;
    • Add/change/remove a control’s properties or attributes;
    • Even (with some reflection magic) change a control’s type or tag.


    So, how do we all this? First, the parser part. We can inspect all page directives by overriding the PreprocessDirective method. This is called for all page directives:

       1: public override void PreprocessDirective(String directiveName, IDictionary attributes)
       2: {
       3:     if (directiveName == "page")
       4:     {
       5:         //make a page asynchronous
       6:         attributes["async"] = "true";
       7:     }
       8:  
       9:     base.PreprocessDirective(directiveName, attributes);
      10: }

    The page’s compilation mode is controlled by GetCompilationMode:

       1: public override CompilationMode GetCompilationMode(CompilationMode current)
       2: {
       3:     return (base.GetCompilationMode(current));
       4: }

    As for adding controls dynamically, we make use of the ParseComplete method:

       1: public override void ParseComplete(ControlBuilder rootBuilder)
       2: {
       3:     if (rootBuilder is FileLevelPageControlBuilder)
       4:     {
       5:         this.ProcessControlBuilder(rootBuilder);
       6:     }
       7:  
       8:     base.ParseComplete(rootBuilder);
       9: }
      10:  
      11: private void ProcessControlBuilder(ControlBuilder builder)
      12: {
      13:     this.ProcessControlBuilderChildren(builder);
      14:  
      15:     if (builder.ControlType == typeof(HtmlForm))
      16:     {
      17:         //add a Literal control inside the form tag
      18:         var literal = ControlBuilder.CreateBuilderFromType(null, builder, typeof(Literal), "asp:Literal", "literal", new Hashtable { { "Text", "Inserted dynamically I" } }, -1, null);
      19:         builder.AppendSubBuilder(literal);
      20:  
      21:         //add an HTML snippet inside the form tag
      22:         builder.AppendLiteralString("<div>Inserted dynamically II</div>");
      23:     }
      24: }
      25:  
      26: private void ProcessControlBuilderChildren(ControlBuilder parentBuilder)
      27: {
      28:     foreach (var builder in parentBuilder.SubBuilders.OfType<ControlBuilder>())
      29:     {
      30:         this.ProcessControlBuilderChildren(builder);
      31:     }
      32: }

    Same for changing a control’s properties:

       1: private static readonly FieldInfo simplePropertyEntriesField = typeof(ControlBuilder).GetField("_simplePropertyEntries", BindingFlags.Instance | BindingFlags.NonPublic);
       2:  
       3: private void SetControlProperty(ControlBuilder builder, String propertyName, String propertyValue)
       4: {
       5:     var properties = (simplePropertyEntriesField.GetValue(builder) as IEnumerable);
       6:  
       7:     if (properties == null)
       8:     {
       9:         properties = new ArrayList();
      10:         simplePropertyEntriesField.SetValue(builder, properties);
      11:     }
      12:  
      13:     var entry = properties.OfType<SimplePropertyEntry>().SingleOrDefault(x => x.Name == propertyName) ?? simplePropertyEntryConstructor.Invoke(null) as SimplePropertyEntry;
      14:     entry.Name = propertyName;
      15:     entry.UseSetAttribute = (builder.ControlType != null && builder.ControlType.GetProperties().Any(x => x.Name.Equals(propertyName, StringComparison.OrdinalIgnoreCase)) == false);
      16:     entry.PersistedValue = propertyValue;
      17:     entry.Value = entry.PersistedValue;
      18:     entry.Filter = String.Empty;
      19:  
      20:     if (properties.OfType<SimplePropertyEntry>().Any(x => x.Name == propertyName) == false)
      21:     {
      22:         (properties as ArrayList).Add(entry);
      23:     }
      24: }
      25:  
      26: private void ProcessControlBuilder(ControlBuilder builder)
      27: {
      28:     if (typeof(IEditableTextControl).IsAssignableFrom(builder.ControlType) == true)
      29:     {
      30:         this.SetControlProperty(builder, "Text", "Injected dynamically!");
      31:     }
      32:  
      33:     this.ProcessControlBuilderChildren(builder);
      34: }

    And even changing the control’s output tag or instance type:

       1: private static readonly FieldInfo controlTypeField = typeof(ControlBuilder).GetField("_controlType", BindingFlags.Instance | BindingFlags.NonPublic);
       2: private static readonly FieldInfo tagNameField = typeof(ControlBuilder).GetField("_tagName", BindingFlags.Instance | BindingFlags.NonPublic);
       3:  
       4: private void SetControlType(ControlBuilder builder, Type controlType)
       5: {
       6:     controlTypeField.SetValue(builder, controlType);
       7: }
       8:  
       9: private void SetTagName(ControlBuilder controlBuilder, String tagName)
      10: {
      11:     tagNameField.SetValue(controlBuilder, tagName);
      12: }
      13:  
      14: private void ProcessControlBuilder(ControlBuilder builder)
      15: {
      16:     if (builder.TagName != null)
      17:     {
      18:         this.SetTagName(builder, builder.TagName.ToUpper());
      19:     }
      20:  
      21:     if (builder.ControlType == typeof(MyControl))
      22:     {
      23:         this.SetControlType(builder, typeof(MyDerivedControl));
      24:     }
      25:  
      26:     this.ProcessControlBuilderChildren(builder);
      27: }

    Why would we want to change a control’s type? Well, thing about generics, for once.

    Filter

    And now the filtering part: why is it a filter? Because it allows us to filter and control a number of things:

    • The allowed master page, base page class and source file;
    • The allowed controls;
    • The total number of controls allowed on a page;
    • The total number of direct and otherwise references on a page;
    • Allow or disallow code and event handler declarations;
    • Allow or disallow code blocks (<%= … %>, <%: … %>, <% … %>);
    • Allow or disallow server-side script tags (<script runat=”server”>…</script>);
    • Allow, disallow and change data binding expressions (<%# … %>);
    • Add, change or remove event handler declarations.


    All of the filtering methods and properties described below return a Boolean flag and its base implementation may or may not be called, depending on the logic that we want to impose.

    Allowing or disallowing a base page class is controlled by the AllowBaseType method (the default is to accept):

       1: public override Boolean AllowBaseType(Type baseType)
       2: {
       3:     return (baseType == typeof(MyBasePage));
       4: }

    For master pages, user controls or source files we have the AllowVirtualReference virtual method (again, the default is true):

       1: public override Boolean AllowVirtualReference(String referenceVirtualPath, VirtualReferenceType referenceType)
       2: {
       3:     if (referenceType == VirtualReferenceType.Master)
       4:     {
       5:         return (referenceVirtualPath == "AllowedMaster.Master");
       6:     }
       7:     else if (referenceType == VirtualReferenceType.UserControl)
       8:     {
       9:         return (referenceVirtualPath != "ForbiddenControl.ascx");
      10:     }
      11:  
      12:     return (base.AllowVirtualReference(referenceVirtualPath, referenceType));
      13: }

    Controls are controlled (pun intended) by AllowControl, which also defaults to accept:

       1: public override Boolean AllowControl(Type controlType, ControlBuilder builder)
       2: {
       3:     return (typeof(IForbiddenInterface).IsAssignableFrom(controlType) == false);
       4: }

    This may come in handy to disallow the usage of controls in ASP.NET MVC ASPX views!

    The number of controls and dependencies on a page is defined by NumberOfControlsAllowed, NumberOfDirectDependenciesAllowed and TotalNumberOfDependenciesAllowed. Interesting, the default for all these properties is 0, so we have to return –1:

       1: public override Int32 NumberOfControlsAllowed
       2: {
       3:     get
       4:     {
       5:         return (-1);
       6:     }
       7: }
       8:  
       9: public override Int32 NumberOfDirectDependenciesAllowed
      10: {
      11:     get
      12:     {
      13:         return (-1);
      14:     }
      15: }
      16:  
      17: public override Int32 TotalNumberOfDependenciesAllowed
      18: {
      19:     get
      20:     {
      21:         return (-1);
      22:     }
      23: }

    Direct dependencies are user controls directly declared in the page and indirect ones are those declared inside other user controls.

    Code itself, including event handler declarations, are controlled by AllowCode (default is true):

       1: public override Boolean AllowCode
       2: {
       3:     get
       4:     {
       5:         return (true);
       6:     }
       7: }

    If we want to change a data binding expression, we resort to ProcessDataBindingAttribute, which also returns true by default:

       1: public override Boolean ProcessDataBindingAttribute(String controlId, String name, String value)
       2: {
       3:     if (name == "Text")
       4:     {
       5:         //Do not allow binding the Text property
       6:         return (false);
       7:     }
       8:  
       9:     return (base.ProcessDataBindingAttribute(controlId, name, value));
      10: }

    For intercepting event handlers, there’s the ProcessEventHook, which likewise returns true by default:

       1: public override Boolean ProcessEventHookup(String controlId, String eventName, String handlerName)
       2: {
       3:     if (eventName == "SelectedIndexChanged")
       4:     {
       5:         //Remove event handlers for the SelectedIndexChanged event
       6:         return (false);
       7:     }
       8:  
       9:     return (base.ProcessEventHookup(controlId, eventName, handlerName));
      10: }

    And finally, for code blocks, server-side scripts and data binding expressions, there’s the ProcessCodeConstruct method, which likewise also allows everything by default:

    Conclusion

    This was in no means an in-depth description of page parser filters, I just meant to give you an idea of its (high) potential. It is very useful to restrict what end users can place on their pages (SharePoint style) as well as for adding dynamic control programmatically in specific locations of the page, before it is actually built.

    As usual, let me hear your thoughts! Winking smile

    Read more...

  • NHibernate Succinctly

    It’s with great pleasure that I see the release of NHibernate Succinctly, a book that I wrote for Syncfusion’s Succinctly series! It’s my second title, more to come! Winking smile

    Like Entity Framework Code First Succinctly, this book has something for the beginner as well as for more advanced users. Unlike EFCFS, it covers the current version of NHibernate.

    My good friend Zoran Maksimovic (@zoranmax) was the technical reviewer and besides him, I also want to thank everyone at Syncfusion: Hillary Bowling, Darren West, Tres Watkins and Graham High for their feedback and support, and for the opportunity they gave me. Of course, my coleagues at Critical, Pedro Gomes (@pedromvgomes) and Marco Carreira, and also my old friend Tiago Andrade, who also conducted reviews, cannot be forgotten as well!

    Go ahead, grab your copy and let me know what you think!

    By the way, it might be interesting to write something about my experience as an author… Any of you Succinctly authors out there would like to share your experience? Write me a line or comment here! Thanks!

    Read more...

  • New Features in SharePoint Designer 2013 Workflows

    SharePoint Designer 2013 workflows brought along new and quite welcome features. I will list my favorite ones.

    First, the ability to define stages (blocks of instructions) and to jump (yes, goto-style!) between them. This permits a better organization of our code and because of conditional jumps, even includes the ability to reuse code and to loop between stages.

    image

    Next one is stage-level loops. We have two flavors: one where the loop count is predefined from an Integer variable and the other where a condition is used to determine its end.

    image

    Then we have a new type of variables, Dictionary, and three associated actions: build a dictionary with values, get an item from a dictionary and count the number of items in it. Each Dictionary item can be of a different type, and it is even possible to have items of type Dictionary. A Dictionary can be indexed by its key or by position, which is very useful to use inside loops.

    image

    It is now possible to start list and site workflows, but only SharePoint 2010 are supported. Workflows can be started synchronously, in which case, the originating workflow will wait for the result, or asynchronously, aka, fire and forget. Depending on the workflow selected, it may be necessary to specify values for its parameters.

    Also new is the ability to assign tasks and start approval processes.

    image


    image

    A perhaps not so used one is the capability to start a document translation process. The name is misleading, since it can also be used to translate list fields. The result translation is stored in another list.

    Finally, we have the ability to call an HTTP web service. This will mostly used to call REST-style web services, but nothing prevents us from calling SOAP, since we can build a SOAP request using the string utility actions that the Designer offers. We can specify both request contents and headers, and retrieve the result, headers and HTTP status code. The problem is, SharePoint Designer workflows can only process results coming as JSON, not XML, but there are a number of translation web services that can be used to turn XML into JSON.

    image

    Finally,

    All in all, very useful additions! Smile

    Read more...

  • Looping Through List Items in SharePoint 2013 Designer Workflows

    SharePoint 2013 Designer workflows now has two new interesting options: the ability to call HTTP web services and the option to loop over some code a number of times. This, together with the new REST API, which supports querying lists and returning data in JSON, allows iterating through list items in a workflow, something that was not possible before.

    In order to demonstrate this, let’s create a new Site Workflow in SharePoint Designer, that will iterate through the Tasks list:

    image

    Call it Process Tasks, for example, and make sure you select SharePoint 2013 as the platform type.

    In the workflow designer, let’s start by creating a new stage, call it Retrieve Tasks:

    image

    In it, we add a new Set Workflow Variable action which creates a new String variable called url with the value “http://sp2013/_api/web/lists/getbytitle('Tasks')/items”. This uses the new REST API, and you can pass in additional options, such as for ordering by the DueDate field in descending order:

    http://sp2013/_api/web/lists/getbytitle('Tasks')/items?$orderby=DueDate desc

    or filtering:

    http://sp2013/_api/web/lists/getbytitle('Tasks')/items?$filter=DueDate gt DateTime’2014-07-31T00:00:00’

    Next, we add a Dictionary variable (Build a Dictionary action), call it requestHeaders, and initialize it as this:

    image

    Both “Accept” and “Content-Type” entries are of the String type and they both contain the value “application/json;odata=verbose”, SharePoint REST API understands this and sets the response content type appropriately as JSON. If we don’t pass these values, the output would come as XML.

    Following, add an Call an HTTP Web Service action and set its properties. The request will be the url variable:

    image

    Response content will go to a new variable called responseContent:

    image

    Response headers will go to a new variable called responseHeaders:

    image

    And the same goes for the response code (variable responseCode):

    image

    Then we set the request headers to be the requestHeaders variable we created just now, by clicking on the properties for the Call an HTTP Web Service action:

    image

    Now, create a new stage, call it Process Tasks, and, at the end of the initial stage, add a Go to Process Tasks action.

    On the Process Tasks stage, add a Get an Item from a Dictionary action, set the item as d/results, the source variable reponseContent and the output to a new variable of type Dictionary called list. Then count items from this list variable using a Count Items in Dictionary action and store the result in a new Integer variable called count. This variable will tell us how many times we have to loop. Finally, create a new Integer variable called index and set it to 0 (Set Workflow Variable), this will be the loop index.

    Next, add a loop (Loop n Times), call it Loop Task Items, and set the loop variable to count. Inside the loop, get value d/results([%Variable: index%]) using a Get an Item from a Dictionary action from responseContent and store it in a new Dictionary variable called item. Get some fields (Get an Item from a Dictionary) from the item variable, such as Title and DueDate  (mind you, these will be task item fields) and store them in appropriate variables and do whatever you want with them, like logging its contents (Log). Time to increment the loop counter: add a Do Calculation action and in it increment the index variable into a new Integer variable called indexPlusOne. Then set the index variable to be the indexPlusOne (Set Workflow Variable). Finally, exit the loop and set the workflow status (Set Workflow Status action) to Finished. At the end of the stage, select Go to End of Workflow.

    That’s it. Your workflow should look like this:

    image

    The new functionality makes SharePoint Designer workflows much more powerful than before. I will continue to talk about it in the following posts.

    Read more...

  • NHibernate Pitfalls: XML Mappings

    This is part of a series of posts about NHibernate Pitfalls. See the entire collection here.

    If you are still using XML mappings – .hbm.xml files –, there’s nothing wrong with that, but you may run into problems.

    First, you will need to add these files as embedded resources in your project, if you are calling Configuration.AddAssembly(), Configuration.AddClass() or you are specifying the name of the assembly in the .config file like this:

       1: <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
       2:     <session-factory>
       3:         <property name="connection.driver_class">NHibernate.Driver.Sql2008ClientDriver</property>
       4:         <property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>
       5:         <property name="connection.connection_string_name">MyConnection</property>
       6:         <mapping assembly="MyAssembly.MyModel" />
       7:     </session-factory>
       8: </hibernate-configuration>

    These methods will look for .hbm.xml files as embedded resources in that assembly:

    image

    Alternatively, you can have the files on the filesystem, but you will have to call Configuration.AddDirectory(), Configuration.AddFile() or Configuration.AddInputStream(), passing the appropriate parameters.

    In either case, the name of each .hbm.xml must end with .hbm.xml (of course!) and must be composed of the name of the associated class including its namespace.

    If you don’t do this, NHibernate will not find your mappings, which will result in runtime errors.

    Read more...