Archive

Archive for the ‘Exploring the CodeFluent Runtime’ Category

Exploring the CodeFluent Runtime: Web Controls – Part 2

February 5, 2014 1 comment

In Part 1 of this series, we looked at some useful controls from the CodeFluent.Runtime.Web assembly.
On the same subject, we’ll explore in this post some other very useful controls for ASP.NET WebForms application.

The first controls are DataSource controls; They aren’t visual but very convenient as they can be bound to any DataBound controls like GridView, ListView, etc.

CountryDataSource (CodeFluent.Runtime.Web.UI.CountryDataSource) gives you a list of countries with a lot of properties, including localization information (EnglishName, NativeName, Location, Region, etc.). The type of the enumerated item is CodeFluent.Runtime.Utilities.Country. You can learn more about this type in the related article on our blog.

<cfe:CountryDataSource ID="CountryDataSource1" runat="server"/>
<asp:GridView ID="GridView2" runat="server" DataSourceID="CountryDataSource1" AllowPaging="true">

CountryDataSource

CultureDataSource (CodeFluent.Runtime.Web.UI.CultureDataSource) gives you a list of CultureInfo (System.Globalization.CultureInfo) and can be bound with any DataBoundControl (GridView, DropDownList…).

<cfe:CultureDataSource ID="CultureDataSource1" runat="server" />
<asp:GridView ID="GridView3" runat="server" DataSourceID="CultureDataSource1" AllowPaging="true">

CultureDataSource

CodeFluent Entities comes with another cool Web Control: the CultureDropDownList.

CultureDropDownList (CodeFluent.Runtime.Web.UI.WebControls.CultureDropDownList) displays automatically for you a DropDownList filled with cultures. With a single line of code, you can let the user change the UI Culture of your website.
First, add this control to your page:

<cfe:CultureDropDownList id="cultures" runat="server" CultureCookieName="culture" AutoPostBack="true" TitleMemberName="EnglishIEStyle" TextMemberName="NativeName" CultureList="en-us;fr-fr" />

The CultureList property lets you set the cultures you want to display. By default, all available cultures (on the current computer) are loaded.

Then, just add the following code in the Global.asax file.

protected void Application_AcquireRequestState(object sender, EventArgs e)
{
    CultureDropDownList.SetRequestCulture(Request, "culture"); 
}

The second parameter corresponds to the name of the cookie set in the CultureDropDownList in the page.

Because the CultureDropDownList control is set to AutoPostBack=”true”, when the user selects another culture, the website page will automatically reload with the selected culture. Of course, you need to put in place the ASP.NET globalization mechanism and provide the corresponding resources files :).

FreeForm Control
Now, another topic. Let’s imagine you have several forms to implement as pages on your site, most of them used to get simple input from your users. Let’s suppose you want to send email with the content of the forms. This can be useful for polls for example.

For this, you can use the FreeForm control (CodeFluent.Runtime.Web.UI.WebControls.FreeForm). It allows you to create an arbitrary form, add all the child controls you want to it and then add a piece of code to gather all the user input data. Here is a quick example.

We start with a simple markup:

<cfe:FreeForm ID="FF" runat="server" OnFormChanged="OnFormChanged" DecamelizeOptions="Default" >
    <ItemTemplate>
        <asp:Panel ID="Panel3" runat="server" GroupingText="Personnal Information">
            <asp:Label ID="Label1" runat="server" Text="Preferred Name:" /><br />
            <asp:TextBox ID="TextBox1" runat="server" Text='<%#Bind("PreferredName") %>' /><br />
            <asp:Label ID="Label2" runat="server" Text="City:" /><br />
            <asp:TextBox ID="TextBox3" runat="server" Text='<%#Bind("City") %>' /><br />
        </asp:Panel>
        <asp:Panel ID="Panel4" runat="server" GroupingText="Business Information">
            <asp:Label ID="Label3" runat="server" Text="Your Company:" /><br />
            <asp:TextBox ID="TextBox4" runat="server" Text='<%#Bind("YourCompany") %>' /><br />
            <asp:Label ID="Label4" runat="server" Text="Describe your primary role and function:" /><br />
            <asp:TextBox ID="TextBox5" runat="server" Text='<%#Bind("DescribeYourPrimaryRole_x0026_Function") %>' /><br />
        </asp:Panel>
        <br />
        <asp:Button ID="Button2" runat="server" Text="OK" />
    </ItemTemplate>
</cfe:FreeForm>

We have a form with 4 textboxes and their corresponding labels into 2 panels, plus a standard button to submit :

When the user submits the button, the whole input data will be transformed into a dictionary instance automatically. Each control will provide a dictionary entry in that instance. Notice that all the Text attributes of the textboxes have a standard ASP.NET bind token attached. That token will become the entry field key, and the entry value will be the data entered by the user (whatever the type of this data and the type of the control). To get this dictionary you just need to attach to the FormChanged event and read the Values property of the FormChangedEventArgs parameter, like this:

<script runat="server">
    protected void OnFormChanged(object sender, FormChangedEventArgs e)
    {
        StringBuilder sb = new StringBuilder();

        foreach (DictionaryEntry de in e.Values)
        {
            sb.AppendLine(de.Key + "=" + de.Value + "<br/>");
        }
        
        // NOTE: instead, send email here with the content of the StringBuilder
        litResult.Text = sb.ToString();
    }
</script>     

You may have noticed that we have defined the field names using camel-case and also some weird hexadecimal notation. The FreeForm control has the ability to “decamelize” these keys and unescape the Unicode characters represented by their hexadecimal values. This trick allows us to use anything for key names (although the Bind syntax is much more restrictive). You can define several options in the DecamelizeOption attribute (None, ForceFirstUpper, ForceRestLower, UnescapeUnicode, UnescapeHexadecimal, ReplaceSpacesByUnderscore, ReplaceSpacesByMinus, ReplaceSpacesByDot, KeepFirstUnderscores, DontDecamelizeNumbers, KeepFormattingIndices).

So, this simple example gives you the following result:

Of course, you will hopefully implement something more useful in your project :) You can also imagine having a form generator for power-users, letting them design simple forms and process the Key/Value Dictionary generated by the FreeForm control in a pretty much automatic way.

NumericTextBox Control
Do you need a numeric-only textbox input?. CodeFluent.Runtime.Web has a solution for you: the NumericTextBox control.

The NumericTextBox control (CodeFluent.Runtime.Web.UI.WebControls.NumericTextBox) prevents user from entering non-numeric characters. You can define the value type with the TargetTypeName attribute, define the MaximumNumbers, MaximumIntegerNumbers, MaximumDecimalNumbers or the Negative or Positive Sign. Note this control can be used inside a FreeForm control we say previously.

<cfe:NumericTextBox ID="NumericTextBox1" runat="server" Value='<%# Bind("NumberOfEmployees") %>' TargetTypeName="System.Int32" />

There is also associated DataControlField, NumericTextField CodeFluent.Runtime.Web.UI.WebControls.NumericTextField) fields controls that you can use in GridView, DetailsView, etc.

<cfe:NumericTextField DataField="Age" HeaderText="Age" TargetTypeName="System.Int32"/>

Captcha Control
The Captcha control (CodeFluent.Runtime.Web.UI.WebControls.CaptchaControl) displays an image with some simple text inside, but supposedly quite difficult to read for machines. You can define the image size, the complexity of the produced image, and a timeout duration. Notice that the image is generated by the BinaryLargeObjectHttpHandler of CodeFluent Entities (Learn more about Blob here).

The Captcha control comes with its validator, the CaptchaValidator control (CodeFluent.Runtime.Web.UI.WebControls.CaptchaValidator). As any validator, you just need to declare the ControlToValidate and the CaptchaControlID associated.

In this example, we just display a message if the text entered corresponds to what was generated by the Captcha control.

<cfe:CaptchaControl ID="CaptchaControl1" runat="server" Width="200px" Height="50px" Expiration="120"
    Options="FontWarpFactorMedium, BackgroundNoiseLevelHigh,LineNoiseLevelHigh" />
<br />
Please enter the code or press F5 to refresh the browser
<br />
<cfe:CaptchaValidator ID="CaptchaValidator1" runat="server" ControlToValidate="Verify" CaptchaControlID="CaptchaControl1"
    SetFocusOnError="True" ErrorMessage="The code doesn’t match or there was a timeout" ForeColor="Red" />
<br />
<asp:TextBox ID="Verify" runat="server" EnableViewState="False" AutoCompleteType="None" />
<asp:Button ID="btValidate" runat="server" Text="Validate" OnClick="btValidate_Click" /><br />
<asp:Label ID="lblResult" runat="server" Text="You enter the correct text! Thank you for validating." Visible="false" ForeColor="Green"/>

In the button Click event, call Page.IsValid to validate the captcha:

<script runat="server">
    protected void btValidate_Click(object sender, EventArgs e)
    {
        if (Page.IsValid)
        {
            lblResult.Visible = true;
        }
        else
        {
            lblResult.Visible = false;
        }
    }
</script> 

Have a look at the Captcha image here:

Captcha

As you’ve seen in this serie, CodeFluent.Runtime.Web can be very useful to us, web developers who are tired to write a lot of code-behind to do simple actions. With these controls you just need to drag and drop them on your page, save and enjoy.

These controls are located in the CodeFluent.Runtime.Web assembly, part of the CodeFluent Entities product ! Try them!

Happy controling!

The R&D team.

Exploring the CodeFluent Runtime: Web Controls – Part 1

January 28, 2014 1 comment

Today, on the series “Exploring the CodeFluent Runtime” we’re going to explore the ASP.Net Web Controls inside the CodeFluent.Runtime.Web namespace. This is all provided as part of CodeFluent Entities.

In the CodeFluent.Runtime.Web assembly, you’ll find several controls usable in ASP.Net WebForms applications. The first we’ll see are controls used to render UI relatively to the data (bindings).

BooleanControl (CodeFluent.Runtime.Web.UI.WebControls.BooleanControl) displays what’s defined in FalseTemplate or TrueTemplate according to a boolean value.

<cfe:BooleanControl ID="BooleanControl1" runat='server' Value='<%# Eval("MyBooleanValue") %>' AutoBind="true">
    <TrueTemplate>
        This template will be displayed if Value is evaluated as "true"
    </TrueTemplate>
    <FalseTemplate>
        This template will be displayed if Value is evaluated as "false"
    </FalseTemplate>
</cfe:BooleanControl>

CompareControl (CodeFluent.Runtime.Web.UI.WebControls.CompareControl) displays FalseTemplate or TrueTemplate according to what’s defined by the ValueToCompare attribute and an Operator (Equal, NotEqual,
GreaterThan, GreaterThanEqual, LessThan, LessThanEqual, DataTypeCheck). For the DataTypeCheck operator, the ValueToCompare will be the full name of the type to check.

<cfe:CompareControl ID="CompareControl1" runat='server' Value='<%# Eval("MyValueToCompare") %>' Operator="GreaterThan" ValueToCompare="0">
    <TrueTemplate>
        Value is greater than 0
    </TrueTemplate>
    <FalseTemplate>
        Value is less than or equal to 0
    </FalseTemplate>
</cfe:CompareControl>
 
<cfe:CompareControl ID="CompareControl2" runat='server' Value='<%# Eval("MyValueToCompare") %>' Operator="DataTypeCheck" ValueToCompare="System.Int32">
    <TrueTemplate>
        Value is a System.Int32
    </TrueTemplate>
    <FalseTemplate>
        Value is not a System.Int32
    </FalseTemplate>
</cfe:CompareControl>

MultiCompareControl (CodeFluent.Runtime.Web.UI.WebControls.MultiCompareControl) is similar to the CompareControl but is more like a switch.

<cfe:MultiCompareControl ID="MultiCompareControl1" runat="server" Value='<%#Eval("MyValueToMultiCompare") %>'>               
    <case ValueToCompare="10" Operator="GreaterThan">
            Value is greater than 10
    </case>
    <case ValueToCompare="0">
    Value is equal to 0
    </case>
    <default>
    Value is not equal to 0 and is less than or equal to 10
    </default>
</cfe:MultiCompareControl>

ExistsControl (CodeFluent.Runtime.Web.UI.WebControls.ExistsControl) displays FalseTemplate or TrueTemplate depending on a given value. The value is tested against “null”, “DBNull”, or an empty string (possibly trimmed).

<cfe:ExistsControl ID="ExistsControl1" runat='server' Value='<%# Eval("Email") %>' Trim="true">
    <TrueTemplate>
        This template is displayed only if Value is not null or empty 
    </TrueTemplate>
    <FalseTemplate>
        This template is displayed when Value is null
    </FalseTemplate>
</cfe:ExistsControl>

When you work with enumerations into your Model, you want to be able to display and edit them easily into your forms or GridView. We have a solution for you! Let me introduce the Enum Controls.

EnumCheckBoxList (CodeFluent.Runtime.Web.UI.WebControls.EnumCheckBoxList) derives from the standard CheckBoxList control but is automatically filled with the fields of the enumeration type you define EnumTypeName parameter. Note this also supports multi-valued enumerations (with a [Flags] custom attribute).

EnumRadioButtonList (CodeFluent.Runtime.Web.UI.WebControls.EnumRadioButtonList) derives from the standard RadioButtonList control. As the EnumCheckBox, you only need to define the EnumTypeName attribute

EnumDropDownList (CodeFluent.Runtime.Web.UI.WebControls.EnumDropDownList) derives from the standard DropDownList and works the same way.

Another control that allows you to quickly bind your data is the BoolControl (CodeFluent.Runtime.Web.UI.WebControls.BoolControl). The BoolControl is a visual custom control that displays a System.Boolean or Nullable<System.Boolean> bound value. Depending whether the value is nullable or not, it can display a True/False or True/False/Undefined visual. It can use a CheckBox, DropDownList, horizontal button list, ListBox or horizontal or vertical radio button list to display these 2 or 3 items. It also supports read-only rendering and custom texts, interesting for localization purposes.

Is Customer:

<cfe:BoolControl ID="BoolControl1" runat="server" Value='<%# Bind("IsCustomer") %>' TrueText="Yes" FalseText="No" UnspecifiedText="Undefined" BoolControlType="HorizontalRadioButtonList" />

Contact Method:

<cfe:EnumCheckBoxList ID="EnumCheckBoxList1" runat="server" Value='<%# Bind("MethodToContact") %>' EnumTypeName="BlogCFE.ContactManager.ContactMethod" />
Origin (RadioButton):
<cfe:EnumRadioButtonList ID="EnumRadioButtonList1" runat="server" Value='<%# Bind("Origin") %>' EnumTypeName="BlogCFE.ContactManager.ContactOrigin" />
Origin (DropDown):
<cfe:EnumDropDownList ID="EnumDropDownList1" runat="server" Value='<%# Bind("Origin") %>' EnumTypeName="BlogCFE.ContactManager.ContactOrigin" />           

Here is the result:

For each of these controls, an associated DataControlField exists so you can use them in GridView, DetailsView, etc.

<cfe:BoolField DataField="IsCustomer" HeaderText="Is Customer" TrueText="Yes" FalseText="No" BoolControlType="DropDownList" />
<cfe:EnumCheckBoxListField DataValueField="MethodToContact" HeaderText="Contact method" EnumTypeName="BlogCFE.ContactManager.ContactMethod" />
<cfe:EnumRadioButtonListField DataValueField="Origin" HeaderText="Origin (RadioButton)" EnumTypeName="BlogCFE.ContactManager.ContactOrigin" />
<cfe:EnumDropDownListField DataValueField="Origin" HeaderText="Origin (DropDown)" EnumTypeName="BlogCFE.ContactManager.ContactOrigin" />        

the result in a grid view:

List of Contacts

As you’ve seen, these controls can avoid you to write a lot of code focusing more on a declarative way of programming.

In the next article, we’ll introduce the DataSources controls and another couple of cool utilities.

The R&D team.

Exploring the CodeFluent Runtime: Country utilities

January 21, 2014 1 comment

The CodeFluent.Runtime.Utilities.Country class is a cool tool that provides information about countries, regions, geographic locations and currencies.

Below is a figure showing a WPF application with a DataGrid that contains a list of countries with the information this class provides: locale identifier, region, english name, native name (in the corresponding language), currencies, etc.)

Country

XAML :

<Grid>
    <DataGrid x:Name="MyDataGrid" />
</Grid>

C# :

MyDataGrid.ItemsSource = CodeFluent.Runtime.Utilities.Country.AllCountries;

By running the code above, you’ll get a list of countries as a data source for your WPF DataGrid.

The Country object also exposes some useful methods such as:

GetCountry : find a country by its ISO-3166 two-letter code

CodeFluent.Runtime.Utilities.Country.GetCountry("AL")

It also supports principal subdivisions (e.g., provinces or states) of all countries coded in ISO 3166 so you can get locations and not only countries:

// *private joke* Carl, this one's for you !
var guadeloupe = CodeFluent.Runtime.Utilities.Country.GetCountry("GL");

// Get all locations installed on your system.
var allLocations = CodeFluent.Runtime.Utilities.Country.AllLocations;

GetCurrencyCountries : find countries for a given ISO currency symbol

var euroCountries = CodeFluent.Runtime.Utilities.Country.GetCurrencyCountries("EUR")

So here is the same grid with the list of countries that use EURO currency:

Country

Before leaving this topic, I suggest you have also have a look at the CultureComboBox control available in the CodeFluent.Runtime.Design namespace. It provides an associated Winforms ComboBox specialized for displaying countries.

The CodeFluent Runtime is  available with the full CodeFluent Entities product and with the CodeFluent Runtime Client 100% free assembly (available directly from Nuget).

Happy countrying!

The R&D team.

Exploring the CodeFluent Runtime: The Ribbon Control

January 17, 2014 Leave a comment

Hey, unless you lived on another planet the last 7 years, you guys should know what is a Ribbon is in terms of user interface. It’s a sophisticated set of toolbars and buttons placed on several tabs that allows you to quickly find the commands to complete a task. Since the release of Microsoft Office 2007 (Word, Excel, PowerPoint), this kind of control has become greatly appreciated by developers to provide a great user experience to their applications.

Office Ribbon

Office Ribbon

Now, the free CodeFluent Runtime Client Library that we, at SoftFluent, provide, will allow us to easily integrate a similar control in your Windows Forms applications. First of all, just take a look at the following screenshot of this RibbonControl schema:

RibbonControl01

The RibbonControl consists of different tabs called RibbonTab (crazy huh?). Each tab (as ‘Home’ and ‘View’ above) can include one or several groups of controls of RibbonPanel type (as ‘Clipboard’, ‘Font’, ‘Paragraph’, and ‘Insert’ above). Each panel consists of a list of RibbonItems objects (RibbonItem is not a control, it’s just a wrapper object). Each RibbonItem can embed standard controls such as a Button or a DropDownList.

Now, I’m going to explain how to create the RibbonControl introduced above programmatically (as of today, we don’t provide a cool Visual Studio designer integration, so this is in fact the only way to use this control…)

Add a RibbonControl in a Windows form (Winforms technology) :

The first easy step is to add a RibbonControl, in the same way that you would add a button to a form. The RibbonControl inherits from the Control class:

var ribbonControl1 = new CodeFluent.Runtime.Design.RibbonControl();

this.Controls.Add(ribbonControl1);

Add RibbonTabs to RibbonControl:

var homeTab = new CodeFluent.Runtime.Design.RibbonTab("Home");
var viewTab = new CodeFluent.Runtime.Design.RibbonTab("View");

ribbonControl1.Tabs.Add(homeTab);
ribbonControl1.Tabs.Add(viewTab);

Add RibbonPanel to RibbonTab:

var clipBoardPanel = new CodeFluent.Runtime.Design.RibbonPanel("Clipboard");
var fontPanel = new CodeFluent.Runtime.Design.RibbonPanel("Font");
var paragraphPanel = new CodeFluent.Runtime.Design.RibbonPanel("Paragraph");
var insertPanel = new CodeFluent.Runtime.Design.RibbonPanel("Insert");

homeTab.Panels.Add(clipBoardPanel);
homeTab.Panels.Add(fontPanel);
homeTab.Panels.Add(paragraphPanel);
homeTab.Panels.Add(insertPanel);

Here is the result:
RibbonControl03

Add RibbonItem to RibbonPanel:
Finally, we add some standard controls to the RibbonPanel :

var copyButton = new CodeFluent.Runtime.Design.RibbonButton("Copy");
copyButton.Mode = CodeFluent.Runtime.Design.RibbonItemMode.Icon;
copyButton.IconIndex = 0;

var pasteButton = new CodeFluent.Runtime.Design.RibbonButton("Paste");
pasteButton.Mode = CodeFluent.Runtime.Design.RibbonItemMode.Icon;

var pasteOptionDdl = new CodeFluent.Runtime.Design.RibbonDropDownList("Paste options");

pasteOptionDdl.Items.Add(new CodeFluent.Runtime.Design.RibbonDropDownItem("Paste"));
pasteOptionDdl.Items.Add(new CodeFluent.Runtime.Design.RibbonDropDownItem("Paste special"));
clipBoardPanel.Items.Add(copyButton);
clipBoardPanel.Items.Add(pasteButton);
clipBoardPanel.Items.Add(pasteOptionDdl);

Just compile your code to get the desired result :

RibbonControl03

RibbonControl provides an ImageList property that can’store all the icons we need (such as ‘Copy’ / ‘Paste’ buttons here). So, for example, we can add two images to our Windows Forms project and to the image collection (ImageList) of the RibbonControl:

ribbonControl1.ImageList = new ImageList();
ribbonControl1.ImageList.ImageSize = new System.Drawing.Size(32, 32);

ribbonControl1.ImageList.Images.Add(Image.FromFile(@"Images\copyButtonIcon.png"));
ribbonControl1.ImageList.Images.Add(Image.FromFile(@"Images\pasteButtonIcon.png"));

To assign one of these icons to RibbonItem, simply assign the RibbonItem’s IconIndex property, which corresponds to the index of an image in this list:

pasteButton.IconIndex = 1;

Note that you can also resize all images in the collection this way :

ribbonControl1.ImageList.ImageSize = new System.Drawing.Size(32, 32);

In order to handle different sizes of icons, the RibbonControl exposes a second image collection, the SmallImageList. To assign an icon of this collection, just use the SmallIconIndex property.

Convenient and easy, don’t you think ?

Add RibbonControl in WPF application

Since WPF day one, it’s possible to host Windows Forms controls in your WPF application. So, if you need to use the RibbonControl in xaml, check out this article.

There are expensive ribbon controls out on the market offering much more features than this one.  Its main advantage is it’s simple and … free. This control is provided 100% free of charge. Its license is tied to the CodeFluent Runtime Client license (which basically allows you to do anything with it…). The support is provided on a best-effort basis, so if you have any questions about this control or our products, feel free to visit the SoftFluent forum.

Happy ribboning!

The R&D team.

Exploring the CodeFluent Runtime: The Template Engine

December 26, 2013 Leave a comment

As you probably know, we released a few year ago the CodeFluent Runtime as a free Nuget Package named CodeFluentRuntimeClient. This is a set of utilities which is usable across all types of .NET applications (WPF, WinForms, ASP.NET, console, Windows service, etc.) and aims to ease the developer’s life.

Today, I’d like to introduce you, as part of the Exploring the CodeFluent Runtime series, an easy-to-use class to generate documents from a template source file.
You should ask yourself what is a template in term of software development. It’s simply a mixture of text blocks and control logic that can generate an output file. With our template engine, the control logic is written in JavaScript as fragments of program code. By default, the engine is based on the fast IE9+ “chakra” JavaScript engine developed by Microsoft for its Internet Explorer web browser.

Before we go any further it’s important to briefly describe the two following classes from the CodeFluent.Runtime.TemplateEngine namespace:

Template: Defines properties and characteristics of an ActiveX Scripting template and provides a set of methods to load and process a template file.

ParsedTemplate: In-memory and compiled representation of your template file (JavaScript).

The following diagram shows how the template engine internally works:

CodeFluentRuntimeClient Template

If you want to understand how to parse and execute JavaScript by C#, just have a look to this StackOverflow discussion. You’ll find how to interop with the JavaScript “IE9+ Chakra” JavaScript engine.

The easiest way to understand how to use the template engine is by way of an example. The first thing we have to do is create our template file.

Consider the following Rtf input file:

RTF Input file

Rtf Input file

You can download the template file here.

The “<% %>” tag represents the JavaScript code blocks. Let’s use the Template engine in order to process the template described above:

// The ComVisible indicates that the managed type is visible to COM.
[ComVisible(true)]
public class OrderLine
{
    public string ProductName { get; set; }
    public decimal UnitPrice { get; set; }
    public int Quantity { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        // initialize the argument dictionary.
        IDictionary<string, object> arguments = new Dictionary<string, object>();
        arguments.Add("orderLine1", new OrderLine() { ProductName = "Product A", Quantity = 5, UnitPrice = 12 });
        arguments.Add("orderLine2", new OrderLine() { ProductName = "Product B", Quantity = 10, UnitPrice = 30 });
        arguments.Add("orderLine3", new OrderLine() { ProductName = "Product C", Quantity = 4, UnitPrice = 40 });

        CodeFluent.Runtime.TemplateEngine.Template template = new CodeFluent.Runtime.TemplateEngine.Template();

        // Load the source template with the argument initialized above.
        template.Load("PurchaseOrder_Template.rtf", arguments.Keys.ToArray());

        using (StreamWriter writer = new StreamWriter(@"PurchaseOrder.rtf"))
        {
            // Run the template using the CodeFluent Runtime Template engine.
            template.Run(writer, arguments);
        }
    }
}

For running this code you have just to reference the CodeFluent Runtime Client Library and when executing it you’ll get the generated output file :

Rtf Output file

Rtf Output file

It’s good to know that the template engine is fully extendable. It would be helpful if you want to add your own keywords or business rules. For this purpose, you should inherit from the Template and/or ParsedTemplate objects.

On the same topic and through the CodeFluent Entities product, we are shipping a Template producer which is an engine that allow developers to generate text files from template containing C# code blocks.

Happy templating,

Antoine Diekmann

CodeFluent Entities (and CodeFluent Runtime Client) Zip File support

September 26, 2013 Leave a comment

The CodeFluent.Runtime.dll (provided with the CodeFluent Entities commercial product) and the CodeFluent.Runtime.Client.dll (provided as a totally FREE nuget package) both contain a very useful utility class: ZipFile.

We already talked about it in a previous post: http://blog.codefluententities.com/2012/08/24/exploring-the-codefluent-runtime-zipfile/

The big advantage of this class is it uses an unmanaged implementation of the ZIP compression algorithm. It consumes less CPU and less memory. The implementation, written in C/C++, is located in a native DLL called CodeFluent.Runtime.Compression.dll. It’s provided in 32 and 64-bit version, and both versions have the same name.

If you use the commercial CodeFluent Entities product, this 32-bit version DLL is located in the %programfiles(x86)%\SoftFluent\CodeFluent\Modeler directory, and the 64-bit version DLL is located in the %programfiles(x86)%\SoftFluent\CodeFluent\x64 directory.

If you use the Nuget package, both versions are shipped each in a x86 or x64 directory in the package.

There are few problems with this:

  1. Since the CodeFluent.Runtime.Compression.dll is a native DLL, it must be available in the standard DLL search path. The standard way of shipping it was to copy the DLL aside the .NET .exe you were developing.
  2. The problem with this is you can’t write easily a .NET .exe built as “Any CPU” that uses the ZipFile class, because both versions of the DLL have the same name. So you have to build and ship two versions (32 and 64-bit) of your .NET exe just to overcome this, and you must install them in separate directories, even if the rest of your .EXE works just fine in “Any CPU” mode…

To solve these issues, starting with CodeFluent version 760, the new ZipFile class has changed the way it finds the CodeFluent.Runtime.Compression.dll dll. The algorithm is now the following:

CodeFluent ZipFile Compression

So, existing installations should not be affected by this, however our new recommendation is:

  • If you’re writing applications that will run on machine that have the CodeFluent Entities commercial product installed (build 760 or higher), then… do nothing. The ZipFile class will find what it needs automatically.
  • If you’re writing applications that will be deployed on production machines where nothing special is installed, then don’t ship CodeFluent.Runtime.Compression.dll aside your .exe anymore but rename it as CodeFluent.Runtime.Compression.x86.dll and CodeFluent.Runtime.Compression.x64.dll and ship both aside your .exe. If you specifically compile your .exe as X86 or X64, you can put only the one required. If it’s “Any CPU”, copy both.

Happy zippin’ !

The R&D team.

Exploring the CodeFluent Runtime: ChunkedMemoryStream


 
Today, on the series “Exploring the CodeFluent Runtime” we are going to take a look at the ChunkedMemoryStream class on the CodeFluent.Runtime.Utilities namespace.
 
This class allows you to manipulate a memory stream by “chunks”. This can be useful when you are dealing with memory streams big enough (85,000 bytes) to be allocated on the Large Object Heap (LOH).
 
The ChunkedMemoryStream can be used instead of the System.IO.MemoryStream (mscorlib.dll) to avoid memory fragmentation.
 
Let’s build a simple example in order to compare the use of a System.IO.MemoryStream against the CodeFluent.Runtime.Utilities.ChunkedMemoryStream.
 
Let’s say I want to load a file’s content in memory (big enough to sit on the LOH).
 

static void Main(string[] args)
{
  FileStream fileSm = new FileStream(@"file_path", FileMode.Open);
  Stream ms = new MemoryStream();
  fileSm.CopyTo(ms);
  ms.Close();
  fileSm.Close();

  System.Diagnostics.Debugger.Break();
}

 
When the Debugger breaks let’s explore the LOH:
 

LOH using MemoryStream

LOH using MemoryStream


 
We can see that the LOH size is (17184 + 41943056 + 83886096 = 125846336 bytes) and we easily distinguish a memory allocation for 2 byte arrays (perhaps some buffers used internally when copying the data from one stream to another).
 
Let’s now change only one line in our code example and use the CodeFluent.Runtime.Utilities.ChunkedMemoryStream.
 

static void Main(string[] args)
{
  FileStream fileSm = new FileStream(@"file_path", FileMode.Open);
  Stream ms = new CodeFluent.Runtime.Utilities.ChunkedMemoryStream();
  fileSm.CopyTo(ms);
  ms.Close();
  fileSm.Close();

  System.Diagnostics.Debugger.Break();
}

 
And let’s explore the LOH:
 

LOH using ChunkedMemoryStream

LOH using ChunkedMemoryStream


 
We now see that the LOH size is 17184 bytes and we cannot see any trace of a byte array.
 

Using the ChunkedMemoryStream we avoid allocating memory on the LOH when manipulating big streams.

 
Remeber that the CodeFluent Runtime Client is a free library that provides very useful and powerful helpers like:

  • XML utilities
  • IO utilities
  • Type conversion helpers
  • JSON utilities
  • … and many other

 
You can easily install the CodeFluent Runtime Client from Nugget.
 
PM> Install-package CodeFluentRuntimeClient
 
 
Regards,
 
Pablo Fernadez Duran
 
 

Manipulating NTFS alternate data streams in C# with the CodeFluent Runtime Client

March 14, 2013 2 comments

Have you already heard about NTFS alternate streams? Also known as named streams or ADS (Alternate Data Streams).
Well it is a useful feature in NTFS storage systems. It expands the concept of file and data streams.

Alternate Data Streams

Alternate Data Streams

When working with NTFS files, the main data stream (or unnamed stream) is the central element of the file. When you create a file, a main stream is created. When you create an alternate stream and the main stream does not exist it is created, if you delete the main stream the whole file is deleted (so the existing alternate streams).
When you read a file or you write in to a file you are working with the main stream by default.

Alternate streams follows the syntax: “filename.ext:alternateName”

You can store any kind of data in an ADS (as you can do it with the unnamed stream), so you can store binary data, text data, an image, a video and even an executable file.

Let’s make quick test.

Open a command line console (cmd.exe).
Create a text file and write some content in it:

Writing in to the main data stream

Writing in to the main data stream

Let’s read the content:

Reading the main stream

Reading the main stream

Nothing extraordinary, we get the main data stream from our file.
Now let’s try to write in to an alternate data stream (this will create the alternate stream if it does not exist).

Writing in to an Alternate Data Stream

Writing in to an Alternate Data Stream

You have created an alternate data stream called “hide” right on our file “test.txt”, this will not have any incidence with your main data stream.
To ensure that our alternate data stream “hide” has been correctly created we will try to read it.

Reading an Alternate Data Stream content

Reading an Alternate Data Stream content

And to prove that our main data stream is still there, let’s read the main stream.

Reading the main stream

Reading the main stream

We have made some tests only with “text” streams but a stream can be also an image, an executable file and all other kind of stream a file container can host.
What about manipulating Alternate Data Streams with C#?
Well, this feature is unfortunately not available in .NET, we would need to call native methods if we want to manipulate alternate data streams.
So we can build some nice native method wrappers in order to manipulate alternate data streams or we can use the CodeFluent Entities Runtime Client.
CodeFluent Runtime Client is a free library that provides very useful and powerful helpers like:

  • XML utilities
  • IO utilities
  • Type conversion helpers
  • JSON utilities
  • … and many other

You can easily install the CodeFluent Runtime Client from Nugget.

PM> Install-package CodeFluentRuntimeClient

Using the CodeFluent Entities Client Runtime to manipulate alternate data streams is as easy as manipulate all well-known file streams.
We will use the NtfsAlternateStream class which is located in the CodeFluent.Runtime.BinaryServices namespace, it provides some static helper methods to manipulate alternate streams as they were “regular” streams (open, create, read, write, enumerate, delete…).
Let’s take a look to some useful methods to manipulate alternate data streams (ADS):

//Create a stream supporting ADS syntax
FileStream stream = NtfsAlternateStream.Open("test.txt:hide", FileAccess.Write, FileMode.OpenOrCreate, FileShare.None);
stream.Close();

//Writing in to an ADS
NtfsAlternateStream.WriteAllText("test.txt:hide", "Secret content");

//Reading data from an ADS
string text = NtfsAlternateStream.ReadAllText("test.txt:hide");

//Enumerating all the ADS in test.txt
IEnumerable adsStreams = NtfsAlternateStream.EnumerateStreams("test.txt");
foreach (NtfsAlternateStream ads in adsStreams)
{
    Console.WriteLine(ads.Name);
}

//This will not delete the test.txt file
NtfsAlternateStream.Delete("test.txt:hide");

A concrete example of how ADS are used in Windows is when you download a file from the Internet. When I open a file downloaded from the Internet with Word (2013) I receive a warning telling me that the file might not be secure.

Word Protected View

Word Protected View

How does Word know that I downloaded the file from the Internet? Well, every time you download a file, Windows set an ADS called “:Zone.Identifier” containing some data related to the origin of the file. Let’s confirm that.

string altFileName = @"C:\Users\pablo\Downloads\someDoc.docx:Zone.Identifier";
string content = NtfsAlternateStream.ReadAllText(altFileName);
Console.WriteLine(content);

What we get is:

ZoneTransfer ZoneId

ZoneTransfer ZoneId

This value “ZoneId=3” means that the file has “Internet” as origin.

If we delete the “:Zone.Identifier” ADS from the file:

string altFileName = @"C:\Users\pablo\Downloads\someDoc.docx:Zone.Identifier";
//this will not delete the file
NtfsAlternateStream.Delete(altFileName);

Now we don’t receive a warning when trying to open the file, Word has no information from the file origin.
Alternate data streams are nice but they have some limitations. As we have said, ADS are only supported in NTFS file storage systems so what happen if you copy a file containing ADSs to another file system (FAT file system, USB drive, CD/DVD, network transfer…)? Well, you will lose all your ADS!

Avoid writing important or critical data to alternate data streams. ADS are not supported in not NTFS file systems.

Some ideas where ADS might be useful:

  • If you are writing a program to edit images it will be nice to keep the original image (or even all the modification history) so the user can undo some changes. Instead of keeping separate files you can write all the image versions in the same file using ADS, e.g. image.jpg:original, image.jpg:v1
  • You can store thumbnails for graphical files.
  • Imagine you wrote a “reader” application, you can keep some information like: font size, current page, background color… in the file itself.

I am sure you can image other practical and fun uses for Alternate Data Streams, it would be great if you share it with us Winking smile.

Regards.
Pablo Fernandez Duran

CodeFluent Entities and JSON/REST

November 29, 2012 Leave a comment

In a previous post we announced that CodeFluent Entities natively support JSON/REST.

In this post we’re going to see how to take advantage of the generated JSON/REST architecture. Thanks to JSON WCF services we should be able to call server methods from the client of our choice. To illustrate that we’re going to create a back end application exposing JSON WCF services that will be consumed in a console application. As you’re going to see, all the hard work will be done by CodeFluent Entities.

Creating the solution

Start by creating a new CodeFluent Project. We’ll use the “ContactManager Sample Model” for the purpose of this article.ContactManagerModel

  • Add a new Class Library project named “ContactManager” to your solution. It will be used to host the generated files corresponding to your Business Object model and JSON WCF service’s contracts.
  • Add a new SQL Server Database project named “ContactManager.Persistence” to your solution. It will be used to host your generated SQL scripts.
  • Add a new Empty ASP.NET Website project named “ContactManager.BackEnd” to your solution and add a reference to the ContactManager project and create a “Services” folder. It will be used to host the JSON WCF Services.
  • Add a new Console Application project named “ContactManager.Client” to your solution and add a reference to the ContactManager project and to CodeFluent.Runtime.dll. We will use it to make some calls via JSON WCF to the backEnd application and display the results in the console. Also, by default, Microsoft Visual Studio 2010 sets the target framework to .NET Framework 4 Client Profile. Go to the property of your project and change its target to .NET Framework 4.
    image

Adding the producers

  • Add a Business Object Model Producer and set its Target Directory to the ContactManager project. Also add it a Service Object Model Sub Producer and configure it so JSON been enabled and no proxy been produced. This producer will generate the complete WCF-based communication layer (service, contracts) with native JSON/REST support.
  • Add a SQL Server Producer and set its target directory to the ContactManager.Persistence project.
  • Add a Template Producer and set its Target Directory to the the Services folder of your ContactManager.BackEnd project. Also set its Source Directory to “CodeFluent Entities installation folder > Modeler >Templates > ServiceModel > JsonWebServices > Services”.

Configuring the solution

Configure your solution so it first start your  ContactManager.BackEnd application and then your ContactManager.Client application.

Generating code

Now to start generating code, build your CodeFluent Entities project called ContactManager.Model.

Here is the visual studio solution you should have by now, each project containing the generated code (your database should have been created too):

ScreenShot051

Writing the client

When the WCF Service Object Model Producer is set to generate JSON web services, it automatically adds two extra operations to the Business Object model and Services:
1. JsonGet
2. JsonPost

As the name suggests, you can use those methods to read (JsonGet) or write (JsonPost) by calling any other operation available on the service.

So why not use the other operations directly instead?
Well you can (using HTTP POST method and the header Content-Type set to application/json), but what’s interesting with those JsonGet/Post methods is that they add extra JSON oriented features. One of them being able to wrap .NET exception in a nice and simple JavaScript-friendly object.

Note: JsonGet and JsonPost methods are not fully documented yet but a new version of the documentation is on its way.

Here we want to use the JsonGet method in our console application to call the default generated LoadAll method and write the result on the console:

we can break the task down to the following steps:

  • Set up the URL with all parameters
  • Send a GET WebRequest
  • Receive the Json formatted data
  • Deserialize the object(s)
  • Write the result on the console

Therefore, our console application should look something like this:

using System;
using System.Net;
using System.IO;
using CodeFluent.Runtime.Utilities;
using ContactManager;

namespace ContactManager.ConsolApp
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Type a key to start");
            Console.ReadKey();

            string url = "http://localhost:62738/Services/ContactManager.Customer.svc/JsonGet?method=LoadAll";
            string jsonContent = GET(url);

            //Let's display the RAW JSON content first:
            Console.WriteLine("JSON Content:");
            Console.WriteLine(jsonContent + Environment.NewLine);

            //Then each Customer:
            Console.WriteLine("From deserialized content:");
            CustomerCollection customers = JsonUtilities.Deserialize<CustomerCollection>(jsonContent);
            foreach (Customer c in customers)
            {
                Console.WriteLine(c.Trace());
            }
        }

    }
}

Notes: the URL should be changed according to your configuration (port number, and service name should be updated);

The GET method simply downloads and returns the internet string response as follow:

// Returns JSON string
private static string GET(string url)
{
    using (WebClient client = new WebClient())
    {
        try
        {
            return client.DownloadString(url);
        }
        catch (WebException ex)
        {
            WebResponse errorResponse = ex.Response;
            using (Stream responseStream = errorResponse.GetResponseStream())
            {
                StreamReader reader = new StreamReader(responseStream, new System.Text.UTF8Encoding());
                String errorText = reader.ReadToEnd();

                Console.WriteLine(errorText);
            }
            throw;
        }
    }
}

But where do we find the JSON Serializer? Well the CodeFluent Runtime (CodeFluent.Runtime.dll) comes with a very convenient class: JsonUtilities.
The JsonUtilities class is a simple yet powerful JSON Serializer allowing you to convert your .NET objects into JSON and vice versa. See that post for more information.

Running the application

Hitting Ctrl+F5 should build and launch your backend application and then your console application. Typing a key should retrieve all the customers using JSON WCF services and display them on the console as follow:

Type a key to start
JSON Content:
[{"EntityKey":"1","EntityDisplayName":"info@softfluent.com","RowVersion":[0,0,0,0,0,0,7,209],”Id”:1,”EmailAddress”:”info@softfluent.com”,”Password”:null,
“FirstName”:”Thib”,”LastName”:”Nes”,”FullName”:null,”BirthdayDate”:”\/Date(-62135596800000)\/”,”LoyaltyProgramMember”:false,”LicenseNo”:null,”HasPreAccidents”:false,
“Age”:0,”AddressId”:-1,”Rentals”:[],”PaymentType”:0,”EntityState”:1}]

From deserialized content:
[Id=1,EmailAddress=info@softfluent.com,Password=,FirstName=Thib,
LastName=Nes,FullName=,BirthdayDate=1/1/0001 12:00:00 AM,LoyaltyProgramMember=False,LicenseNo=,HasPreAccidents=False,Age=0,
Address=<null>,_addressId=-1,Rentals=[Count=0],PaymentType=Cash, EntityState=Unchanged]
Press any key to continue . . .

 

What about saving data? Well, we would use the JsonPost method instead of JsonGet and use the JsonUtilities.Serialize method to serialize our content. The Main method of our console application would look like this:

static void Main(string[] args)
{
    string url = "http://localhost:62738/Services/ContactManager.Customer.svc/JsonPost?type=EntitySaveCall";
    Customer c = new Customer { FirstName = "John", LastName = "Doe", Age = 42 };
    string jsonContent = JsonUtilities.Serialize(c);
    
    POST(url, jsonContent);
}

And the POST method to send the data:

// POST a JSON string
private static void POST(string url, string jsonContent)
{
    using (WebClient client = new WebClient())
    {
        string response = string.Empty;
        //We need to specify that we are sending Json contents, or our
        //requests will be rejected by the services
        client.Headers.Add("Content-Type: json; charset=UTF-8");
        client.Encoding = System.Text.Encoding.UTF8;
        try
        {
            response = client.UploadString(url, jsonContent);
        }
        catch (WebException ex)
        {
            WebResponse errorResponse = ex.Response;
            using (Stream responseStream = errorResponse.GetResponseStream())
            {
                StreamReader reader = new StreamReader(responseStream, new System.Text.UTF8Encoding());
                String errorText = reader.ReadToEnd();

                Console.WriteLine(errorText);
            }
            throw;
        }
    }
}

This is it! This post highlighted the fact that we can directly consume JSON WCF services generated by CodeFluent Entities from the client of our choice (for instance for Windows Phone, iOS or Android to name but a few). CodeFluent Entities doing all the hard work for us by generating applications based on REST/JSON architecture in a couple of minutes.

Hope this helps!

Cheers,

Thibault NESTOR

Exploring the CodeFluent Runtime: ZipFile

August 24, 2012 1 comment

Since the day it was born, the CodeFluent Entities Runtime embarks a cool ZipFile class that allows you to create .ZIP files from other files, directories and streams, and extract from .ZIP files files, directories of files and streams!

The class is found in the CodeFluent.Runtime.Compression namespace and is very easy to use:

using CodeFluent.Runtime.Compression;

namespace ZipTest
{
    class Program
    {
        static void Main(string[] args)
        {
            // compress
            using (ZipFile file = new ZipFile("newzip.zip", ZipFile.Mode.Overwrite))
            {
                file.AddFile(myFile1);
                file.AddFile(myFile2);
                file.AddDirectory(myDirectory); // recursive, keep relative paths in
            }

            // decompress
            using (ZipFile file = new ZipFile("newzip.zip", ZipFile.Mode.Read))
            {
                file.GetFiles(myOutputDirectory); // recursive, keep relative paths out
            }
        }
    }
}

For CPU performance and memory usage reasons, and contrary to other popular .NET zip implementations (http://www.icsharpcode.net/opensource/sharpziplib/, or http://dotnetzip.codeplex.com/), CodeFluent Entities’ ZipFile implementation is unmanaged.

It means you will have to copy a native Windows DLL (that is shipped with the product) named “CodeFluent.Runtime.Compression.dll” in the bin directory of your application for this to work. Since it’s unmanaged, there are two versions of this dll, one for X86 processes, and another for X64 processes.

It’s fun to see Microsoft has finally taken the same unmanaged route for ZIP handling, this year, in 2012, as we did 7 years ago, when we shipped our first version of CodeFluent Entities :-)

The CodeFluent Runtime is available in two flavors:

Happy zip-ing!

The R&D team.

Follow

Get every new post delivered to your Inbox.

Join 41 other followers