Archive

Archive for March, 2013

Retrieve SQL Output parameters in your BOM with CodeFluent Entities

March 27, 2013 Leave a comment

 
 
Let’s say you have an existing stored procedure that uses OUTPUT parameters to retrieve some data and you want to access it in your Business Object Model (BOM) as an object method.
 
If you can modify your procedure you might want to use a more OOP (Object Oriented Programming) approach. It will be more flexible and it is what CodeFluent Entities follows.
 
But let’s suppose you don’t have the possibility to modify your stored procedure.
 
We will use an existing model to illustrate this post. We will work with the ContactManager demo project available within the CodeFluent Entities project templates in Visual Studio.
 
This is how our existing stored procedure looks like, it has 2 OUTPUT parameters.
 

CREATE PROCEDURE [dbo].[legacy_procedure]
(
@param1 [int] OUTPUT,
@param2 [nvarchar] (256) OUTPUT
)
AS
BEGIN
--some interesting code here
select @param1 = 42
select @param2 = 'answer'
END
GO

 

We create a method called “LegacyProcedure” related to the entity Contact

Add a method to an entity

Add a method to an entity

 

Name the method

Name the method


 
We need to create a “raw” method and specify the parameters for our method.
 
As we want to use an existing stored procedure we leave the body empty.

Defining our method

Defining our method


 
As we will work with an existing stored procedure we need to tell our method to use our existing stored procedure, and not to create his own persistence stored procedure.

 
In the method advanced properties at the “persistence” level we set “Persistence Name” (it must be the same name as the stored procedure).

Set the persistence method name

Set the persistence method name


 
Now we tell the persistence producer not to produce the stored procedure.
To do that we go to the “Aspect and Producer Properties” of our method and set the “Produce” value to False.

Persistence Produce Property

Persistence Produce Property


 
Finally we need to define the parameters that are used in our method.

The method parameters

The method parameters


 
The parameter names must be the same as those declared in our method (as well as the type).

Parameter names

Parameter names


 
Now we need to set the persistence parameter direction. Displaying the advanced properties, in the persistence group we set the direction to “Output”.

Parameter persistence direction

Parameter persistence direction


 
Supposing that you have a “Persistence producer” and a “Business Object Model producer” (BOM) we build the CodeFluent Entities project.
 
If you have a CodeFluent Entities version former to the Build 1.0.61214.707, then you will have a compile error while building the generated BOM project.

Output parameters are not handled

Output parameters are not handled


 
The solution would be to disable the generation of our method and code it by hand in a partial class.
 
But, since Build 1.0.61214.707 CodeFluent Entities now supports the “out” and “ref” parameters in persistence methods.
 
After installing the new version, we build the CodeFluent Entities project. If we take a look at our generated method we will see that the “out” parameters are now handled by our BOM.

Out parameters are handled

Out parameters are handled


 
 
Regards,
Pablo Fernandez Duran

Generate ASP .NET Web API Controllers using Templates

March 20, 2013 Leave a comment

 

In a precedent post we have shown how to build an ASP .NET WebAPI Controller to access the generated Business Object Model (BOM).
 
We saw how to implement manually a Web API Controller for one entity of our model.
 
Now, we are going to see how to build a Template in order to automatically generate a Web API Controller for each one of the entities in our model.
 
We are going to use the “CarRental” demo project included with CodeFluent Entities. It was the same sample project that we used when we created the Web API Controller.
 
The first thing we have to do is create our template file.

 

Templates location

Templates location

 

Our template must be prefixed by “[Template]”.

 
Before writing our template let’s create a producer for our template.
 

Template Producer

Template Producer


 
The “Source Directory” is the location of our template folder and the “Target Directory” is where our files will be generated, in my case I have a folder called “ApiControllers” in my MVC 4 Web Application project.
 
At the bottom of our template we fix some parameters.

[%@ template
enumerable="Producer.Project.Entities"
enumerableItemName="entity"
enumerableTargetPathFunc='Path.Combine(Path.GetDirectoryName(TargetPath), entity.Name) + "Controller.cs"' %]

 
That means that we are going to iterate through all the entities in our project (Producer.Project.Entities). Inside the template we can access the current enumerated entity by the name “entity”. And the name of the generated file (for each entity) will be “[EntityName]Controller.cs”.
 
Now we can write the content of our Api Controller. Let’s start by creating only the Controller class.

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by the Template Producer.
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace [%=entity.Namespace%].Web.ApiControllers
{
	using System.Collections.Generic;
	using System;
	using System.Net;
	using System.Net.Http;
	using System.Web.Http;

    public class [%=entity.Name%]Controller : ApiController
    {
    }
}

 
If we build our CodeFluent Entities project we must see our Api Controllers appear.
 

Generated API Controllers

Generated API Controllers


 
Now let’s implement the Api Controller methods. We will use almost the same implementation as we did in the post “Using ASP .NET Web API with CodeFluent Entities”.

// GET api/[%=entity.Name%]
public IEnumerable<[%=entity.Name%]> Get()
{
    return [%=entity.SetFullTypeName%].LoadAll();
}

// POST api/[%=entity.Name%]
public HttpResponseMessage Post([FromBody][%=entity.Name%] value)
{
	if(value == null || !value.Save())
	{
		return Request.CreateResponse(HttpStatusCode.BadRequest);
	}
	return Request.CreateResponse(HttpStatusCode.OK, value);
}

// PUT api/[%=entity.Name%]
public HttpResponseMessage Put([FromBody][%=entity.Name%] value)
{
	if(value == null || !value.Save())
	{
		return Request.CreateResponse(HttpStatusCode.BadRequest);
	}
	return Request.CreateResponse(HttpStatusCode.OK, value);
}

 

For the Delete and Get (for a single element) methods we need to do some work to manage the entity keys. Indeed, it is possible that some entities have multiple keys.

// DELETE api/[%=entity.Name%]/*ids
public HttpResponseMessage Delete(string ids)
{
	ids = ids.Replace('/', '|');
    [%=entity.ClrFullTypeName%] value = [%=entity.ClrFullTypeName%].LoadByEntityKey(ids);
	if(value != null && value.Delete())
	{
		return Request.CreateResponse(HttpStatusCode.NoContent);
	}
	return Request.CreateResponse(HttpStatusCode.NotFound);
}

	// GET api/[%=entity.Name%]/*ids
public [%=entity.Name%] Get(string ids)
{
	ids = ids.Replace('/', '|');
    [%=entity.ClrFullTypeName%] value = [%=entity.ClrFullTypeName%].LoadByEntityKey(ids);
	if(value == null)
	{
		throw new HttpResponseException(HttpStatusCode.NotFound);
	}
	return value;
}

 
We use a feature in MVC (and Web API) routes that allows us to handle a variable number of segments in a URL pattern.
 
So we will need to make some changes in our routing configuration. I have registered my routes for the Web API in a separate file called “WebApiConfig” (cf. Using ASP .NET Web API with CodeFluent Entities). The trick lies in the “*” before the parameter name (*ids).

config.Routes.MapHttpRoute(
                           name: "DefaultApi",
                           routeTemplate: "api/{controller}/{*ids}",
                           defaults: new { ids = RouteParameter.Optional }
                          );

 

For example, in order to retrieve a specific instance of the entity “InventoryDetail” we need three keys, so the URL to get an instance of “InventoryDetail” will be: http://server/api/InventroyDetail/1/2/3.

 
If we build our CodeFluent Entities project and take a look at the inside of a Controller we will see the complete implementation.
 
Now we only have to test our Controllers. We can use the same tests that we have done in the precedent post related to the ASP .NET Web API.

 
Regards.
 
Pablo Fernandez 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

Using ServiceStack with CodeFluent Entities

March 6, 2013 Leave a comment

In our last blog post we saw how to create a REST service layer using ASP .NET Web API and a CodeFluent Entities model.

Now we are going to use ServiceStack to expose HTTP web services (JSON and XML) from an existing CodeFluent Entities model.
ServiceStack is a REST Web Service Framework for .NET, it is an open source project that you can find here.
ServiceStack is based on a ‘modular’ architecture and it was built to be used in a simply way, no XML configuration and no code generation.
The ‘philosophy’ behind ServiceStack is to use strong-typed DTOs to define a web service API.
To illustrate this post we are going to use the Car Rental Sample project.

CarRental Sample  project

CarRental Sample project



We will add a Persistence producer (SQL Server 2012 for me) and a Business Object Model (BOM) producer.

Producers

Producers



ServiceStack can be used as a standalone solution or can be integrated on a MVC application, we are going to use it in an empty ASP .NET web application.

ASP .NET Web Application

ASP .NET Web Application



First of all we need to install ServiceStack in our ASP .NET web application project via nugget:

       PM> Install-Package ServiceStack

Now we need to register ServiceStack in our configuration (web.config), we want to host ServiceStack at the root path (‘/’) so we use this configuration:

<system.web>
  <compilation debug="true" targetFramework="4.5" />
  <httpRuntime targetFramework="4.5" />
  <httpHandlers>
    <add path="*" type="ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory, ServiceStack" verb="*"/>
  </httpHandlers>
</system.web>

If you want register ServiceStack on a custom path to avoid conflicts with another web framework (eg. ASP .NET MVC) go here.

ServiceStack uses a particular structure for services, a service consists in:

  • A request DTO
  • A service implementation
  • A response DTO

We are going to create a service that handles CRUD operations for the Entity ‘CarGroup’ (you can add some instances to your model so we have some test data).

We start by creating the request DTOs:

[Route("/carGroup", "GET")]
public class GetAllCarGroupRequest : IReturn<CarGroupCollection> { }

[Route("/carGroup/{Id}", "GET")]
public class GetCarGroupRequest : IReturn<CarGroup>
{
    public int Id { get; set; }
}

[Route("/carGroup/{Id}", "DELETE")]
public class DeleteCarGroupRequest
{
    public int Id { get; set; }
}

As you can see we also have associated some routes to our requests.
For the create and update methods (POST and PUT) we will add the request configuration elsewhere because we want to use existing classes as requests (the CarGroup class that will be the object to add or update), we will see this further in this post.
Now we need to create our service and it operations. I will call my service ‘CarGroupService’ and it will inherit from the class ‘ServiceStack.ServiceInterface.Service’.

public class CarGroupService : ServiceStack.ServiceInterface.Service
{
}

ServiceStack will ‘match’ a request to an operation and associate HTTP actions (verbs) to the name of our operations, so our operations must follow some conventions:

public {ResponseDTO} {HTTPVerb}({RequestDTO} request)

Now we can create our operations.

To retrieve all our CarGroup objects:

public CarGroupCollection Get(GetAllCarGroupRequest request)
{
    CarGroupCollection carGroups = CarGroupCollection.LoadAll();
    return carGroups;
}

To retrieve one CarGroup by its id:

public CarGroup Get(GetCarGroupRequest request)
{
    CarGroup carGroup = CarGroup.Load(request.Id);
    if (carGroup == null)
    {
        throw new HttpError(System.Net.HttpStatusCode.NotFound, "Car Group not found");
    }
    return carGroup;
}

To add a new instance of CarGroup or to update an existing instance we will use a common method:

private HttpResult CreateUpdate(CarGroup carGroup)
{
    if (carGroup == null || !carGroup.Save())
    {
        return new HttpResult(System.Net.HttpStatusCode.BadRequest, "Error while saving.");
    }
    return new HttpResult(carGroup, System.Net.HttpStatusCode.OK);
}

And we will call this method for create (POST) and update (PUT) operations:

public HttpResult Post(CarGroup request)
{
    return CreateUpdate(request);
}
<br/>
public HttpResult Put(CarGroup request)
{
    return CreateUpdate(request);
}

Finally, to delete an instance of CarGroup:

public HttpResult Delete(DeleteCarGroupRequest request)
{
    CarGroup carGroup = CarGroup.Load(request.Id);
    if (carGroup != null && carGroup.Delete())
    {
        return new HttpResult(System.Net.HttpStatusCode.NoContent, "Car Group deleted");
    }
    return new HttpResult(System.Net.HttpStatusCode.NotFound, "Car Group not found");
}

We have created all the operations and their associated requests. Now we have to register our web service.

We start by creating an AppHost for our service that inherits from ServiceStack.WebHost.Endpoints.AppHostBase where we can configure our service if we need to, I will use the default configuration:

public class CarGroupAppHost : AppHostBase
{
    //Tell Service Stack the name of your application and where to find your web services
    public CarGroupAppHost() : base("CarGroup Web Services", typeof(CarGroupService).Assembly) { }

    public override void Configure(Container container)
    {
        Routes
            .Add<CarGroup>("/carGroup", "POST")
            .Add<CarGroup>("/carGroup", "PUT");
    }
}

We have added the route configuration for our create (POST) and update (PUT) operations.

Now in the Global.asax.cs file (you need to create it if it does not exist) we initialize our service host:

public class Global : System.Web.HttpApplication
{

    protected void Application_Start(object sender, EventArgs e)
    {
        new CarGroupAppHost().Init();
    }
}

We can found some information about our operations on the url ‘http://server/metadata’, in my case http://localhost:4305/metadata.

Service metadata information

Service metadata information



And that is all, we can test now our service, we will use a Console application.

For example to retrieve all our Car Groups:

string uri = "http://localhost:4305/carGroup";
HttpWebRequest request = HttpWebRequest.CreateHttp(uri);
request.Accept = "application/json";//we only accept JSON
request.Method = "GET";
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
    Console.WriteLine(response.StatusCode);
    using (StreamReader reader = new StreamReader(response.GetResponseStream()))
    {
        string result = reader.ReadToEnd();
        Console.WriteLine(result);
    }
}

And we get:

Get all data service result

Get all data service result



Let’s now test the creation of a new CarGroup:

string uri = "http://localhost:4305/carGroup";
HttpWebRequest request = HttpWebRequest.CreateHttp(uri);
request.Accept = "application/json"; //we only accept JSON
request.Method = "POST";
request.ContentType = "application/json; charset=UTF-8";//we will send JSON

string bodyData = "{\"Name\":\"Super Sport\",\"Category\":\"Mega Sport\"}";

//----- writing data in to the request --------------
request.ContentLength = bodyData.Length;
using (StreamWriter requestWritter = new StreamWriter(request.GetRequestStream()))
{
    requestWritter.Write(bodyData);
}

//----- reading the response
string result = "";
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
    Console.WriteLine(response.StatusCode);
    using (StreamReader reader = new StreamReader(response.GetResponseStream()))
    {
        result = reader.ReadToEnd();
        Console.WriteLine(result);
    }
}

We have just seen how CodeFluent Entities can be easily integrated to ServiceStack.

ServiceStack is a very powerful framework to write Web APIs, you can find more information about ServiceStack and all the features it provides here.

Regards.

Pablo Fernandez Duran

Get started with the CodeFluent Entities API

March 6, 2013 Leave a comment

The CodeFluent Entities API has been around for a while, and this post will help you get started with it! If I tell you that the API is very easy to use and extremely powerful, you will not believe me. Hopefully, you will believe me by the end of this post.

We assume that we have a CodeFluent Entities solution, with its CodeFluent project and its class library for the BOM. We also have created an empty console application.

In this console application, we need to reference 3 libraries:

  • CodeFluent.Model
  • CodeFluent.Model.Common
  • CodeFluent.Runtime

We are now ready to write some code. First we need to load the CodeFluent model, which is a cfp file. This cfp file is an XML file that corresponds to our CodeFluent Entities model:

Project project = new Project();
project.Load(@"c:\path\to\model\myModel.cfp");

The next step is to navigate through the model, and this is where things get easier!

foreach (Entity e in project.Entities)
{
    Console.WriteLine("Entity: " + e.Name);
    foreach (Property p in e.Properties)
    {
        Console.WriteLine(" |- Property: " + p.Name);
        // insert code below here
    }
}

If this code does not try to edit the model, it shows you that the API is very straight forward. In a few lines, the API lets you navigate through every property of every entity of your ALL model! And yes, you can also read every attribute of each property, read the methods, rules…

Now, let us try to modify the model. We will look at the default value of each property, and modify some of them:

if (!string.IsNullOrEmpty(p.DefaultValue))
{
    switch (p.DefaultValue)
    {
        case "MyDefaultTitle":
            Console.Write("DEFAULT VALUE: " + p.DefaultValue + " was changed to: ");
            p.DefaultValue = "Title";
            Console.Write(p.DefaultValue + Environment.NewLine);
            break;
        case "Sample2":
            Console.Write("DEFAULT VALUE: " + p.DefaultValue + " was changed to: ");
            p.DefaultValue = "Sample1";
            Console.Write(p.DefaultValue + Environment.NewLine);
            break;
        case "Sample1":
            Console.Write("DEFAULT VALUE: " + p.DefaultValue + " was changed to: ");
            p.DefaultValue = "Sample2";
            Console.Write(p.DefaultValue + Environment.NewLine);
            break;
    }
}

We are looking for three default values (“MyDefaultTitle”, “Sample1”, “Sample2”) and we are modifying them. There is one last thing to do, which is to save the model.

project.Package.Save();

The save method needs to be inserted at the end of your method, outside the for loops.

In this example, you have learned how to use the API to modify your CodeFluent Entities model. To go further, you could add/edit/delete methods, rules, producers… The possibilities are almost limitless and yet, the API remains very easy to use. Have fun!

Vincent Patry