tag:blogger.com,1999:blog-85225179902911423032024-03-05T15:09:54.222+00:00Web NotesDamian Zapart, Principal Engineering Manager @ Microsoft - official blog.Damian Zaparthttp://www.blogger.com/profile/17026397366973677672noreply@blogger.comBlogger32125tag:blogger.com,1999:blog-8522517990291142303.post-35222263135811554712021-04-04T00:08:00.004+01:002021-04-04T00:08:37.653+01:00Using Newtonsoft serializer in CosmosDB client<h2 style="text-align: left;">Problem</h2><div style="text-align: left;">In some scenarios engineers might want to use a custom JSON serializer for documents stored in CosmosDB. </div><h2 style="text-align: left;">Solution</h2><div style="text-align: left;">In CosmosDBV3 .NET Core API, when creating an instance of <i>CosmosClient </i>one of optional setting in <i>CosmosClientOptions </i>is to specify an instance of a <i>Serializer</i>. This serializer must be JSON based and be of <i>CosmosSerializer </i>type. This means that if a custom serializer is needed this should inherit from <i>CosmosSerializer </i>abstract class and override its two methods for serializing and deserializing of an object. The challenge is that both methods from <i>CosmosSerializer</i> are stream based and therefore might be not as easy to implement as engineers used to assume - still not super complex. <br />For demonstration purpose as or my custom serializer I'm going to use Netwonsoft.JSON library. Firstly a new type is needed and this must inherit from <i>CosmosSerializer. </i></div><p><span style="color: blue; font-family: Consolas; font-size: 13px;">using</span><span style="background-color: white; font-family: Consolas; font-size: 13px;"> Microsoft.Azure.Cosmos;</span></p><pre style="background: white; color: black; font-family: Consolas; font-size: 13px;"><span style="color: blue;">using</span> Newtonsoft.Json;
<span style="color: blue;">using</span> System.IO;
<span style="color: blue;">using</span> System.Text;
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><</span><span style="color: grey;">summary</span><span style="color: grey;">></span>
<span style="color: grey;">///</span><span style="color: green;"> Custom serializer for CosmosDB client.</span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></</span><span style="color: grey;">summary</span><span style="color: grey;">></span>
<span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">SerliarizationService</span> : CosmosSerializer
{
<span style="color: blue;">private</span> <span style="color: blue;">readonly</span> JsonSerializer serializer;
<span style="color: blue;">public</span> <span style="color: #2b91af;">SerliarizationService</span>()
{
<span style="color: blue;">this</span>.serializer = <span style="color: blue;">new</span> JsonSerializer
{
NullValueHandling = NullValueHandling.Ignore
};
}
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><</span><span style="color: grey;">summary</span><span style="color: grey;">></span>
<span style="color: grey;">///</span><span style="color: green;"> Logic for deserialization.</span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></</span><span style="color: grey;">summary</span><span style="color: grey;">></span>
<span style="color: blue;">public</span> <span style="color: blue;">override</span> T <span style="color: #74531f;">FromStream</span><<span style="color: #2b91af;">T</span>>(Stream <span style="color: #1f377f;">stream</span>)
{
<span style="color: #8f08c4;">return</span> <span style="color: blue;">this</span>.serializer.Deserialize<T>(<span style="color: blue;">new</span> JsonTextReader(<span style="color: blue;">new</span> StreamReader(stream)));
}
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><</span><span style="color: grey;">summary</span><span style="color: grey;">></span>
<span style="color: grey;">///</span><span style="color: green;"> Serialization logic.</span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></</span><span style="color: grey;">summary</span><span style="color: grey;">></span>
<span style="color: blue;">public</span> <span style="color: blue;">override</span> Stream <span style="color: #74531f;">ToStream</span><<span style="color: #2b91af;">T</span>>(T <span style="color: #1f377f;">input</span>)
{
<span style="color: blue;">using</span> <span style="color: blue;">var</span> <span style="color: #1f377f;">stringWriter</span> = <span style="color: blue;">new</span> StringWriter();
<span style="color: blue;">using</span> <span style="color: blue;">var</span> <span style="color: #1f377f;">jsonTextWriter</span> = <span style="color: blue;">new</span> JsonTextWriter(stringWriter);
<span style="color: blue;">this</span>.serializer.Serialize(jsonTextWriter, input, input.GetType());
<span style="color: #8f08c4;">return</span> <span style="color: blue;">new</span> MemoryStream(Encoding.UTF8.GetBytes(stringWriter.ToString()));
}
}</pre><div style="text-align: left;">With a custom serialization in place, the only thing to change is to change settings when initializing a new instance of <i>CosmosClient.<br /><br /></i></div>
<pre style="background: white; color: black; font-family: Consolas; font-size: 13px;">cosmosClient = <span style="color: blue;">new</span> CosmosClient(
<span style="color: blue;">this</span>.dbConfig.EndpointUrl,
<span style="color: blue;">this</span>.dbConfig.AuthorizationKey,
<span style="color: blue;">new</span> CosmosClientOptions()
{
Serializer = <span style="color: blue;">new</span> SerliarizationService(),
});</pre><pre style="background: white; color: black; font-family: Consolas; font-size: 13px;"><br /></pre><div style="text-align: left;">Job done.<br />Thank you</div><div style="text-align: left;"><br />/dz</div>Damian Zaparthttp://www.blogger.com/profile/17026397366973677672noreply@blogger.comtag:blogger.com,1999:blog-8522517990291142303.post-79030943530402167882021-03-20T22:45:00.006+00:002021-03-20T22:58:48.415+00:00Persisting Enum in database with Entity Framework<h2 style="text-align: left;">Problem statement</h2><div style="text-align: justify;">We all want to write clean code and follow best coding practices. This all engineers 'North Star' goal which in many cases can not be easily achievable because of many potential difficulties with converting our ideas/good practices into working solutions. </div><div style="text-align: justify;"><br /></div><div style="text-align: justify;">One of an example I recently came across was about using ASP.NET Core and Entity Framework 5 to store Enum values in a relational database (like Azure SQL). Why is this a problem you might ask... and my answer here is that you want to work with Enum types in your code but persist an integer in your databases.</div><div style="text-align: justify;"><br /></div><div style="text-align: justify;">You can think about in that way. Why we use data types at all when everything could be just a string which is getting converted into a desirable type when needed. This 'all-string' approach is of course a huge anti-pattern and a bad practice for many reasons with few being: degraded performance, increased storage space, increased code duplication. </div><div style="text-align: justify;"><br /></div><div style="text-align: justify;"><h3>Pre-requirements</h3></div><div style="text-align: justify;"><b style="text-align: left;">1. Status enum type definition.</b></div><div><div style="text-align: left;">
<pre style="background: white; color: black; font-family: Consolas; font-size: 13px;"><span style="color: blue;">public</span> <span style="color: blue;">enum</span> <span style="color: #2b91af;">Status</span>
{
Undefined,
New,
Processing,
Completed,
Error
}</pre>
</div><div style="text-align: left;"><b>2. Entity class</b></div><div style="text-align: left;"><br /></div><div style="text-align: left;">
<pre style="background: white; color: black; font-family: Consolas; font-size: 13px;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">BackgroudJob</span>
{
<span style="color: blue;">public</span> <span style="color: blue;">int</span> Id { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }
<span style="color: blue;">public</span> <span style="color: #2b91af;">String</span> Title { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }
<span style="color: blue;">public</span> <span style="color: #2b91af;">JobStatus</span> Status { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }
}</pre>
</div><div style="text-align: left;"><b>3 . Azure (or on-prem) SQL super simple table structure. 'Status' column is the one that we will insert our enum into</b><br /><br /></div><div style="text-align: left;"><span style="font-family: Courier New; font-size: 10pt;"><span style="color: blue;">CREATE</span> <span style="color: blue;">TABLE</span> <span style="color: maroon;">[dbo]</span><span style="color: silver;">.</span><span style="color: maroon;">[BackgroudJob]</span><br /> <span style="color: maroon;">(</span><br /> <span style="color: maroon;">[Id]</span> <span style="color: black; font-style: italic;">[INT]</span> <span style="color: blue;">PRIMARY</span> <span style="color: blue;">KEY</span> <span style="color: blue;">NOT</span> <span style="color: blue;">NULL</span> <span style="color: blue;">IDENTITY</span><span style="color: silver;">,</span><br /> <span style="color: maroon;">[Title]</span> <span style="color: black; font-style: italic;">[NVARCHAR]</span><span style="color: maroon;">(</span><span style="color: black;">50</span><span style="color: maroon;">)</span> <span style="color: blue;">NOT</span> <span style="color: blue;">NULL</span><span style="color: silver;">,</span><br /> <span style="color: maroon;">[Status]</span> <span style="color: black; font-style: italic;">[INT]</span> <span style="color: blue;">NOT</span> <span style="color: blue;">NULL</span><br /> <span style="color: maroon;">)</span><span style="color: silver;">;</span> </span></div><div style="text-align: left;"><span style="font-family: Courier New; font-size: 10pt;"><br /></span></div><h3 style="text-align: left;">Recommended solution </h3><div style="text-align: justify;">To me the best solution for this problem is to use a build-in support for Enum persistence which comes with Entity Framework Core and it's about built on the top of a <a href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.storage.valueconversion?view=efcore-5.0" target="_blank">value conversion</a>. </div><div style="text-align: justify;"><br /></div><div style="text-align: justify;">As you can see the above SQL table expects a status of integer type where the entity class stores a status as an Enum. Unfortunately these two types (<i>Integer </i>and <i>JobStatus</i>) are not directly compatible while persisting data. Thankfully one can be easily converted into another in a fully automated and transparent to developers way with use of a native <span style="background-color: white; color: #2b91af; font-family: Consolas; font-size: 13px;"><a href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.storage.valueconversion.enumtonumberconverter-2?view=efcore-5.0" target="_blank">EnumToNumberConverter</a></span>. In order to use it, all is required is to add a specific conversion logic during creation of a DB structure in <a href="https://docs.microsoft.com/en-us/ef/core/modeling/" target="_blank">CodeFirst DB schema creation</a> - it's simple.</div>
<pre style="background: white; color: black; font-family: Consolas; font-size: 13px;"><span style="color: blue;">protected</span> <span style="color: blue;">override</span> <span style="color: blue;">void</span> <span style="color: #74531f;">OnModelCreating</span>(<span style="color: #2b91af;">ModelBuilder</span> <span style="color: #1f377f;">modelBuilder</span>)
{
<span style="color: blue;">base</span>.<span style="color: #74531f;">OnModelCreating</span>(<span style="color: #1f377f;">modelBuilder</span>);
<span style="color: #1f377f;">modelBuilder</span>.<span style="color: #74531f;">Entity</span><<span style="color: #2b91af;">BackgroudJob</span>>(<span style="color: #1f377f;">entity</span> =>
{
<span style="color: #1f377f;">entity</span>.<span style="color: #74531f;">HasKey</span>(<span style="color: #1f377f;">e</span> => <span style="color: #1f377f;">e</span>.Id);
<span style="color: #1f377f;">entity</span>.<span style="color: #74531f;">Property</span>(<span style="color: #1f377f;">e</span> => <span style="color: #1f377f;">e</span>.Title).<span style="color: #74531f;">IsRequired</span>().<span style="color: #74531f;">HasMaxLength</span>(50);
<span style="color: #1f377f;">entity</span>.<span style="color: #74531f;">Property</span>(<span style="color: #1f377f;">e</span> => <span style="color: #1f377f;">e</span>.Status).<span style="color: #74531f;">IsRequired</span>().<span style="color: #74531f;">IsRequired</span>()</pre><pre style="background: white; color: black; font-family: Consolas; font-size: 13px;"><span> </span><span> </span><span> </span><span> </span><span> </span><b><span> </span>.<span style="color: #74531f;">HasConversion</span>(<span style="color: blue;">new</span> <span style="color: #2b91af;">EnumToNumberConverter</span><<span style="color: #2b91af;">JobStatus</span>, <span style="color: blue;">int</span>>());</b>
});
}</pre>
<div style="text-align: left;"><span style="font-family: Courier New; font-size: 10pt;"><br /></span></div><b>Pros</b></div><div><ul style="text-align: left;"><li>Conversion logic is centralized</li><li>Logic is transparent to developer</li><li>No need to a 'manual' enum to int (and vice versa) conversion explicitly in the code</li><li>Less extra code to test</li><li>Use of native framework</li></ul><div><b>Cons</b></div></div><div><ul style="text-align: left;"><li>Logic is not really transparent</li><li>Custom converters might be needed for complex use cases</li></ul><div><br /></div></div><h3 style="text-align: justify;">Another solution #1 - manual conversion to integer (not recommended)<br /><br /></h3><div>Manual conversion solution is about changing a type from enum to integer (or string) explicitly in code. This conversion should be of course centralized but unfortunately this might not be possible in the case when logic for accessing persistence layer is all around a project code. It might also requires to create a separated data transfer object (DTO) class and perform a mapping from underlying entity into DTO. It will looks something like this. </div><div><br /></div><div><br />Thank you.</div><div><br /></div><div>/dz<br /><br /></div>Damian Zaparthttp://www.blogger.com/profile/17026397366973677672noreply@blogger.comDublin, Ireland53.3498053 -6.260309725.039571463821154 -41.4165597 81.660039136178852 28.8959403tag:blogger.com,1999:blog-8522517990291142303.post-54282810593507852672017-09-17T22:06:00.000+01:002017-09-17T22:06:42.490+01:00Runtime generated objects serializationIf you think in a generic way about all well implemented RESTful APIs you will find a pattern that can be easily described and stored in metadata. Most RESTful API is just a combination of the following elements:<br />
<br />
<ul>
<li>Resource location (URL)</li>
<li>HTTP method</li>
<li>Header information</li>
<li>Input parameters (required and optional)</li>
<li>Content type</li>
<li>Output parameters</li>
<li>Business logic description</li>
</ul>
<br />
<div style="text-align: justify;">
Today I would like to discuss an interesting problem that I came across recently. Imagine for a second that you need to implement a RESTful API client which uses a combination of metadata which describes API and a user input in order to make a HTTP calls. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
In such a scenario you will quickly realize that for a subset of API calls you will need to develop a custom classes in order to have them later serialized (to JSON or XML) in runtime so that you can send it via POST or PUT requests. This rises a question. Do I really need to implement N - 1 classes that represent all types that some API(s) expect(s) as a part of HTTP request body?</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Well, maybe. In my case I decided to use a more generic approach and leverage a simplicity of standard data formats like JSON. The '<i>hack</i>' is very simple. From a serialization point of view any class is just a container for properties of specific type - methods and interfaces we can skip as its have nothing to do with serialization. Lets than simplify a class generic description. A class is a collection or key-value pairs. Sounds similar isn't it? Maybe it sounds like JSON format description? This is correct...milestone achieved. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
We already know that we have a key-value pair type of collection. How to describe it from a data structure perspective? Very simple! Actually so simple that we have more than one option available.<br />
<br />
We can use the followings:</div>
<div style="text-align: justify;">
</div>
<ul>
<li>Dictionary<string,object></li>
<li>dynamic type</li>
<li>Anonymous types and var </li>
</ul>
<div>
Other:</div>
<ul>
<li>Approach with <b>List<Tuple<string,object>></b> does not work! A result JSON has a structure with a property names like Item1, Item2....expected.</li>
</ul>
<div>
<i>[{"Item1":"Name","Item2":"Damian"},{"Item1":"Surname","Item2":"Damian"},{"Item1":"Age","Item2":12},{"Item1":"Books","Item2":["Book 1","Book 2"]}]</i></div>
<ul>
<li>If you know any other method (even crazy and geeky version) please let me know. Just don't send a one with reflection...</li>
</ul>
<div>
OK. It's time to serialize out classes.</div>
<div>
<br /></div>
<div>
<b>1. By using Dictionary<string, object></b></div>
<div>
<br /></div>
<pre style="background: white; color: black; font-family: "consolas"; font-size: 13;"><span style="color: green;"> // Dictionary approach</span>
<span style="color: #2b91af;">Dictionary</span><<span style="color: blue;">string</span>, <span style="color: #2b91af;">Object</span>> userDict = <span style="color: blue;">new</span> <span style="color: #2b91af;">Dictionary</span><<span style="color: blue;">string</span>, <span style="color: blue;">object</span>>();
userDict.Add(<span style="color: #a31515;">"Name"</span>, <span style="color: #a31515;">"Damian"</span>);
userDict.Add(<span style="color: #a31515;">"Surname"</span>, <span style="color: #a31515;">"Zapart"</span>);
userDict.Add(<span style="color: #a31515;">"Age"</span>, 12);
userDict.Add(<span style="color: #a31515;">"Books"</span>, <span style="color: blue;">new</span> <span style="color: #2b91af;">List</span><<span style="color: #2b91af;">String</span>> { <span style="color: #a31515;">"Book 1"</span>, <span style="color: #a31515;">"Book 2"</span> });
<span style="color: #2b91af;">JsonConvert</span>.SerializeObject(userDict);</pre>
<div>
<br />
<b>2. By using a dynamic type</b><br />
<br />
<pre style="background: white; color: black; font-family: "consolas"; font-size: 13;"><span style="color: green;"> // Dynamic type approach</span>
<span style="color: blue;">dynamic</span> user = <span style="color: blue;">new</span>
{
Name = <span style="color: #a31515;">"Damian"</span>,
Surname = <span style="color: #a31515;">"Zapart"</span>,
Age = 12,
Books = <span style="color: blue;">new</span> <span style="color: #2b91af;">List</span><<span style="color: #2b91af;">String</span>> { <span style="color: #a31515;">"Book 1"</span>, <span style="color: #a31515;">"Book 2"</span> },
};
<span style="color: #2b91af;">JsonConvert</span>.SerializeObject(user);</pre>
<pre style="background: white; color: black; font-family: "consolas"; font-size: 13;"></pre>
<pre style="background: white; color: black; font-family: "consolas"; font-size: 13;"></pre>
<pre style="background: white; color: black; font-family: "consolas"; font-size: 13;"></pre>
</div>
<b><br /></b>
<b>3. By using anonymous types</b><br />
<br />
<pre style="background: white; color: black; font-family: "consolas"; font-size: 13;"><span style="color: green;"> // Anonymous approach</span>
<span style="color: blue;">var</span> userAnonymous = <span style="color: blue;">new</span>
{
Name = <span style="color: #a31515;">"Damian"</span>,
Surname = <span style="color: #a31515;">"Zapart"</span>,
Age = 12,
Books = <span style="color: blue;">new</span> <span style="color: #2b91af;">List</span><<span style="color: #2b91af;">String</span>> { <span style="color: #a31515;">"Book 1"</span>, <span style="color: #a31515;">"Book 2"</span> }
};</pre>
<br />
And we done! Was a pleasure. Next time will focus on a performance of each solution.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg924JfILhhj6IN82rbIy_43n4OikdcMYhdxgvvd077Pu5VVIHXlkaloeYfjiaYPo61ElVljuQWC1VGSv_1wNg6blBX1p1q_t43_MqOVcV6qUGdj2n6P-4vHBsQ0D_2tRxADftQbI5AO_he/s1600/Capture.PNG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="224" data-original-width="228" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg924JfILhhj6IN82rbIy_43n4OikdcMYhdxgvvd077Pu5VVIHXlkaloeYfjiaYPo61ElVljuQWC1VGSv_1wNg6blBX1p1q_t43_MqOVcV6qUGdj2n6P-4vHBsQ0D_2tRxADftQbI5AO_he/s1600/Capture.PNG" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Result JSON.</td></tr>
</tbody></table>
<br />Damian Zaparthttp://www.blogger.com/profile/17026397366973677672noreply@blogger.comtag:blogger.com,1999:blog-8522517990291142303.post-55995406371402149652016-09-28T05:47:00.000+01:002017-08-27T15:10:53.740+01:00Deep dive in unit testing<div dir="ltr" style="line-height: 1.2; margin-bottom: 14pt; margin-top: 5pt; text-align: justify;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">These days each product reaching market is labelled as top quality - no matter if it`s a toy or a car or an application. Everyone talk about quality, quality is everywhere and at the same time quality by nature is a tricky thing to define and measure. To give you an example, imagine a two new brand cars from a two different car manufacturers like for example BMW and Fiat. Dealers of both brands will tell you that their cars are</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> top quality</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> and in fact that is true! The problem starts when you try to understand what top quality means for both car manufacturers - what are their standards of quality. What Fiat can consider as top quality might be completely not acceptable for BMW. From client perspective what really important is to understand how to measure quality in a standards driven way. As an example let's compare a </span><a href="https://en.wikipedia.org/wiki/Euro_NCAP" style="text-decoration: none;"><span style="background-color: transparent; color: blue; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">European car safety performance assessment</span></a><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> rating for both brands (NCAP is rated from 1 to 5 stars where 5 stars is given for most safety cars). In this rating cars manufactured by Fiat sometimes get 5 stars but usually it`s below 5. At the same time BMW gets must get 5 otherwise car won’t be released. Please remember that both car manufacturers claims their car to be top quality (!!) and without having a </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">standard</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> in place (like NCAP) from client perspective it`s difficult to understand quality standards baseline for each brand.</span></div>
<div dir="ltr" style="line-height: 1.2; margin-bottom: 14pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Having a common standards is also very important in the software development world as the same quality rules applies to all software products. All applications or systems might be considered as top quality as without common standards it`s just matter of defining what the quality means. For example having only one production outage per week might be considered as top quality by some teams when other teams do not tolerate any outage at all. </span></div>
<div dir="ltr" style="line-height: 1.2; margin-bottom: 14pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">"</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">A unit test is an automated piece of code that invokes a unit of work in the system and then checks a single assumption about the behaviour of that unit of work</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">" (</span><a href="http://artofunittesting.com/definition-of-a-unit-test/" style="text-decoration: none;"><span style="background-color: transparent; color: blue; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">Unit Testing Lessons in Ruby, Java and .NET - The Art Of Unit Testing - Definition of a Unit Test</span></a><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">). Above definition describes unit test to be a piece of code calling other small (atomic) piece of product code under test. For people who are new in development process this might sound very bizarre as a benefit of having unit tests in a project is not clearly defined. However unit tests are one of the most useful and powerfully tool in the developer hands. The advantages of having unit tests implemented are:</span></div>
<ul style="margin-bottom: 0pt; margin-top: 0pt;">
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Cut dependencies</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> - the most powerful feature of unit tests is that a piece of code can be executed in isolation (without dependencies fully in place) by using mock(s). Mock objects are simulated objects that mimic the behaviour of real objects in controlled ways. Therefore a product code which for example makes call to external API or database can be easily tested by 'mocking dependencies' (without a need of having other components setup) in such case dependencies still exists but it replaced by mock object.</span></div>
</li>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Execution time</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> - unit tests are fast, really fast. Short time of a test execution is achieved by cutting dependencies and isolating code which allows to execute entire test in memory - without any network traffic.</span></div>
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<ins class="adsbygoogle"
style="display:block"
data-ad-format="fluid"
data-ad-layout="image-side"
data-ad-layout-key="-fg+5r+6l-ft+4e"
data-ad-client="ca-pub-2921101697945774"
data-ad-slot="9471661303"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
</li>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Fail fast</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> - by the nature of defects, it`s more expensive and time consuming to fix potential bug in Production or UAT rather than on local development environment. Unit tests help in detection of defects at very early stage of development process. As per fast execution time and mocks each developer can run unit tests on local environment. However this manual activity (it`s good habit) can be easily automated as all unit tests can be executed as a part of gated check-in build in TFS (code commit process). In such a scenario a code change will be accepted only if all unit tests will pass.</span></div>
</li>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Continuous delivery -</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> as unit test are self-contained and therefore don`t need any pre-existing data in order to execute. This feature allow to run it as a part of continuous delivery process straight after code merge between for example UAT and Production branches. Such an approach allows to ensure that code merge did not introduce any unexpected regression or defect.</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><br class="kix-line-break" /></span></div>
</li>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Enforces good design</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> - implementing unit tests it not that easy but it`s not hard as well. Certain product code architecture must be put in place prior to writing tests itself. Thankfully just by following </span><a href="https://en.wikipedia.org/wiki/SOLID_(object-oriented_design)" style="text-decoration: none;"><span style="background-color: transparent; color: blue; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">SOLID </span></a><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">principles code unit testability can be achieved pretty fast. Moreover what is important is that following SOLID principles makes code even more open for change (agile) as well as easier to maintenance. </span></div>
</li>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Facilitates change -</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> introducing any change is any piece of code always brings a risk. This risk can be easily mitigated when product has high </span><a href="https://en.wikipedia.org/wiki/Code_coverage" style="text-decoration: none;"><span style="background-color: transparent; color: blue; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">unit test coverage</span></a><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">. Running unit tests after completing development changes on a local development environment can help to identify potential regression in a code and fix it straightaway. </span></div>
</li>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.2; margin-bottom: 14pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Allow to measure code coverage –</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> running a unit tests against source code under test provides a useful matrix of a percentage of executed (tested) lines of code by subset of unit tests per project.</span></div>
</li>
</ul>
<div dir="ltr" style="line-height: 1.2; margin-bottom: 14pt; margin-left: 36pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: transparent; color: black; font-family: "calibri"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><img height="219" src="https://lh4.googleusercontent.com/lhPGV-Vtkc1H2eUoc6CtlTdBdKWSKdweCvi-7c_qW02KkfMSPGOdh7IZeVknD-ngtOuArUs_advdhYkummfCvYiTz-wOmTEMjNp7vA6Y0v0Szd9hOHImjq54jZjyjfwCgMCRzByitMbDypo_qg" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="602" /></span></div>
<b id="docs-internal-guid-cb0dda3e-6f1d-b1e9-21c8-cce35d5c2f07" style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.2; margin-bottom: 14pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">I already described what unit tests are and how can be used to improve a product quality. However at this stage there are three additional questions in regards to unit testing:</span></div>
<div dir="ltr" style="line-height: 1.2; margin-bottom: 14pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Q: Who should develop unit tests?</span></div>
<div dir="ltr" style="line-height: 1.2; margin-bottom: 14pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">A</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">: In Agile Scrum world there is no separation in a team for Developer and Tester roles – all members of a developments teams are consider to be developers. To answer this question I encourage you to think about unit testing as way for developers (all team members) to proof that code works as expected. This means that is up to each team member who introduced any change in the code to actually add/modify/deprecate relevant unit tests. Without following such an approach developer cannot proof that code he/she implemented is actually functional. The good practice here is to change a standard development process (implement code -> test code) and start using a </span><a href="https://en.wikipedia.org/wiki/Test-driven_development" style="text-decoration: none;"><span style="background-color: transparent; color: blue; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">TDD</span></a><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> (Test Driven Development) approach. Additionally the TDD approach help to solve another common problem with testing which is about time allocation. Unfortunately it`s very common patter across agile development teams to actually deprioritize (drop) testing work at the end of sprit under pressure of deadlines. With TDD tests goes first (before actual product code change) so that time allocation is always there. </span></div>
<div dir="ltr" style="line-height: 1.2; margin-bottom: 14pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">In summary unit tests verifies quality of both code changes and overall product. It should be up to entire development team to make sure that enough time is allocated for testing and tests are implemented on time for each change.</span></div>
<div dir="ltr" style="line-height: 1.2; margin-bottom: 14pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Q: How to encourage your team to implement unit tests?</span></div>
<div dir="ltr" style="line-height: 1.2; margin-bottom: 14pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">A</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">: A short answer is that you should not have to do that. All developers should understand how beneficial is to actually have unit tests in place. Unfortunately this is not always true and in some cases a mentoring effort is required in order to explain to your team the benefits of unit testing. Additionally other aspects of software development process like </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">code reviews</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> and measuring </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">code coverage</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> during build might be used.</span></div>
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<ins class="adsbygoogle"
style="display:block"
data-ad-format="fluid"
data-ad-layout="image-side"
data-ad-layout-key="-fg+5r+6l-ft+4e"
data-ad-client="ca-pub-2921101697945774"
data-ad-slot="9471661303"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
<div dir="ltr" style="line-height: 1.2; margin-bottom: 14pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Q: When to run unit tests?</span></div>
<div dir="ltr" style="line-height: 1.2; margin-bottom: 14pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">A</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">: The beauty of unit tests is that it’s very fast and easy to run. As unit tests use mock to cut dependencies each developer can run thousands of it from his/her local development environment in a few seconds. This is very powerful tool as by being able to run set of tests against a project with a high code coverage means that each developer can check impact of a code change on entire product. This gives all team members a great tool which helps to avoid regressions in product code so that they can save more time. Additionally unit tests can be executed automatically by </span><a href="https://en.wikipedia.org/wiki/Continuous_integration" style="text-decoration: none;"><span style="background-color: transparent; color: blue; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">CI</span></a><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> as a part of change commit to code repository (code check-in) so that breaking code change has no chance to get into repository as it will be rejected in a case of unit test failure.</span></div>
<div dir="ltr" style="line-height: 1.2; margin-bottom: 14pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">The last question remains. Is it worth to make investment in unit tests? </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Of course it is!</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> It’s never too late to bring some improvements for both your product and your team. Time invested in unit tests implementation might initially significant but will reduce in time and investment will certainly pay off. </span></div>
<br />Damian Zaparthttp://www.blogger.com/profile/17026397366973677672noreply@blogger.comtag:blogger.com,1999:blog-8522517990291142303.post-59602059053302917452015-02-08T16:14:00.002+00:002015-02-08T16:14:20.748+00:00Using Hortonworks Hive in .NET<div style="text-align: justify;">
A few months ago I decided to learn a big data. This sounds very complex and of course it is. All these <a href="http://www.bigdata-madesimple.com/hadoop-glossary-20-most-important-terms/">strange names</a> which actually tells nothing to person who is new in these area combined with different way of looking at data storage makes entire topic even more complex. However after reading N blogs and watching many, many tutorials today I finally had a chance to try to write some code. As in last week I managed to setup a <a href="http://hortonworks.com/" target="_blank">Hortonworks </a>distribution of Hadoop today I decided to connect to it from my <a href="http://www.microsoft.com/net">.NET</a> based application and this is what I will describe in this post.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
First things first I didn`t setup entire Hortonworks ecosystem from scratch - I`d love to but for now it`s far beyond my knowledge thus I decided to use a <a href="http://hortonworks.com/products/hortonworks-sandbox/#install">sandbox environment</a> provided by Hortonworks. There are multiple different VMs available to download but in my case I`ve choose a Hyper-V. More about setting this environment up you can read <a href="http://hortonworks.com/wp-content/uploads/unversioned/pdfs/InstallingHortonworksSandbox2onWindowsusingHyper-V.pdf">here</a>.</div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8r-zHjcuiY5ZVbG_9GCFXji0t9GqR85yyzq9bHCfXZ-dIuM2RAT8DxIsLp-j0k_x9v2AiL5TSZgXfJ-yLv7Q6tdTRlRr2Xh5JhtBPvll28u5kf4uuAXM-wQr94xYsqngIfCzOoUXTsi07/s1600/hortonworks.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8r-zHjcuiY5ZVbG_9GCFXji0t9GqR85yyzq9bHCfXZ-dIuM2RAT8DxIsLp-j0k_x9v2AiL5TSZgXfJ-yLv7Q6tdTRlRr2Xh5JhtBPvll28u5kf4uuAXM-wQr94xYsqngIfCzOoUXTsi07/s1600/hortonworks.png" height="400" width="368" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Picture 1. Up and running sandbox environment.<br />
<br /></td></tr>
</tbody></table>
<div style="text-align: justify;">
Now when I have my big data store ready I need to be able to establish a connection to it and start exchanging data. The problem is that Hadoop is not a database rather that that it`s a distributed file system (<a href="http://hadoop.apache.org/docs/r1.2.1/hdfs_design.html">HDFS</a>) and <a href="http://en.wikipedia.org/wiki/MapReduce">map reduce</a> engine so non of these fits my need directly. The tools that I`m looking for is called <a href="https://hive.apache.org/">Hive</a> which is data warehouse infrastructure built on top of Hadoop. Hive provides a SQL like syntax (called HiveQL) which I can use as in the case of normal database. To learn more about Hive syntax, data types and concept I`d stronly recommend <a href="https://cwiki.apache.org/confluence/display/Hive/Tutorial#Tutorial-MultiTable/FileInserts">this tutorial</a>.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
OK, so far so good. I decided that I`m going to use Hive as my warehouse that I will be connecting to from my .NET based application. The next step is to take care about a data provider which is a something like a driver that allow my code to interact with Hive. Of course there is no native .NET provider for Hive but this is where <a href="http://en.wikipedia.org/wiki/Open_Database_Connectivity">ODBC </a>middle-ware API plays a part. The end-to-end <a href="http://hortonworks.com/wp-content/uploads/2013/04/Hortonworks-Hive-ODBC-Driver-User-Guide.pdf">tutorial </a>how to download and setup ODBC drivers for Hortonworks Hive allowed me to set it up pretty easily and fast so I could focus on the last part which is a C# code.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjYjUjTLu26rNt9IsTSZufU0zRu76uS-Eh_fYRJosDo9yrQJIdzAZ6cPjWakhyphenhyphenPxWybcCMO8TZscHW6f9E4EzthQNz4GBv_hzBgSDs2Y7TRLlvYEgx4zjndYg4CIm0AfXq6S6T-honD92Y/s1600/odbc.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjYjUjTLu26rNt9IsTSZufU0zRu76uS-Eh_fYRJosDo9yrQJIdzAZ6cPjWakhyphenhyphenPxWybcCMO8TZscHW6f9E4EzthQNz4GBv_hzBgSDs2Y7TRLlvYEgx4zjndYg4CIm0AfXq6S6T-honD92Y/s1600/odbc.png" height="368" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Picture 2. Hortonworks Hive ODBC Driver setup.<br />
<br /></td></tr>
</tbody></table>
<div style="text-align: justify;">
For all developers who have at least some experience with ADO.NET or ODBC programming writing code for communicating with Hive should be very straightforward as overall concept as well as classes are exactly the same. First of all I need to have a connection string to my instance of Hive and I can build it very easily in two ways:</div>
<div style="text-align: justify;">
</div>
<ul>
<li>Just by specifying a predefined (Picture 2.) DNS name: <i>dsn=Hadoop ODBC</i></li>
<li>By specifying all properties directly in the connection string:
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"><span style="color: blue;">var</span> connectionString = <span style="color: #a31515;">@"DRIVER={Hortonworks Hive ODBC Driver}; </span>
<span style="color: #a31515;"> Host=192.168.56.101;</span>
<span style="color: #a31515;"> Port=10000;</span>
<span style="color: #a31515;"> Schema=default;</span>
<span style="color: #a31515;"> HiveServerType=2;</span>
<span style="color: #a31515;"> ApplySSPWithQueries=1;</span>
<span style="color: #a31515;"> AsyncExecPollInterval=100;</span>
<span style="color: #a31515;"> HS2AuthMech=2;</span>
<span style="color: #a31515;"> UserName=sandbox;"</span>;</pre>
</li>
</ul>
<div>
<span style="font-family: Consolas;"><span style="font-size: 13px; white-space: pre;"><br /></span></span></div>
One way or another after setting up connection string the following steps in my code are:<br />
<div>
1) Opening a connection to Hive.</div>
<div>
2) Creating a simple Hive table called 'Searches' which contains 3 columns plus one partition column called <span style="background-color: white; color: #a31515; font-family: Consolas; font-size: 13px;">searchTime</span>.</div>
<div>
3) Inserting data to 'Searches' table.</div>
<div>
4) Retrieving data from 'Searches' table by using a simple Hive SELECT query and <a href="https://msdn.microsoft.com/en-us/library/system.data.odbc.odbcdatareader%28v=vs.110%29.aspx">OdbcDataReader </a>class.</div>
<div>
5) Dropping a 'Searches' table.</div>
<div>
<br /></div>
<div>
The full code for my solution is presented below.</div>
<div>
<br /></div>
<div>
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"><span style="color: blue;">namespace</span> Hadoopclient
{
<span style="color: blue;">using</span> System;
<span style="color: blue;">using</span> System.Data.Odbc;
<span style="color: blue;">class</span> <span style="color: #2b91af;">Program</span>
{
<span style="color: blue;">static</span> <span style="color: blue;">void</span> Main(<span style="color: blue;">string</span>[] args)
{
<span style="color: green;">// @"dsn=Hadoop ODBC"</span>
<span style="color: blue;">var</span> connectionString = <span style="color: #a31515;">@"DRIVER={Hortonworks Hive ODBC Driver}; </span>
<span style="color: #a31515;"> Host=192.168.56.101;</span>
<span style="color: #a31515;"> Port=10000;</span>
<span style="color: #a31515;"> Schema=default;</span>
<span style="color: #a31515;"> HiveServerType=2;</span>
<span style="color: #a31515;"> ApplySSPWithQueries=1;</span>
<span style="color: #a31515;"> AsyncExecPollInterval=100;</span>
<span style="color: #a31515;"> HS2AuthMech=2;</span>
<span style="color: #a31515;"> UserName=sandbox;"</span>;
<span style="color: blue;">var</span> createTableCommandText = <span style="color: #a31515;">"CREATE TABLE Searches(searchTerm STRING, userid BIGINT,userIp STRING) "</span> +
<span style="color: #a31515;">"COMMENT 'Stores all searches for data' "</span> +
<span style="color: #a31515;">"PARTITIONED BY(searchTime DATE) "</span> +
<span style="color: #a31515;">"STORED AS SEQUENCEFILE;"</span>;
<span style="color: blue;">using</span> (<span style="color: blue;">var</span> connection = <span style="color: blue;">new</span> <span style="color: #2b91af;">OdbcConnection</span>(connectionString))
{
<span style="color: blue;">using</span> (<span style="color: blue;">var</span> command = <span style="color: blue;">new</span> <span style="color: #2b91af;">OdbcCommand</span>(createTableCommandText, connection))
{
<span style="color: blue;">try</span>
{
connection.Open();
<span style="color: green;">// Create a table.</span>
command.ExecuteNonQuery();
<span style="color: green;">// Insert row of data.</span>
command.CommandText = <span style="color: #a31515;">"INSERT INTO TABLE Searches PARTITION (searchTime = '2015-02-08') "</span> +
<span style="color: #a31515;">"VALUES ('search term', 1, '127.0.0.1')"</span>;
command.ExecuteNonQuery();
<span style="color: green;">// Reading data from Hadoop.</span>
command.CommandText = <span style="color: #a31515;">"SELECT * FROM Searches"</span>;
<span style="color: blue;">using</span> (<span style="color: blue;">var</span> reader = command.ExecuteReader())
{
<span style="color: blue;">while</span> (reader.Read())
{
<span style="color: blue;">for</span> (<span style="color: blue;">var</span> i = 0; i < reader.FieldCount; i++)
{
<span style="color: #2b91af;">Console</span>.WriteLine(reader[i]);
}
}
}
}
<span style="color: blue;">catch</span> (<span style="color: #2b91af;">OdbcException</span> ex)
{
<span style="color: #2b91af;">Console</span>.WriteLine(ex.Message);
<span style="color: blue;">throw</span>;
}
<span style="color: blue;">finally</span>
{
<span style="color: green;">// Drop table</span>
command.CommandText = <span style="color: #a31515;">"DROP TABLE Searches"</span>;
command.ExecuteNonQuery();
}
}
}
}
}
}
</pre>
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;">
</pre>
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;">
</pre>
Thank you.</div>
Damian Zaparthttp://www.blogger.com/profile/17026397366973677672noreply@blogger.comtag:blogger.com,1999:blog-8522517990291142303.post-75947190597212725662014-12-04T04:57:00.004+00:002014-12-04T04:57:52.042+00:00Multithread processing of the SqlDataReader - Producer/Consumer design pattern<div style="text-align: justify;">
In today post I want to describe how to optimize usage of a ADO.NET <a href="http://msdn.microsoft.com/library/system.data.sqlclient.sqldatareader(v=vs.110).aspx" target="_blank">SqlDataReader</a> class by using multi-threading. To present that lets me introduce a problem that I will try to solve. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<b>Scenario</b>:</div>
<div style="text-align: justify;">
In a project we decided to move all data from a multiple databases to one data warehouse. It will be a good few terabytes of data or even more. Data transfer will be done by using a custom importer program.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<b>Problem</b>:</div>
<div style="text-align: justify;">
After implementing a database agnostic logic of generating and executing a query I realized that I can retrieve data from source databases faster that I can upload them to big data store through HTTP client -importer program. In other words, data reader is capable of reading data faster then I can process it an upload to my big data lake.</div>
<div style="text-align: justify;">
<br /></div>
<div>
<b>Solution</b>:<br />
As a solution for solving this problem I would like to propose one of a multi-thread design pattern called <a href="http://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem" target="_blank">Producer/Consumer</a>. In general this pattern consists of a two main classes where:<br />
<ul>
<li><b>Producer </b>class is responsible for adding a new items to a shared collection</li>
<li><b>Consumer </b>class is responsible for retrieving items from the collection and processing them in a specific way.</li>
</ul>
<div>
<div style="text-align: justify;">
There is also a third component in this pattern which allows to share data between both consumer and producer - it`s a thread safe collection. Of course there can be multiple consumers and multiple producers working in the same time concurrently however the most important part is that no matter how many threads have been created all share the same collection. </div>
</div>
<div>
<div style="text-align: justify;">
<br /></div>
</div>
<div>
<div style="text-align: justify;">
Using this solution will help me to speedup my upload process because a producer class will be adding a new records the shared collection and at the same time multiple consumers treads will be reading from it and processing items one by one.</div>
</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSaHgzhBCBoRRv0a9-2fDfDCkyBtwUGjcmc1AZlNdzhtzwibf8pGM403Kunnrs0b_KN9AnUnQg_ZPl9J6M9mjCGyX9-z2cXJCVayxhwSQsJWoivR9xu3RTBL_cpmW3WwVzEkuFVeIN02q0/s1600/Untitled.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSaHgzhBCBoRRv0a9-2fDfDCkyBtwUGjcmc1AZlNdzhtzwibf8pGM403Kunnrs0b_KN9AnUnQg_ZPl9J6M9mjCGyX9-z2cXJCVayxhwSQsJWoivR9xu3RTBL_cpmW3WwVzEkuFVeIN02q0/s1600/Untitled.png" height="376" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Picture 1. Consumer producer design pattern basic schema.</td></tr>
</tbody></table>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<b>Implementation</b>:</div>
<div class="separator" style="clear: both; text-align: justify;">
To implement this design pattern I created a really simple console application and apart from the Program.cs class, which centralizes a program logic, I put there just a few more files. Firstly I implemented a thread-safe collection because as I mentioned it will be a place to share data between instances of producer and consumer(s). As my collection I`ve chosen a <a href="http://msdn.microsoft.com/en-us/library/dd267312%28v=vs.110%29.aspx" target="_blank">BlockinCollection<T></a> type from the <b>System.Collections.Concurrent </b>namespace as it`s purely designed to be used in the consumer producer design pattern implementation. At the same time it provides both a set of list like functions for adding and retrieving items in a thread-safe way and exposes a design pattern specific elements such a <b>CompleteAdding() </b>function or <b>IsAddingCompleted </b>property (the purpose of this elements is to allow producer class notify one or more consumers that items adding has been finished and consumer thread(s) should be completed). Therefore I put this collection in a new class and wrap it so then my code for my <b>ItemCollection<T></b> class looks as follow:</div>
</div>
<div>
<br /></div>
<div>
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"><span style="color: blue;"> using</span> System;
<span style="color: blue;">using</span> System.Collections.Concurrent;
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span>
<span style="color: grey;">///</span><span style="color: green;"> An items collection.</span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><typeparam name=</span><span style="color: grey;">"T"</span><span style="color: grey;">></span><span style="color: green;">Type of the item.</span><span style="color: grey;"></typeparam></span>
<span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">ItemCollection</span><T>
{
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span>
<span style="color: grey;">///</span><span style="color: green;"> The internal collection of items.</span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span>
<span style="color: blue;">private</span> <span style="color: #2b91af;">BlockingCollection</span><T> collection;
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span>
<span style="color: grey;">///</span><span style="color: green;"> Gets the collection upper bound.</span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><value></span>
<span style="color: grey;">///</span><span style="color: green;"> The upper bound.</span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></value></span>
<span style="color: blue;">public</span> <span style="color: blue;">uint</span> UpperBound { <span style="color: blue;">get</span>; <span style="color: blue;">private</span> <span style="color: blue;">set</span>; }
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span>
<span style="color: grey;">///</span><span style="color: green;"> Gets a value indicating whether this adding to the collection has been completed.</span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span>
<span style="color: blue;">public</span> <span style="color: blue;">bool</span> IsAddingCompleted
{
<span style="color: blue;">get</span>
{
<span style="color: blue;">return</span> <span style="color: blue;">this</span>.collection.IsAddingCompleted;
}
}
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span>
<span style="color: grey;">///</span><span style="color: green;"> Initializes a new instance of the </span><span style="color: grey;"><see cref=</span><span style="color: grey;">"ItemCollection{T}"</span><span style="color: grey;">/></span><span style="color: green;"> class.</span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><param name=</span><span style="color: grey;">"upperBound"</span><span style="color: grey;">></span><span style="color: green;">The collection upper bound.</span><span style="color: grey;"></param></span>
<span style="color: blue;">public</span> ItemCollection(<span style="color: blue;">uint</span> upperBound = 25)
{
<span style="color: blue;">this</span>.UpperBound = upperBound;
<span style="color: blue;">this</span>.collection = <span style="color: blue;">new</span> <span style="color: #2b91af;">BlockingCollection</span><T>((<span style="color: blue;">int</span>)<span style="color: blue;">this</span>.UpperBound);
}
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span>
<span style="color: grey;">///</span><span style="color: green;"> Adds the specified item.</span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><param name=</span><span style="color: grey;">"item"</span><span style="color: grey;">></span><span style="color: green;">The item.</span><span style="color: grey;"></param></span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><param name=</span><span style="color: grey;">"timeoutMiliseconds"</span><span style="color: grey;">></span><span style="color: green;">The timeout miliseconds.</span><span style="color: grey;"></param></span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><returns></span><span style="color: green;">Adding result.</span><span style="color: grey;"></returns></span>
<span style="color: blue;">public</span> <span style="color: blue;">bool</span> TryAdd(T item, <span style="color: blue;">int</span> timeoutMiliseconds)
{
<span style="color: blue;">var</span> addResult = <span style="color: blue;">this</span>.collection.TryAdd(item, timeoutMiliseconds);
<span style="color: blue;">if</span> (!addResult)
{
<span style="color: blue;">throw</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">InvalidOperationException</span>(<span style="color: #a31515;">"Unable to add item to collection."</span>);
}
<span style="color: blue;">return</span> addResult;
}
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span>
<span style="color: grey;">///</span><span style="color: green;"> Try to take an item from collection.</span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><param name=</span><span style="color: grey;">"timeoutMiliseconds"</span><span style="color: grey;">></span><span style="color: green;">The timeout miliseconds.</span><span style="color: grey;"></param></span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><returns></span><span style="color: green;">An instance of the item.</span><span style="color: grey;"></returns></span>
<span style="color: blue;">public</span> T TryTake(<span style="color: blue;">int</span> timeoutMiliseconds)
{
<span style="color: blue;">var</span> result = <span style="color: blue;">default</span>(T);
<span style="color: blue;">if</span> (!<span style="color: blue;">this</span>.collection.TryTake(<span style="color: blue;">out</span> result, timeoutMiliseconds))
{
<span style="color: blue;">throw</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">InvalidOperationException</span>(<span style="color: #a31515;">"Unable to get item from collection."</span>);
}
<span style="color: blue;">return</span> result;
}
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span>
<span style="color: grey;">///</span><span style="color: green;"> Completes the process of adding.</span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span>
<span style="color: blue;">public</span> <span style="color: blue;">void</span> CompleteAdding()
{
<span style="color: blue;">this</span>.collection.CompleteAdding();
}
}</pre>
</div>
<div>
<br /></div>
<div>
<div style="text-align: justify;">
When my collection is ready a next step is to fill it with data. To do that I implemented a producer class which internally starts a new thread and within it in while loop it`s keeps adding items to the collection as long as evaluated producing function returned false. In such case it`s calling the</div>
</div>
<div>
<div style="text-align: justify;">
<b>CompleteAdding() </b>function on<b> ItemCollection<T></b> class to let consumers know that there will be no more items added to it. I mentioned about a 'producing function' above so just to make it clear in my producer class constructor I expect a <b>Func<T></b> definition. I done that as I want to keep producer logic generic so it can be use in multiple scenarios - in this case passed function comes from main thread and it`s responsible for retrieving data from a source database.</div>
<br /></div>
<div>
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"><span style="color: grey;"> ///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span>
<span style="color: grey;">///</span><span style="color: green;"> The items producer.</span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span>
<span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">Producer</span><T>
<span style="color: blue;">where</span> T : <span style="color: blue;">class</span>, <span style="color: blue;">new</span>()
{
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span>
<span style="color: grey;">///</span><span style="color: green;"> The collection.</span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span>
<span style="color: blue;">private</span> <span style="color: blue;">readonly</span> <span style="color: #2b91af;">ItemCollection</span><T> collection;
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span>
<span style="color: grey;">///</span><span style="color: green;"> The producing function.</span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span>
<span style="color: blue;">private</span> <span style="color: blue;">readonly</span> <span style="color: #2b91af;">Func</span><T> producingFunction;
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span>
<span style="color: grey;">///</span><span style="color: green;"> Initializes a new instance of the </span><span style="color: grey;"><see cref=</span><span style="color: grey;">"Producer{T}"</span><span style="color: grey;">/></span><span style="color: green;"> class.</span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><param name=</span><span style="color: grey;">"producingFunction"</span><span style="color: grey;">></span><span style="color: green;">The producing function.</span><span style="color: grey;"></param></span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><param name=</span><span style="color: grey;">"collection"</span><span style="color: grey;">></span><span style="color: green;">The collection.</span><span style="color: grey;"></param></span>
<span style="color: blue;">public</span> Producer(<span style="color: #2b91af;">Func</span><T> producingFunction, <span style="color: #2b91af;">ItemCollection</span><T> collection)
{
<span style="color: blue;">if</span> (producingFunction == <span style="color: blue;">null</span>)
{
<span style="color: blue;">throw</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">ArgumentNullException</span>(<span style="color: #a31515;">"producingFunction"</span>);
}
<span style="color: blue;">if</span> (collection == <span style="color: blue;">null</span>)
{
<span style="color: blue;">throw</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">ArgumentNullException</span>(<span style="color: #a31515;">"collection"</span>);
}
<span style="color: blue;">this</span>.collection = collection;
<span style="color: blue;">this</span>.producingFunction = producingFunction;
}
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span>
<span style="color: grey;">///</span><span style="color: green;"> Starts producing items.</span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span>
<span style="color: blue;">public</span> <span style="color: blue;">void</span> Start()
{
<span style="color: #2b91af;">Task</span>.Factory.StartNew(() =>
{
<b> <span style="color: blue;">while</span> (<span style="color: blue;">this</span>.Produce())</b>
{
<span style="color: blue;">continue</span>;
}
<b> <span style="color: blue;">this</span>.collection.CompleteAdding();</b>
});
}
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span>
<span style="color: grey;">///</span><span style="color: green;"> Produces this item.</span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><returns></span><span style="color: green;">True is item has been produced and added to collection.</span><span style="color: grey;"></returns></span>
<span style="color: blue;">public</span> <span style="color: blue;">bool</span> Produce()
{
<span style="color: blue;">var</span> producingResult = <b><span style="color: blue;">this</span>.producingFunction.Invoke();</b>
<span style="color: blue;">var</span> result = <span style="color: blue;">false</span>;
<span style="color: blue;">if</span> (producingFunction != <span style="color: blue;">default</span>(T))
{
result = <span style="color: blue;">this</span>.collection.TryAdd(producingResult, (<span style="color: blue;">int</span>)<span style="color: #2b91af;">TimeSpan</span>.FromSeconds(10).TotalMilliseconds);
}
<span style="color: blue;">return</span> result;
}
}</pre>
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;">
</pre>
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"></pre>
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"></pre>
<div style="text-align: justify;">
The last part of the design pattern is a consumer. I implemented it similarly to the producer and in the class constructor I expect a definition of an Action<T> which I invoke to consume the item from the shared collection.</div>
</div>
<div>
<br /></div>
<div>
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"><span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span>
<span style="color: grey;">///</span><span style="color: green;"> A consumer class.</span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><typeparam name=</span><span style="color: grey;">"T"</span><span style="color: grey;">></span><span style="color: green;">Type of the object to process.</span><span style="color: grey;"></typeparam></span>
<span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">Consumer</span><T>
<span style="color: blue;">where</span> T : <span style="color: blue;">class</span>, <span style="color: blue;">new</span>()
{
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span>
<span style="color: grey;">///</span><span style="color: green;"> The collection.</span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span>
<span style="color: blue;">private</span> <span style="color: blue;">readonly</span> <span style="color: #2b91af;">ItemCollection</span><T> collection;
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span>
<span style="color: grey;">///</span><span style="color: green;"> The consuming function.</span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span>
<span style="color: blue;">private</span> <span style="color: blue;">readonly</span> <span style="color: #2b91af;">Action</span><T> consumingAction;
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span>
<span style="color: grey;">///</span><span style="color: green;"> Initializes a new instance of the </span><span style="color: grey;"><see cref=</span><span style="color: grey;">"Consumer{T}"</span><span style="color: grey;">/></span><span style="color: green;"> class.</span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><param name=</span><span style="color: grey;">"collection"</span><span style="color: grey;">></span><span style="color: green;">The collection.</span><span style="color: grey;"></param></span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><param name=</span><span style="color: grey;">"consumingFunction"</span><span style="color: grey;">></span><span style="color: green;">The consuming function.</span><span style="color: grey;"></param></span>
<span style="color: blue;">public</span> Consumer(<span style="color: #2b91af;">ItemCollection</span><T> collection, <span style="color: #2b91af;">Action</span><T> consumingFunction)
{
<span style="color: blue;">if</span> (collection == <span style="color: blue;">null</span>)
{
<span style="color: blue;">throw</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">ArgumentNullException</span>(<span style="color: #a31515;">"collection"</span>);
}
<span style="color: blue;">if</span> (collection == <span style="color: blue;">null</span>)
{
<span style="color: blue;">throw</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">ArgumentNullException</span>(<span style="color: #a31515;">"consumingFunction"</span>);
}
<span style="color: blue;">this</span>.collection = collection;
<span style="color: blue;">this</span>.consumingAction = consumingFunction;
}
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span>
<span style="color: grey;">///</span><span style="color: green;"> Consumes this item from collection.</span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span>
<span style="color: blue;">public</span> <span style="color: blue;">void</span> Consume()
{
<span style="color: blue;">var</span> instance = <span style="color: blue;">default</span>(T);
<b> <span style="color: blue;">while</span> (!<span style="color: blue;">this</span>.collection.IsAddingCompleted)</b>
{
instance = <span style="color: blue;">this</span>.collection.TryTake((<span style="color: blue;">int</span>)<span style="color: #2b91af;">TimeSpan</span>.FromMinutes(1).TotalMilliseconds);
<span style="color: blue;">if</span> (instance != <span style="color: blue;">null</span>)
{
<b> <span style="color: blue;">this</span>.consumingAction.Invoke(instance);</b>
}
<span style="color: blue;">else</span>
{
<span style="color: blue;">throw</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">InvalidOperationException</span>(<span style="color: #a31515;">"Unable to get item from collection."</span>);
}
}
}
}</pre>
</div>
<div>
<br />
<div style="text-align: justify;">
Lastly, in the Program.cs I put all the logic required to married all pieces together. As you may notice in the code below I put a producing and consuming function definitions in this class body. Moreover instead of using just a single thread for consumer I decided to start multiple - where the number of threads is equal to number of cores on the host.</div>
<br />
<br /></div>
<div>
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"><span style="color: blue;">static</span> <span style="color: blue;">void</span> Main(<span style="color: blue;">string</span>[] args)
{
<span style="color: blue;">var</span> itemCollection = <span style="color: blue;">new</span> <span style="color: #2b91af;">ItemCollection</span><<span style="color: #2b91af;">User</span>>();
<span style="color: blue;">var</span> consumerTasks = <span style="color: blue;">new</span> <span style="color: #2b91af;">List</span><<span style="color: #2b91af;">Task</span>>();
<span style="color: blue;">var</span> connection = <span style="color: blue;">new</span> <span style="color: #2b91af;">SqlConnection</span>(args[0]);
connection.Open();
<span style="color: blue;">var</span> dataReader = GetDataReader(connection);
<span style="color: green;">// Producer initialization.</span>
<span style="color: blue;">var</span> producer = <span style="color: blue;">new</span> <span style="color: #2b91af;">Producer</span><<span style="color: #2b91af;">User</span>>(() =>
{
<span style="color: #2b91af;">User</span> user = <span style="color: blue;">null</span>;
<span style="color: blue;">if</span> (dataReader.Read())
{
user = <span style="color: blue;">new</span> <span style="color: #2b91af;">User</span>()
{
Id = dataReader.GetInt32(0),
Name = dataReader.GetString(1),
Surname = dataReader.GetString(2),
Email = dataReader.GetString(3)
};
}
<span style="color: blue;">return</span> user;
}, itemCollection);
<b> producer.Start();</b>
<span style="color: green;">// One task perc logical processor.</span>
<span style="color: #2b91af;">Enumerable</span>.Range(0, System.<span style="color: #2b91af;">Environment</span>.ProcessorCount)
.ToList()
.ForEach(i =>
{
<b> <span style="color: blue;">var</span> consumer = <span style="color: blue;">new</span> <span style="color: #2b91af;">Consumer</span><<span style="color: #2b91af;">User</span>>(itemCollection, user =>
{
<span style="color: #2b91af;">Program</span>.InsertToBigData(user);
});
<span style="color: green;">// Start consumption.</span>
consumerTasks.Add(<span style="color: #2b91af;">Task</span>.Factory.StartNew(() => { consumer.Consume(); }));</b>
});
<span style="color: green;">// Waiting for all tasks to complete.</span>
<b><span style="color: #2b91af;">Task</span>.WhenAll(consumerTasks.ToArray())</b>
.ContinueWith((task) =>
{
<span style="color: blue;">if</span> (!dataReader.IsClosed)
{
dataReader.Close();
}
connection.Close();
connection.Dispose();
});
}</pre>
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;">
</pre>
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;">
</pre>
Thank you<pre style="background: white; color: black; font-family: Consolas; font-size: 13;">
</pre>
</div>
Damian Zaparthttp://www.blogger.com/profile/17026397366973677672noreply@blogger.comDublin, Ireland53.3498053 -6.260309699999993453.0446728 -6.9085031999999931 53.6549378 -5.6121161999999938tag:blogger.com,1999:blog-8522517990291142303.post-20736561375317276762014-10-05T18:04:00.000+01:002014-10-05T18:04:52.618+01:00Asynchronous WebApi2 HTTP client example<div style="text-align: justify;">
Today I want to cover a very common scenario about how to create a HTTP client for a WebAPI 2 service. To present my implementation I will be using one of a Task<T> <a href="http://dzapart.blogspot.ie/2014/10/a-task-chaining-refactoring-with-example.html" target="_blank">extension method</a> that I described recently on my blog.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Let`s start from defining an API service. In this example it udes a REST based WebApi service with the following implementation.</div>
<br />
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"> [<span style="color: #2b91af;">AllowAnonymous</span>]
<span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">CityController</span>
{
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span>
<span style="color: grey;">///</span><span style="color: green;"> The city repository.</span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span>
<span style="color: blue;">private</span> <span style="color: blue;">readonly</span> <span style="color: #2b91af;">ICityRepository</span> cityRepository;
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span>
<span style="color: grey;">///</span><span style="color: green;"> Initializes a new instance of the </span><span style="color: grey;"><see cref=</span><span style="color: grey;">"CityController"</span><span style="color: grey;"> /></span><span style="color: green;"> class.</span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><param name=</span><span style="color: grey;">"cityRepository"</span><span style="color: grey;">></span><span style="color: green;">The city repository.</span><span style="color: grey;"></param></span>
<span style="color: blue;">public</span> CityController(<span style="color: #2b91af;">ICityRepository</span> cityRepository)
{
<span style="color: blue;">this</span>.cityRepository = cityRepository;
}
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span>
<span style="color: grey;">///</span><span style="color: green;"> Return a list of cities.</span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><param name=</span><span style="color: grey;">"query"</span><span style="color: grey;">></span><span style="color: green;">The query.</span><span style="color: grey;"></param></span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><returns></span>
<span style="color: grey;">///</span><span style="color: green;"> A list of </span><span style="color: grey;"><see cref=</span><span style="color: grey;">"Users"</span><span style="color: grey;"> /></span><span style="color: green;">.</span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></returns></span>
[<span style="color: #2b91af;">HttpGet</span>]
[<span style="color: #2b91af;">Route</span>(<span style="color: #a31515;">"api/"</span> + <span style="color: #2b91af;">ApiVersion</span>.CurrentVersion + <span style="color: #a31515;">"/cities"</span>)]
<span style="color: blue;">public</span> <span style="color: blue;">async</span> <span style="color: #2b91af;">Task</span><<span style="color: #2b91af;">HttpResponseMessage</span>> Get(<span style="color: blue;">string</span> query)
{
<span style="color: blue;">return</span> <span style="color: blue;">await</span> <span style="color: blue;">this</span>.cityRepository.AutocompleteCityAsync(query)
.Continue<<span style="color: #2b91af;">IQueryable</span><<span style="color: #2b91af;">City</span>>, <span style="color: #2b91af;">HttpResponseMessage</span>>(entities =>
{
<span style="color: blue;">var</span> cities = entities.MapCollection<<span style="color: #2b91af;">TCity</span>>();
<span style="color: blue;">return</span> <span style="color: blue;">this</span>.CreateListResponse<<span style="color: #2b91af;">TCity</span>>(cities);
});
}</pre>
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"> }</pre>
<br />
<div style="text-align: justify;">
As you can see there is no any big deal there. I created a <i>CityController </i>class which is decorated with an attribute <i><a href="http://www.davidhayden.me/blog/asp.net-mvc-4-allowanonymous-attribute-and-authorize-attribute" target="_blank">AllowAnonymous</a></i>. This will tell a WebApi engine that all functions inside this controller may be accessed by anonymous user - not logged in. Next, the controller class initialization accepts an one parameter of <i>ICityRepository </i>which is nothing else than a simple implementation of a <a href="http://www.asp.net/mvc/tutorials/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application" target="_blank">Repository Pattern</a> for Entity Framework. A fact that I passing an instance of this repository as a constructor parameter means that I used in my solution an <a href="http://www.codeproject.com/Articles/29271/Design-pattern-Inversion-of-control-and-Dependency" target="_blank">Inversion of Control (IoC)</a> and <a href="http://www.asp.net/web-api/overview/advanced/dependency-injection" target="_blank">Dependency Injection</a> (I recommend here using <a href="https://unity.codeplex.com/" target="_blank">Unity</a> as it`s the simplest one as far as I check) - this post doesn`t cover an implementation details for both patterns however I will try to create post about it soon and link it here. Now, coming back to <i>CityController</i>... it has one public function which is a WebApi service call for a GET (decorated by the attribute <i><a href="http://msdn.microsoft.com/en-us/library/microsoft.activities.messaging.httpget(v=azure.10).aspx" target="_blank">HttpGet</a></i><span style="background-color: white; color: #2b91af; font-family: Consolas; font-size: 13px;">)</span> request for the URL<i> GET/ http://{url}/api/v1/cities?query={query} </i>(<i><a href="http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2" target="_blank">Route</a></i> attribute). This function is also an asynchronous one, which means that it`s returning a <i>Task<T> </i>type which in this case is a <i>Task<HttpResponseMessage></i>. The body of it uses a task chaining implementation (with my custom <a href="http://dzapart.blogspot.ie/2014/10/a-task-chaining-refactoring-with-example.html" target="_blank">Continue<T,R> </a>extension method) to call the <i>AutocompleteCityAsync</i> repository method and map results returned by it to a TCity data transfer object by using the <a href="http://automapper.codeplex.com/" target="_blank">AutoMapper</a>.<br />
<br /></div>
<div style="text-align: justify;">
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"><span style="color: blue;">using</span> BookingWorld.Common.Interfaces.Entities;
<span style="color: blue;">using</span> System.Runtime.Serialization;
[<span style="color: #2b91af;">DataContract</span>]
<span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">TCity</span>
{
<span style="color: blue;">public</span> TCity()
{ }
[<span style="color: #2b91af;">DataMember</span>]
<span style="color: blue;">public</span> <span style="color: blue;">string</span> Code { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }
[<span style="color: #2b91af;">DataMember</span>]
<span style="color: blue;">public</span> <span style="color: blue;">decimal</span> Latitude { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }
[<span style="color: #2b91af;">DataMember</span>]
<span style="color: blue;">public</span> <span style="color: blue;">decimal</span> Longitude { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }
[<span style="color: #2b91af;">DataMember</span>]
<span style="color: blue;">public</span> <span style="color: blue;">decimal</span>? Scoring { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }
[<span style="color: #2b91af;">DataMember</span>]
<span style="color: blue;">public</span> <span style="color: blue;">bool</span> CapitalCity { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }
[<span style="color: #2b91af;">DataMember</span>]
<span style="color: blue;">public</span> <span style="color: blue;">int</span> QueryCount { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }
[<span style="color: #2b91af;">DataMember</span>]
<span style="color: blue;">public</span> <span style="color: blue;">string</span> Name { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }
[<span style="color: #2b91af;">DataMember</span>]
<span style="color: blue;">public</span> <span style="color: blue;">int</span> Id { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }
[<span style="color: #2b91af;">DataMember</span>]
<span style="color: blue;">public</span> <span style="color: blue;">bool</span> Active { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }
}</pre>
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"></pre>
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"></pre>
<div style="text-align: justify;">
By nature the WebApi2 service serializes all responses objects to JSON format. This is a very important part that developer has to know to implement working client. In this example my GET request will return a serialized collection on <i>TCiti </i>objects. Now I described a service logic so it`s time to start writing more about a client itself.<br />
<br />
There is no strict rules how to consume a WebApi service. As it`s build at the top of standard HTTP <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html" target="_blank">request methods</a> and uses a JSON format of data it`s completely platform agnostic. It`s means that you can send request to it from non-.NET platform like iOS or Android mobile device and as long as you`re using the same standards you will get an response. However in this example the client of this API is a <a href="http://www.asp.net/mvc/tutorials/mvc-5/introduction/getting-started" target="_blank">MVC5</a> based website (this really doesn`t matter what is the version, the only this which is important is that it`s based on .NET Framework 4.5.1). First of all let`s introduce a service proxy base class - this is the code of the implementation and later calling a specific API function is just a matter of changing an input parameters.<br />
<br />
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">Proxy</span>
{
<span style="color: blue;">public</span> <span style="color: #2b91af;">IDictionary</span><<span style="color: blue;">string</span>, <span style="color: blue;">object</span>> Parameters { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span>
<span style="color: grey;">///</span><span style="color: green;"> The </span><span style="color: grey;"><see cref=</span><span style="color: grey;">"HttpClient"</span><span style="color: grey;">/></span><span style="color: green;"> used for communicating with the API.</span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span>
<span style="color: blue;">private</span> <span style="color: #2b91af;">HttpClient</span> httpClient;
<span style="color: blue;">public</span> <span style="color: #2b91af;">Uri</span> ServiceUrl
{
<span style="color: blue;">get</span>;
<span style="color: blue;">private</span> <span style="color: blue;">set</span>;
}
<span style="color: blue;">public</span> <span style="color: blue;">string</span> ControllerName
{
<span style="color: blue;">get</span>;
<span style="color: blue;">private</span> <span style="color: blue;">set</span>;
}
<span style="color: blue;">protected</span> Proxy(<span style="color: blue;">string</span> serviceBase, <span style="color: blue;">string</span> controllerName)
{
<span style="color: blue;">this</span>.ServiceUrl = <span style="color: blue;">new</span> <span style="color: #2b91af;">Uri</span>(serviceBase);
<span style="color: blue;">this</span>.httpClient = <span style="color: blue;">new</span> <span style="color: #2b91af;">HttpClient</span>();
<span style="color: blue;">this</span>.ControllerName = controllerName;
<span style="color: blue;">this</span>.Parameters = <span style="color: blue;">new</span> <span style="color: #2b91af;">Dictionary</span><<span style="color: blue;">string</span>, <span style="color: blue;">object</span>>();
}
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span>
<span style="color: grey;">///</span><span style="color: green;"> Sends a GET request to the API.</span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><typeparam name=</span><span style="color: grey;">"TReturnType"</span><span style="color: grey;">></span><span style="color: green;">The type of the return type.</span><span style="color: grey;"></typeparam></span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><param name=</span><span style="color: grey;">"getUri"</span><span style="color: grey;">></span><span style="color: green;">The GET URI.</span><span style="color: grey;"></param></span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><returns></span><span style="color: green;">A task which results in a {TReturnType} object.</span><span style="color: grey;"></returns></span>
<span style="color: blue;">protected</span> <span style="color: blue;">async</span> <span style="color: #2b91af;">Task</span><TReturnType> GetAsync<TReturnType>(<span style="color: #2b91af;">Uri</span> getUri)
<span style="color: blue;">where</span> TReturnType : <span style="color: blue;">class</span>, <span style="color: blue;">new</span>()
{
<span style="color: blue;">return</span> <span style="color: blue;">await</span> <span style="color: blue;">this</span>.httpClient.<b>GetAsync</b>(getUri)
.Continue<<span style="color: #2b91af;">HttpResponseMessage</span>, <span style="color: blue;">string</span>>(
httpResponseMessage =>
{
<span style="color: blue;">if</span> (httpResponseMessage.StatusCode.IsServerErrorCode())
{
<span style="color: blue;">throw</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">Exception</span>(httpResponseMessage.ReasonPhrase);
}
<span style="color: blue;">if</span> (httpResponseMessage.StatusCode.IsSuccessCode())
{
<span style="color: blue;">if</span> (<span style="color: blue;">typeof</span>(TReturnType) == <span style="color: blue;">typeof</span>(<span style="color: blue;">string</span>))
{
<span style="color: blue;">return</span> <span style="color: blue;">this</span>.httpClient.GetStringAsync(getUri) <span style="color: blue;">as</span> <span style="color: #2b91af;">Task</span><<span style="color: blue;">string</span>>;
}
<span style="color: blue;">return</span> httpResponseMessage.Content.ReadAsStringAsync();
}
<span style="color: blue;">return</span> <span style="color: #2b91af;">Task</span>.FromResult(<span style="color: blue;">string</span>.Empty);
}).<b>Continue</b><<span style="color: blue;">string</span>, TReturnType>(resultJson =>
{
<span style="color: blue;">var</span> result = <span style="color: blue;">default</span>(TReturnType);
<span style="color: blue;">if</span> (!<span style="color: blue;">string</span>.IsNullOrWhiteSpace(resultJson))
{
result = Newtonsoft.Json.<span style="color: #2b91af;">JsonConvert</span></pre>
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"> .<b>DeserializeObject</b><TReturnType>(resultJson);
}
<span style="color: blue;">return</span> result;
});
}</pre>
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"></pre>
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"></pre>
<br />
As you can see my proxy is not a very sophisticated implementation. It contains three very import parts:<br />
<br />
1) It uses a<i> <a href="http://httpclient./">HttpClient.</a><a href="http://msdn.microsoft.com/en-us/library/system.net.http.httpclient.getasync(v=vs.118).aspx">GetAsync</a></i><span style="background-color: white; font-family: Consolas; font-size: 13px;"> </span>function which is a .NET native code which will start first asynchronous task.<br />
<br />
2) <i>Continue<string,TReturnType> </i>- this is my own implementation of a wrapper around <i>ContinueWith</i> native .NET function which simplify accessing a request results. In that case this function has two generic types: a string (JSON string returned from the API) and <i>TReturnType </i> type that JSON will be deserialized to.<br />
<br />
3) Object deserialization - this is crucial step when a JSON will be <a href="http://james.newtonking.com/json/help/index.html" target="_blank">transformed</a> into a <i>TReturnType.</i><br />
<i><br /></i>
Presented class in a very generic one. It`s not related to any API as it`s configured by the parameters of derived classes (please note that it`s has a protected constructor). Now when we have it implemented it`s a piece of cake to implement a client for a City API.<br />
<br />
However before I present an API specific proxy class I want to mention one more thing. In my option it`s obvious thing that most of an API calls passes some parameters to it. In the case the GET request these parameters are part of the query string (part of URL). To centralized implementation of constructing a request URL for a particular API call in the <i>Proxy</i> base class I implemented a function presented below which build a request URL based on the parameters stored in the base class <i>Parameters</i> property of dictionary type<span style="background-color: white; font-family: Consolas; font-size: 13px;">.</span><br />
<br />
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"><span style="color: blue;">protected</span> <span style="color: #2b91af;">Uri</span> BuildRequestUri()
{
<span style="color: blue;">var</span> stringBuilder = <span style="color: blue;">new</span> <span style="color: #2b91af;">StringBuilder</span>(<span style="color: blue;">this</span>.ServiceUrl.ToString());
stringBuilder.Append(<span style="color: blue;">this</span>.ControllerName);
<span style="color: blue;">if</span> (<span style="color: blue;">this</span>.Parameters != <span style="color: blue;">null</span> && <span style="color: blue;">this</span>.Parameters.Any())
{
stringBuilder.Append(<span style="color: #a31515;">"?"</span>);
<span style="color: blue;">foreach</span> (<span style="color: blue;">var</span> parameter <span style="color: blue;">in</span> <span style="color: blue;">this</span>.Parameters)
{
stringBuilder.AppendFormat(<span style="color: #a31515;">"{0}={1}"</span>, parameter.Key, parameter.Value);
<span style="color: blue;">if</span> (parameter.Key != <span style="color: blue;">this</span>.Parameters.Last().Key)
{
stringBuilder.Append(<span style="color: #a31515;">"&"</span>);
}
}
}
<span style="color: blue;">this</span>.Parameters.Clear();
<span style="color: blue;">return</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">Uri</span>(stringBuilder.ToString());
}</pre>
<br />
Finally it`s time to present a API specific version of the client. It`s very tiny, don`t you think? Yes, it`s is because most of the logic I put in the base class already and this derived class is only responsible for passing proper set of parameters to it parent. In that case <i>CityProxy</i> accepts an API top level URL i.e. <i>http://www.api.com/api/v1/. </i>Also in the constructor it passes a controller specific name - in that case it`s '<i>cities</i>' as I specified in the <i>Route</i> attribute in service definition. Now, it the <i>GetCities</i> function I can pass query to look-up for a city and next it will be converted to the query string parameter by the <i>BuildRequestUri</i> function from base. Lastly I await a <i>GetAsync</i><span style="background-color: white; font-family: Consolas; font-size: 13px;"> </span>function and pass a type of response (<i>List<TCity></i><span style="background-color: white; font-family: Consolas; font-size: 13px;">)</span>that response JSON will be deserialized to.<br />
<br />
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"><span style="color: blue;"> using</span> BookingWorld.Common.Proxy;
<span style="color: blue;">using</span> BookingWorld.Common.Types;
<span style="color: blue;">using</span> System.Collections.Generic;
<span style="color: blue;">using</span> System.Collections.ObjectModel;
<span style="color: blue;">using</span> System.Threading.Tasks;
<span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">CityProxy</span> : <span style="color: #2b91af;">Proxy</span>
{
<span style="color: blue;">public</span> CityProxy(<span style="color: blue;">string</span> baseUrl)
: <span style="color: blue;">base</span>(baseUrl, <span style="color: #a31515;">"cities"</span>)
{
}
<span style="color: blue;">public</span> <span style="color: blue;">async</span> <span style="color: #2b91af;">Task</span><<span style="color: #2b91af;">List</span><<span style="color: #2b91af;">TCity</span>>> GetCities(<span style="color: blue;">string</span> query)
{
<span style="color: blue;">this</span>.Parameters.Add(<span style="color: #a31515;">"query"</span>, query);
<span style="color: blue;">var</span> requestUri = <span style="color: blue;">this</span>.BuildRequestUri();
<span style="color: blue;">return</span> <span style="color: blue;">await</span> <span style="color: blue;">this</span>.GetAsync<<span style="color: #2b91af;">List</span><<span style="color: #2b91af;">TCity</span>>>(requestUri);
}
}</pre>
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;">
</pre>
For those who are looking for more, I also implemented a POST.<br />
<br /></div>
</div>
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"><span style="color: grey;"> ///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span>
<span style="color: grey;">///</span><span style="color: green;"> Performs an asynchronous POST of the supplied object to the given URI.</span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><typeparam name=</span><span style="color: grey;">"TPostObjectType"</span><span style="color: grey;">></span><span style="color: green;">Type of the object to POST.</span><span style="color: grey;"></typeparam></span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><typeparam name=</span><span style="color: grey;">"TReturnType"</span><span style="color: grey;">></span><span style="color: green;">Type of the object to read from the returned POST operation.</span><span style="color: grey;"></typeparam></span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><param name=</span><span style="color: grey;">"postUri"</span><span style="color: grey;">></span><span style="color: green;">The POST uri.</span><span style="color: grey;"></param></span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><param name=</span><span style="color: grey;">"objectToPost"</span><span style="color: grey;">></span><span style="color: green;">The actual object to POST.</span><span style="color: grey;"></param></span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><returns></span>
<span style="color: grey;">///</span><span style="color: green;"> A </span><span style="color: grey;"><see cref=</span><span style="color: grey;">"Task{TReturnType}"</span><span style="color: grey;"> /></span><span style="color: green;"> from posting the object.</span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></returns></span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><exception cref=</span><span style="color: grey;">"System.ArgumentNullException"</span><span style="color: grey;">></span><span style="color: green;">postUri</span><span style="color: grey;"></exception></span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><remarks></span>
<span style="color: grey;">///</span><span style="color: green;"> Use this version of POST if the type of object returned in the</span>
<span style="color: grey;">///</span><span style="color: green;"> POST response is different from the object that was posted.</span>
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></remarks></span>
<span style="color: blue;">protected</span> <span style="color: blue;">async</span> <span style="color: #2b91af;">Task</span><TReturnType> PostAsync<TPostObjectType, TReturnType>(
<span style="color: #2b91af;">Uri</span> postUri,
TPostObjectType objectToPost)
<span style="color: blue;">where</span> TReturnType : <span style="color: blue;">class</span>
{
<span style="color: blue;">if</span> (postUri == <span style="color: blue;">null</span>)
{
<span style="color: blue;">throw</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">ArgumentNullException</span>(<span style="color: #a31515;">"postUri"</span>);
}
<span style="color: blue;">var</span> jsonToPost = Newtonsoft.Json.<span style="color: #2b91af;">JsonConvert</span>.SerializeObject(objectToPost);
<span style="color: blue;">var</span> content = <span style="color: blue;">new</span> <span style="color: #2b91af;">StringContent</span>(jsonToPost);
<span style="color: blue;">return</span> <span style="color: blue;">await</span> <span style="color: blue;">this</span>.httpClient.PostAsync(postUri.AbsoluteUri, content)</pre>
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"> .Continue<<span style="color: #2b91af;">HttpResponseMessage</span>, <span style="color: blue;">string</span>>(
httpResponseMessage =>
{
<span style="color: blue;">if</span> (httpResponseMessage.StatusCode.IsServerErrorCode())
{
<span style="color: blue;">throw</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">Exception</span>(httpResponseMessage.ReasonPhrase);
}
<span style="color: blue;">if</span> (httpResponseMessage.StatusCode.IsSuccessCode())
{
<span style="color: blue;">return</span> httpResponseMessage.Content.ReadAsStringAsync();
}
<span style="color: blue;">return</span> <span style="color: #2b91af;">TaskCreator</span>.Completed<<span style="color: blue;">string</span>>(<span style="color: blue;">string</span>.Empty);
})</pre>
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"> .Continue<<span style="color: blue;">string</span>, TReturnType>(resultJson =>
{
<span style="color: blue;">var</span> result = <span style="color: blue;">default</span>(TReturnType);
<span style="color: blue;">if</span> (!<span style="color: blue;">string</span>.IsNullOrWhiteSpace(resultJson))
{
result = Newtonsoft.Json.<span style="color: #2b91af;">JsonConvert</span></pre>
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"> .DeserializeObject<TReturnType>(resultJson);
}
<span style="color: blue;">return</span> result;
});
}</pre>
Damian Zaparthttp://www.blogger.com/profile/17026397366973677672noreply@blogger.comDublin, Ireland53.3498053 -6.260309699999993453.0463133 -6.9057566999999933 53.6532973 -5.6148626999999935tag:blogger.com,1999:blog-8522517990291142303.post-91648287870346471522014-10-05T13:45:00.001+01:002014-10-05T14:55:51.241+01:00A Task chaining refactoring with an example<div style="text-align: justify;">
This was a very long break since I posted my last web note however it`s time to share some fresh experience with the developer community. Today I want to show one of a handy solution which allowed me to simplify a <a href="http://msdn.microsoft.com/en-us/library/system.threading.tasks.task(v=vs.110).aspx" target="_blank">Task</a> chaining in .NET 4.5.1.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Let`s start from defining a problem which in this case is a <i><a href="http://msdn.microsoft.com/en-us/library/dd321405(v=vs.110).aspx" target="_blank">Task.ContinueWith<TResult></a></i> method and the way how it`s designed for a tasks chaining. So if you want to use a chaining by using this function, all the time you need to access a parent task result property which in many cases causes a lot of redundancy in the code. To demonstrate this I use a simple <i>async </i>WebApi2 GET cities auto-complete function which will query a database and later map result set of entities to collection of data transfer objects (DTO).</div>
<br />
<span style="background-color: red;">// !!BADLY DESIGNED CODE!!</span><br />
<span style="background-color: white; font-family: Consolas; font-size: 13px;">[</span><span style="color: #2b91af; font-family: Consolas; font-size: 13px;">HttpGet</span><span style="background-color: white; font-family: Consolas; font-size: 13px;">]</span><br />
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"><span style="color: blue;">public</span> <span style="color: blue;">async</span> <span style="color: #2b91af;">Task</span><<span style="color: #2b91af;">HttpResponseMessage</span>> Get(<span style="color: blue;">string</span> query)
{</pre>
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"> <span style="color: blue;">return</span> <span style="color: blue;">await</span> <span style="color: blue;">this</span>.cityRepository</pre>
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"> .AutocompleteCityAsync(query)</pre>
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"> .<b>ContinueWith<<span style="color: #2b91af;">HttpResponseMessage</span>></b>(<b>parentTask </b>=></pre>
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"> {</pre>
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"> <span style="color: blue;">var</span> cities = parentTask.<b>Result</b>.MapCollection<<span style="color: #2b91af;">TCity</span>>();</pre>
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"></pre>
<pre style="background: white; font-family: Consolas; font-size: 13px;"><pre style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; color: black; font-family: Consolas;"> //Returns HttpResponseMessage.</pre>
<span style="color: blue;">return</span> <span style="color: blue;">this</span>.CreateListResponse<<span style="color: #2b91af;">TCity</span>>(cities);
});
}</pre>
<br />
<div style="text-align: justify;">
As you can see in the example above by awaiting a <i>citiRepository.AutocompleteCityAsync</i><span style="background-color: white; font-family: Consolas; font-size: 13px;"> </span>function I started an asynchronous operation (Task). When this function returns a result a next piece of code going to be invoked as I used a <i>ContinueWith<T> </i>function where <i>T</i> is a type of results that my continuation code returns. The problem is that in chained code I need to deal with a previous task itself and the only way to retrieve result of it is to access a <i>Result </i>property directly.</div>
<br />
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"><span style="color: blue;">public</span> <span style="color: blue;">static</span> <span style="color: #2b91af;">Task</span><TNewResult> Continue<TResult, TNewResult>(</pre>
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"><span style="color: blue;"> this</span> <span style="color: #2b91af;">Task</span><TResult> task,</pre>
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"> <span style="color: #2b91af;">Func</span><TResult, <span style="color: #2b91af;">Task</span><TNewResult>> continuation)
{
<span style="color: blue;">if</span> (task == <span style="color: blue;">null</span>)
{
<span style="color: blue;">throw</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">ArgumentNullException</span>(<span style="color: #a31515;">"task"</span>);
}
<span style="color: blue;">if</span> (continuation == <span style="color: blue;">null</span>)
{
<span style="color: blue;">throw</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">ArgumentNullException</span>(<span style="color: #a31515;">"continuation"</span>);
}
<span style="color: blue;">return</span> task
.<b>ContinueWith</b>(innerTask => continuation(innerTask.Result))
.<b>Unwrap</b>();
}</pre>
<br />
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The continuation code can be easily re-factored by creating a simple extension method for a <b>Task<T> </b>type. As presented in code above, just by centralizing a call of the <i>ContinueWith </i>function with a custom continuation function followed by a <i><a href="http://msdn.microsoft.com/en-us/library/dd780917(v=vs.110).aspx" target="_blank"><b>Unwrap</b></a> </i>method a chaining become much cleaner. So then a <i>Continue<TResult, TNewResult> </i>function knows a type of result from a parent task and also know what type a continuation code going to return. Therefor let`s use it an see how a chaining looks like after I use my extension method. Please note that I`m not accessing a parent Task.Result directly and instead of this I working just with a type returned by this task.</div>
<br />
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"> <span style="font-family: Consolas; white-space: normal;">[</span><span style="color: #2b91af; font-family: Consolas; white-space: normal;">HttpGet</span><span style="font-family: Consolas; white-space: normal;">]</span>
<span style="color: blue;">public</span> <span style="color: blue;">async</span> <span style="color: #2b91af;">Task</span><<span style="color: #2b91af;">HttpResponseMessage</span>> Get(<span style="color: blue;">string</span> query)
{
<span style="color: blue;">return</span> <span style="color: blue;">await</span> <span style="color: blue;">this</span>.cityRepository</pre>
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"> .AutocompleteCity(query)
.Continue<<span style="color: #2b91af;">IQueryable</span><<span style="color: #2b91af;">City</span>>, <span style="color: #2b91af;">HttpResponseMessage</span>>(entities =>
{
<span style="color: blue;">var</span> cities = entities.MapCollection<<span style="color: #2b91af;">TCity</span>>();
<span style="color: blue;">return</span> <span style="color: blue;">this</span>.CreateListResponse<<span style="color: #2b91af;">TCity</span>>(cities);
});</pre>
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"><pre style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; font-family: Consolas;"> }</pre>
</pre>
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"></pre>
<div style="text-align: justify;">
So as conclusion, just by using a simple extension method, I was able to successfully re-factor a common task chaining logic which results in having more cleaner and easier to understand code.</div>
Damian Zaparthttp://www.blogger.com/profile/17026397366973677672noreply@blogger.comDublin, Ireland53.3498053 -6.260309699999993453.0463133 -6.9057566999999933 53.6532973 -5.6148626999999935tag:blogger.com,1999:blog-8522517990291142303.post-19449373913535152602013-08-04T23:52:00.002+01:002013-08-05T11:09:56.847+01:00Managing Android emulator in .NET<div style="text-align: justify;">
Automated coded UI testing become very popular in the past few years. Its allow developers to create tests which are executed directly on UI level and simulate user actions. At the same time HTML5 become a standard for creating universal modern applications which can be hosts in a native browser controls.<br />
<br />
New model of creating applications brings a new challenges in the testing fields that's why in this post I want to present my solution (it takes me almost two days to get this working!) which is first step in the process of creation an end-to-end test automation for mobile applications. My solution is prototype of a .NET console application which can be use to control Android emulator and simulate user standard operation like installing app, typing and rotating. This prototype can be use as '<i>emulator manager</i>' which controls device emulator on which tests are performed - for example by using <a href="https://code.google.com/p/selenium/wiki/WebDriverForMobileBrowsers" target="_blank">Selenium</a>.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
As initial requirements to run the project:</div>
<div style="text-align: justify;">
1) Install the latest <a href="http://java.com/en/download/index.jsp" target="_blank">Java</a> build <b>:(</b> (sorry .NET geeks but it`s required)</div>
<div style="text-align: justify;">
2) Install <a href="http://developer.android.com/sdk/index.html" target="_blank">Android SDK</a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Now we have all environment in place so we can create our emulator device. To do that we need to use <a href="http://developer.android.com/tools/devices/managing-avds.html" target="_blank">Android Virtual Devices Manager</a> tool which is located in the '.<i>.\\sdk\tools\</i>' path inside Android SDK folder. To run this tool we need start <b>cmd</b>, navigate to the SDK tools folder and type '<b>android avd</b>'. Now we can create a new emulator by specifying all setting we need - in the picture below I presented settings for my AVD called '<i>nexus</i>'. To make sure that all configuration if correct we should run out AVD by calling <b>emulator.exe</b> from '.<i>.\\sdk\tools\</i>' for example '<i><b>emulator -avd nexus</b></i>' - this cause our emulator start running and first run might take some time so be patient.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3FOF3EHuMitMduTJdfsKpaXgYjcJ2zv5P8ieW1KR0h_aHFUwAJAkJGI0LlhKK1T1fVHQ70t6SGWMyR1RYwcB5P5jGmqrbwEnzJCpNsMIri9w1ZlYJH1Zx7Ib64uJ92z6RjNmqNCvYGNGm/s1600/avd.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="590" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3FOF3EHuMitMduTJdfsKpaXgYjcJ2zv5P8ieW1KR0h_aHFUwAJAkJGI0LlhKK1T1fVHQ70t6SGWMyR1RYwcB5P5jGmqrbwEnzJCpNsMIri9w1ZlYJH1Zx7Ib64uJ92z6RjNmqNCvYGNGm/s640/avd.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Picture 1. Configuration of a new device emulator.</td></tr>
</tbody></table>
<div style="text-align: justify;">
Now its time to back to the C# code a present solution which can manage Android emulator through .NET code. Basically solution based on the simple console application which is calling externals console applications:</div>
<br />
<ul>
<li style="text-align: justify;"><a href="http://developer.android.com/tools/help/emulator.html"><b>emulator.exe</b></a> - console application which allow to start device emulator by device name with specific parameters.</li>
<li style="text-align: justify;"><a href="http://developer.android.com/tools/help/adb.html"><b>adb.exe</b></a> - console application which allow communication with device emulator; allow to run shell mode directly on the emulator.</li>
</ul>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUSPILpSIqQyk9wzAoi2de96RE2fl5Eg9p_tikSSq0gPhanVvNr2qOCtuvI-t0kv_qP9-dw3yFHDoJaysKS0WJkOmMDz7fpK0SwePpXsdJ0h9BFckIaNpFduSiSo8iAStuBM06hizqCtgj/s1600/architecture.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="502" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUSPILpSIqQyk9wzAoi2de96RE2fl5Eg9p_tikSSq0gPhanVvNr2qOCtuvI-t0kv_qP9-dw3yFHDoJaysKS0WJkOmMDz7fpK0SwePpXsdJ0h9BFckIaNpFduSiSo8iAStuBM06hizqCtgj/s640/architecture.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Picture 2. Application architecture.</td></tr>
</tbody></table>
<br />
<div style="text-align: justify;">
There is two very important parts inside this solution. First one is the <b>IEmulator </b>interface which expose all functions which are currently supported by the program. The idea is that this solution can be extended to all main three mobile platforms (iOS, Android, Windows) and the <b>IEmulator </b>interface will remain common an contract for all of them so just implementation of each emulator will be different (now only <b>AndroidEmulator </b>class is implemented). <b>IEmulator </b>interface implementation is as follow:</div>
<div style="text-align: justify;">
<br />
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="31" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li><span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span></li>
<li style="background: #f3f3f3;"><span style="color: grey;">///</span><span style="color: green;"> Expose all emulator tasks.</span></li>
<li><span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span></li>
<li style="background: #f3f3f3;"><span style="color: blue;">public</span> <span style="color: blue;">interface</span> <span style="color: #2b91af;">IEmulator</span></li>
<li>{</li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> Starts the emulator.</span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><returns></span><span style="color: green;">Value which determines emulator is ready for use.</span><span style="color: grey;"></returns></span></li>
<li style="background: #f3f3f3;"> <span style="color: blue;">bool</span> Initialize();</li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> Enable shell mode on the emulator.</span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span></li>
<li> <span style="color: blue;">void</span> StartShell();</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> Checks the emulator is running.</span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span></li>
<li style="background: #f3f3f3;"> <span style="color: blue;">bool</span> IsRunning();</li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> Install app on the emulator.</span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><param name="packagePath"></span><span style="color: green;">Path to the apk package to intsall.</span><span style="color: grey;"></param></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><returns></span><span style="color: green;">True if application installed correctly.</span><span style="color: grey;"></returns></span></li>
<li> <span style="color: blue;">bool</span> InstallApp(<span style="color: blue;">string</span> packagePath = <span style="color: blue;">null</span>);</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> Uninstall specyfic package from emulator.</span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><param name="packageName"></span><span style="color: green;">Specyfic package name to uninstall.</span><span style="color: grey;"></param></span></li>
<li> <span style="color: blue;">void</span> UninstallApp(<span style="color: blue;">string</span> packageName = <span style="color: blue;">null</span>);</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> Run monkey on package.</span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><param name="activitiesCount"></span><span style="color: green;">Action count.</span><span style="color: grey;"></param></span></li>
<li> <span style="color: blue;">void</span> RunMonkey(<span style="color: blue;">int</span> activitiesCount = 500);</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> Simulating keypress events on emulator.</span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><param name="codes"></span><span style="color: green;">Hardware codes array.</span><span style="color: grey;"></param></span></li>
<li> <span style="color: blue;">void</span> TypeAsHardwareInput(<span style="color: blue;">int</span>[] codes);</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> Change orientation of the emulator.</span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span></li>
<li style="background: #f3f3f3;"> <span style="color: blue;">void</span> ChangeOrientation();</li>
<li>}</li>
</ol>
</div>
</div>
<br /></div>
<div style="text-align: justify;">
As you can see here, not all options are implemented but the most important functions are on place so let`s have a quick look on its:<br />
<ul>
<li><b>Initialize</b>: function which starts device emulator by calling <b>emulator.exe </b>as separate process and pass AVD name from the configuration file.</li>
<li><b>StartShell</b>: using '<i>adb shell</i>' command from <b>adb.exe</b> tool in separated process to start <a href="http://developer.android.com/tools/help/adb.html#shellcommands">shell mode</a> on the currently running AVD. Process which hosts shell will remain active until application close.</li>
<li><b>IsRunning</b>: function which call '<i>adb devices</i>' command in separated process from <b>adb.exe</b> tool to check if AVD is currently running.</li>
<li><b>InstallApp</b>: install APK file from specific path in local PC by calling <i>'adb wait-for-device install <apk full-path></i>' command from <b>adb.exe</b> as separated process. Additional <i>wait-for-device </i>command ensure that emulator is ready to install app. </li>
<li><b>UninstalApp</b>: uninstall app from shell level by using package name (ex. <i>com.android.tools.sdkcontroller</i> stored in <i>AndroidInstalledAppName </i>App.config)</li>
<li><b>RunMonkey</b>: from shell mode run <a href="http://developer.android.com/tools/help/monkey.html">monkey</a> random actions on the installed package by executing N (activitiesCount) random activities.</li>
<li><b>TypeAsHardwareInput</b>: allow to use simulate hardware keys to input any supported input. Under the hood its calling shell command '<i>input keyevent <key_code></i>' with key code specified for the platform. Key-codes list is available <a href="http://thecodeartist.blogspot.ie/2011/03/simulating-keyevents-on-android-device.html">here</a>.</li>
</ul>
Last function I want to describe in not supported by the Android SDK and from testing point of view it`s crucial -I mean here changing emulator orientation during the run-time. I spent a lot of time reading and investigating any potential possibility of changing emulator orientation by no of solutions I`ve found was working for me. There is only one official way to switch emulator orientation - by pressing CTRL+F11, and I`m implemented it. Source code for this using an external library called <a href="http://inputsimulator.codeplex.com/">InuputSimulator</a> (thank you <a href="http://www.codeplex.com/site/users/view/michaelnoonan">Michael</a>) to simulate keystroke. Additionally I used emulator process name to find exact process and get focus on their main window before simulate keystroke. </div>
<br />
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="32" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li>[DllImport(<span style="color: #a31515;">"user32.dll"</span>)]</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">static</span> <span style="color: blue;">extern</span> <span style="color: blue;">bool</span> SetForegroundWindow(<span style="color: #2b91af;">IntPtr</span> hWnd);</li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> Change orientation of the emulator.</span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span></li>
<li> <span style="color: blue;">public</span> <span style="color: blue;">void</span> ChangeOrientation()</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">var</span> emulatorProcess = Process.GetProcessesByName(<span style="color: #a31515;">"emulator-arm"</span>);</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">if</span> (emulatorProcess.Count() == 0)</li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">throw</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">InvalidOperationException</span>(<span style="color: #a31515;">"Unable to find emulator process."</span>);</li>
<li> }</li>
<li style="background: #f3f3f3;"> </li>
<li> BringToFront(emulatorProcess[0]);</li>
<li style="background: #f3f3f3;"> WindowsInput.InputSimulator.SimulateModifiedKeyStroke(WindowsInput.VirtualKeyCode.CONTROL, WindowsInput.VirtualKeyCode.F11);</li>
<li> }</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> Set focus on the process.</span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><param name="pTemp"></span><span style="color: green;">Process to be focused.</span><span style="color: grey;"></param></span></li>
<li> <span style="color: blue;">private</span> <span style="color: blue;">void</span> BringToFront(Process pTemp)</li>
<li style="background: #f3f3f3;"> {</li>
<li> SetForegroundWindow(pTemp.MainWindowHandle);</li>
<li style="background: #f3f3f3;"> }</li>
</ol>
</div>
</div>
<br />
Now when all functions are on place we can call them in logical order.<br />
<br />
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li><span style="color: blue;">class</span> <span style="color: #2b91af;">Program</span></li>
<li style="background: #f3f3f3;">{</li>
<li> <span style="color: blue;">static</span> <span style="color: blue;">void</span> Main(<span style="color: blue;">string</span>[] args)</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">var</span> emulator = EmulatorFactory.GetEmulator(EmulatorType.Android);</li>
<li style="background: #f3f3f3;"> </li>
<li> emulator.Initialize();</li>
<li style="background: #f3f3f3;"> </li>
<li> emulator.InstallApp();</li>
<li style="background: #f3f3f3;"> </li>
<li> emulator.StartShell();</li>
<li style="background: #f3f3f3;"> </li>
<li> emulator.ChangeOrientation();</li>
<li style="background: #f3f3f3;"> emulator.ChangeOrientation();</li>
<li> </li>
<li style="background: #f3f3f3;"> emulator.RunMonkey();</li>
<li> emulator.UnistallApp();</li>
<li style="background: #f3f3f3;"> }</li>
<li>}</li>
</ol>
</div>
</div>
<br />
<b>I can`t guarantee but I hope that soon I will add next emulator - keep your fingers crossed!</b><br />
<br />
Whole source code of the project is available <a href="http://dzapart.com.pl/BlogFiles/EmulatorsManager.7z" rel="nofollow" target="_blank">here</a>.<br />
<br />
<div>
<b>Thank you</b></div>
<div>
<br /></div>
<div>
More info:</div>
<div>
<ul>
<li><a href="http://developer.android.com/tools/help/adb.html">ADB.exe</a></li>
<li><a href="http://developer.android.com/tools/help/emulator.html">Android Emulator</a></li>
<li><a href="http://blog.rabidgremlin.com/2010/11/05/android-tips-the-emulator/">Android tips</a></li>
<li><a href="http://developer.android.com/tools/help/monkey.html">Android Monkey</a></li>
</ul>
</div>
Damian Zaparthttp://www.blogger.com/profile/17026397366973677672noreply@blogger.comDublin, Ireland53.3498053 -6.260309699999993453.0463133 -6.9057566999999933 53.6532973 -5.6148626999999935tag:blogger.com,1999:blog-8522517990291142303.post-68165308309191052162013-07-21T00:14:00.001+01:002013-07-21T00:18:21.957+01:00Playing with a .NET types definition<div style="text-align: justify;">
In the last few days I spent some time trying to unify structure of one of the project I`m currently working on. Most of the changes were about changing variable types because it`s were not used right way. That is why in this post I want to share my observations and practices with you.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
First of all we need to understand what '<i>variable definition</i>' is and how it`s different from '<i>variable initialization</i>'. This part should be pretty straightforward:</div>
<ul>
<li style="text-align: justify;"> <b>variable definition</b> consist of data type and variable name only <b><i><data_type> <variable_name></i>;</b> for example<i> int i</i>; . It`s important to understand how variable definition affects your code because it behaves differently depends weather you work with <b>value </b>or <b>reference </b>types. In the case of value types after defining variable it always has default value and it`s never null value. However after defined reference type variable without initializing it has null value by default.</li>
<li style="text-align: justify;"><b>variable initialization</b> is a process of assigning value to the variable - <b><i>variable_name = value; </i></b>it can be merged with the definition into one line expression <data_type> <variable_name> = value;</li>
</ul>
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">Test</span></li>
<li style="background: #f3f3f3;">{</li>
<li> <span style="color: blue;">public</span> Test()</li>
<li style="background: #f3f3f3;"> { </li>
<li> <span style="color: green;">// variable definition for value type.</span></li>
<li style="background: #f3f3f3;"> <span style="color: blue;">int</span> i; <span style="color: green;">// i == 0 as this stage.</span></li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: green;">// variable definition for reference type.</span></li>
<li> <span style="color: blue;">string</span> s; <span style="color: green;">// s == null at this stage.</span></li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: green;">// value type variable initialization</span></li>
<li style="background: #f3f3f3;"> i = 10; <span style="color: green;">// i == 10.</span></li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: green;">// referece type variable initialization</span></li>
<li> s = <span style="color: #a31515;">"Test"</span>;</li>
<li style="background: #f3f3f3;"> }</li>
<li>}</li>
</ol>
</div>
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Now we can go forward and compare a different types of a variable definition. As many of you remember in the past, in .NET Framework 2.0, only one type of variable definition exists. Here I mean classic, <b>strongly typed</b>, combination of type and variable name (example below line 13.). It was very popular (because at this time there was nothing else to replace it) but this approach requires creating separated type for each problem. This cause in many project multiple very similar types exists so it was not a perfect solution.</div>
<br />
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">Test</span></li>
<li style="background: #f3f3f3;">{</li>
<li> <span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">SomeType</span></li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">internal</span> <span style="color: blue;">void</span> DoSomething()</li>
<li style="background: #f3f3f3;"> { </li>
<li> </li>
<li style="background: #f3f3f3;"> }</li>
<li> }</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: blue;">public</span> Test()</li>
<li style="background: #f3f3f3;"> {</li>
<li> <b><span style="color: #2b91af;">SomeType</span> type = <span style="color: blue;">new</span> <span style="color: #2b91af;">SomeType</span>();</b></li>
<li style="background: #f3f3f3;"> type.DoSomething();</li>
<li> }</li>
<li style="background: #f3f3f3;">}</li>
</ol>
</div>
</div>
<br />
<div style="text-align: justify;">
Since .NET Framework 3.0 developers was able to switch their mind into different kind of thinking about defining variables because a new <b><a href="http://msdn.microsoft.com/en-us/library/bb383973.aspx" target="_blank">var</a> </b>keyword became in use. A var keyword is separated type of defining variables, which are still <b>strongly typed</b> but it`s resolved by the compiler based on value assigned to it during initialization (<span style="color: red;">a var variable have to be defined and initialized in the same line of code</span>). Why is so cool to use it? This is a very good question and a lot <a href="http://stackoverflow.com/questions/356846/c-sharp-var-vs-specific-type-performance" target="_blank">discussions </a>around that already exists in the Internet. First of all variables defined with var keyword in general have more descriptive name because in other case even developer might have a problem with reading own code. Let see an example:</div>
<br />
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li><span style="color: blue;">using</span> System.Collections.Generic;</li>
<li style="background: #f3f3f3;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">Test</span></li>
<li>{</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">SomeType</span></li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">internal</span> <span style="color: blue;">void</span> DoSomething()</li>
<li> { </li>
<li style="background: #f3f3f3;"> </li>
<li> }</li>
<li style="background: #f3f3f3;"> }</li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: blue;">public</span> Test()</li>
<li> {</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: green;">// SomeType someType = new SomeType();</span></li>
<li style="background: #f3f3f3;"> <span style="color: blue;">var</span> someType = <span style="color: blue;">new</span> <span style="color: #2b91af;">SomeType</span>(); <span style="color: green;">// equivalent to line above.</span></li>
<li> <span style="color: blue;">var</span> someTypeList= <span style="color: blue;">new</span> <span style="color: #2b91af;">List</span><<span style="color: #2b91af;">SomeType</span>>();</li>
<li style="background: #f3f3f3;"> }</li>
<li>}</li>
</ol>
</div>
</div>
<br />
<div style="text-align: justify;">
However the real power of using <b>var </b>keyword ins`t naming convention but something which is called <a href="http://msdn.microsoft.com/en-us/library/vstudio/bb397696.aspx" target="_blank">anonymous types</a>.<b> <span style="color: #6aa84f;">It`s really powerful tool in developers hands</span></b>!! Anonymous types are generated by the compiler, are <b>strongly typed</b> and not exists physically as a class or structure in a project code but provide a convenient way to encapsulate a set of read-only properties into a single object. Let`s see example of using it:</div>
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li><span style="color: blue;">using</span> System.Collections.Generic;</li>
<li style="background: #f3f3f3;"><span style="color: blue;">using</span> System.Linq;</li>
<li><span style="color: blue;">using</span> System;</li>
<li style="background: #f3f3f3;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">Test</span></li>
<li>{</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">User</span></li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">public</span> <span style="color: blue;">int</span> Id { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</li>
<li> <span style="color: blue;">public</span> <span style="color: blue;">string</span> Name { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">public</span> <span style="color: blue;">string</span> Surname { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</li>
<li> <span style="color: blue;">public</span> <span style="color: blue;">string</span> Department { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">public</span> <span style="color: blue;">byte</span>[] HugeArray { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</li>
<li> }</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: blue;">public</span> Test()</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">var</span> userList = <span style="color: blue;">new</span> <span style="color: #2b91af;">List</span><<span style="color: #2b91af;">User</span>>();</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: green;">// code to populate the list.</span></li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: green;">// Creating a new anonymous type with HrId and FullName properties.</span></li>
<li style="background: #f3f3f3;"> <span style="color: blue;">var</span> userInHrDepartment = <span style="color: blue;">from</span> user <span style="color: blue;">in</span> userList</li>
<li> <span style="color: blue;">where</span> user.Department == <span style="color: #a31515;">"HR"</span></li>
<li style="background: #f3f3f3;"> <span style="color: blue;">select</span> <span style="color: blue;">new</span> { HrId = user.Id, FullName = user.Name + <span style="color: #a31515;">" "</span> + user.Surname };</li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: green;">// Tterate through collection of anonymous type.</span></li>
<li> <span style="color: blue;">foreach</span> (<span style="color: blue;">var</span> hrUser <span style="color: blue;">in</span> userInHrDepartment)</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: #2b91af;">Console</span>.WriteLine(hrUser.FullName);</li>
<li style="background: #f3f3f3;"> }</li>
<li> }</li>
<li style="background: #f3f3f3;">}</li>
</ol>
</div>
</div>
<br />
<div style="text-align: justify;">
As you can see by using a very simple LINQ query I`m extracting only variable I really want to process, and without creating strong type explicit I`m using anonymous type to iterate through the collection and accessing specific properties.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Last type of a variable definitions comes with .NET Framework 4.0 which introduce a new <a href="http://msdn.microsoft.com/en-us/library/dd264736.aspx" target="_blank">dynamic</a> type.</div>
<div style="text-align: justify;">
This is completely different type of thinking for developers because this type of object behaves very similar to the well know <b>object </b>type. However the difference between those two is huge because object is so powerful because of inheritance while dynamic type is<b> not strongly typed</b>, <a href="http://en.wikipedia.org/wiki/Late_binding" target="_blank">late-bound</a> and exists only at run-time. Basically it`s a bag where we can put everything and expect everything but we can`t be sure that something exist there. Let see dynamic type in action.</div>
<div style="text-align: justify;">
<br /></div>
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li><span style="color: blue;">using</span> System.Collections.Generic;</li>
<li style="background: #f3f3f3;"><span style="color: blue;">using</span> System.Linq;</li>
<li><span style="color: blue;">using</span> System;</li>
<li style="background: #f3f3f3;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">Test</span></li>
<li>{</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">User</span></li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">public</span> <span style="color: blue;">int</span> Id { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</li>
<li> <span style="color: blue;">public</span> <span style="color: blue;">string</span> Name { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">public</span> <span style="color: blue;">string</span> Surname { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</li>
<li> <span style="color: blue;">public</span> <span style="color: blue;">string</span> Department { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">public</span> <span style="color: blue;">byte</span>[] HugeArray { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</li>
<li> }</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: blue;">public</span> Test()</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">var</span> user = <span style="color: blue;">new</span> <span style="color: #2b91af;">User</span>();</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">dynamic</span> userModyfied = user;</li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: green;">// Adding extra property to the User type.</span></li>
<li> userModyfied.AdditionalProperty = <span style="color: #a31515;">"Test value"</span>;</li>
<li style="background: #f3f3f3;"> <span style="color: #2b91af;">Console</span>.WriteLine(userModyfied.AdditionalProperty);</li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: blue;">dynamic</span> userModyfied2 = <span style="color: blue;">new</span> <span style="color: #2b91af;">User</span>();</li>
<li> userModyfied2.AdditionalProperty2 = <span style="color: #a31515;">"Test value 2"</span>;</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: #2b91af;">Console</span>.WriteLine(userModyfied.AdditionalProperty2); <span style="color: green;">// value exists</span></li>
<li style="background: #f3f3f3;"> <span style="color: #2b91af;">Console</span>.WriteLine(userModyfied.AdditionalProperty); <span style="color: green;">// value doesn`t exist</span></li>
<li> }</li>
<li style="background: #f3f3f3;">}</li>
</ol>
</div>
</div>
<br />
As you can see in the example above. This is very strange type and might bring a lot or troubles when used incorrectly. Additionally usage it hurts performance of our solution so use it wisely only if necessary.<br />
<br />
Thank you<br />
<br />Damian Zaparthttp://www.blogger.com/profile/17026397366973677672noreply@blogger.comtag:blogger.com,1999:blog-8522517990291142303.post-2124843665987672412013-07-20T19:37:00.000+01:002013-07-20T19:37:05.232+01:00Creating API with MVC ApiController part 3 - moving to asynchronous code<div style="text-align: justify;">
In my two previous posts (<a href="http://dzapart.blogspot.ie/2013/06/creating-api-with-mvc-apicontroller_20.html" target="_blank">part 1</a> and <a href="http://dzapart.blogspot.ie/2013/07/creating-api-with-mvc-apicontroller.html" target="_blank">part 2</a>) I described both simple and more advance approach of creating Rest-full API in MVC 4. Today I want to take another step forward and go a little deeper in the creation of API. In this post I`m going to describe how we can create asynchronous API functions which bring better performance to our applications.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The first thing that need to be understand is an asynchronous operation in .NET Framework. In .NET Framework 4.0 one of the most important changed was introducing <a href="http://msdn.microsoft.com/en-us/library/system.threading.tasks.task.aspx" target="_blank">Task</a> class.The Tasks in System.Threading.Tasks namespace are a method of fine grained parallelism, similar to creating and using threads, but they have a few key differences and the main difference is that Tasks in .NET 4.0 don’t actually correlate to a new thread, they are executed on the new thread pool that is being shipped in .NET 4.0. More about task you can read <a href="http://msdn.microsoft.com/en-us/library/dd460717(v=vs.100).aspx" target="_blank">here</a> but to understand this article all you need to understand about the Task<T> class is that this type encapsulate asynchronous action which returns T type object. <b>Task<T></b> type also expose a result of it in the <b>Result<T> </b>property and allow to verify execution state by checking <b>Status </b>or <b>IsCompleted </b>property. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Now we know more about asynchronous tasks in .NET Framework 4.0 but it`s not all because .NET Framework 4.5 offers a two completely new keywords in C# <b>async </b>and <b>await</b>. Those keywords exist together and work (in one function) to make functions completely asynchronous. To understand how to use it first of all we need to aware of plate to put it:</div>
<div style="text-align: justify;">
</div>
<ul>
<li style="text-align: justify;"><b>async </b>- exist in function signature right after access modifiers; it`s mark function to be asynchronous</li>
<li style="text-align: justify;"><b>await</b> - exists in the function body which is marked as async; it placed before function result which was called asynchronously </li>
</ul>
<div>
<div style="text-align: justify;">
Usage of both new keywords is very easy as far as you can see on the example presented below (from <a href="http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx" target="_blank">MSDN</a>) but still restrictions still and you can read about it <a href="http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx" target="_blank">here</a>. </div>
</div>
<div>
<br /></div>
<div>
<pre style="background-color: white; font-family: Consolas, Courier, monospace; font-size: 14px; line-height: 18px; overflow: auto; padding: 5px; word-wrap: normal;"><span style="color: blue;">async</span> Task<<span style="color: blue;">int</span>> AccessTheWebAsync()
{
<span style="color: green;">// You need to add a reference to System.Net.Http to declare client.</span>
HttpClient client = <span style="color: blue;">new</span> HttpClient();
<span style="color: green;">// GetStringAsync returns a Task<string>. That means that when you await the </span>
<span style="color: green;">// task you'll get a string (urlContents).</span>
Task<<span style="color: blue;">string</span>> getStringTask = client.GetStringAsync(<span style="color: #a31515;">"http://msdn.microsoft.com"</span>);
<span style="color: green;">// You can do work here that doesn't rely on the string from GetStringAsync.</span>
DoIndependentWork();
<span style="color: green;">// The await operator suspends AccessTheWebAsync. </span>
<span style="color: green;">// - AccessTheWebAsync can't continue until getStringTask is complete. </span>
<span style="color: green;">// - Meanwhile, control returns to the caller of AccessTheWebAsync. </span>
<span style="color: green;">// - Control resumes here when getStringTask is complete. </span>
<span style="color: green;">// - The await operator then retrieves the string result from getStringTask. </span>
<span style="color: blue;">string</span> urlContents = <span style="color: blue;">await</span> getStringTask;
<span style="color: green;">// The return statement specifies an integer result. </span>
<span style="color: green;">// Any methods that are awaiting AccessTheWebAsync retrieve the length value. </span>
<span style="color: blue;">return</span> urlContents.Length;
}</pre>
<pre style="background-color: white; font-family: Consolas, Courier, monospace; font-size: 14px; line-height: 18px; overflow: auto; padding: 5px; word-wrap: normal;"></pre>
</div>
<div style="text-align: justify;">
Now, when working with asynchronous operations is not problem for us, it`s time to back to our Rest API and make is asynchronous. As example of asynchronous API I want to use the same API I presented in my <a href="http://dzapart.blogspot.ie/2013/07/creating-api-with-mvc-apicontroller.html" target="_blank">previous post</a> and instead of changing logic just change it to fully asynchronous - so in other words I want to extend existing API with all CRUD operation form managing users to work non synchronous way.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
[1] The very first thing I want to change is all API function signatures. I mean here change all functions from <b>HttpResponseMessage Get()</b> to <b>async Task<HttpResponseMessage> Get()</b>. I also believe that the new function signature is not mysterious for you after you read this article introduction.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
[2] As second change I want to make is encapsulate all API functions logic execution to be part of the Task<T> as presented in example below.</div>
<br />
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="34" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li> [<span style="color: #2b91af;">HttpGet</span>]</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">public</span> HttpResponseMessage Get()</li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">return</span> Request.CreateResponse<<span style="color: #2b91af;">ReadOnlyCollection</span><User>>(<span style="color: #2b91af;">HttpStatusCode</span>.OK, <span style="color: #2b91af;">FakeDbContext</span>.Instance.Users.AsReadOnly());</li>
<li> }</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: green;">// Changing synchonous code to asynchonous function</span></li>
<li style="background: #f3f3f3;"> </li>
<li> [<span style="color: #2b91af;">HttpGet</span>]</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">public</span> <span style="color: #2b91af;">async</span> Task<HttpResponseMessage> Get()</li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">return</span> await <span style="color: #2b91af;">Task</span><HttpResponseMessage>.Factory.StartNew(() =></li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: #2b91af;">var</span> allUsers = <span style="color: #2b91af;">FakeDbContext</span>.Instance.Users.ToArray();</li>
<li> <span style="color: #2b91af;">var</span> resultCollection = <span style="color: blue;">new</span> <span style="color: #2b91af;">Collection</span><User>(allUsers);</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">return</span> Request.CreateResponse<<span style="color: #2b91af;">Collection</span><User>>(<span style="color: #2b91af;">HttpStatusCode</span>.OK, resultCollection);</li>
<li> });</li>
<li style="background: #f3f3f3;"> }</li>
</ol>
</div>
</div>
<br />
<div style="text-align: justify;">
<b>That`s it!</b> It was really straightforward as you can see. Now our API is working fully asynchronous and can be called without blocking. Let have overall look of it.</div>
<div style="text-align: justify;">
<br /></div>
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="1" style="background: #ffffff; margin: 0 0 0 3em; padding: 0 0 0 5px;">
<li><span style="color: blue;">using</span> MvcApplication1.Controllers;</li>
<li style="background: #f3f3f3;"> </li>
<li><span style="color: blue;">namespace</span> WebApi.Controllers</li>
<li style="background: #f3f3f3;">{</li>
<li> <span style="color: blue;">using</span> System;</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">using</span> System.Collections.ObjectModel;</li>
<li> <span style="color: blue;">using</span> System.Net;</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">using</span> System.Net.Http;</li>
<li> <span style="color: blue;">using</span> System.Threading.Tasks;</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">using</span> System.Web.Http;</li>
<li> <span style="color: blue;">using</span> WebApi.Common;</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">using</span> WebApi.Models;</li>
<li><span style="color: blue;">using</span> MvcApplication1.Controllers;</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> Asynchonous controller for managing </span><span style="color: grey;"><see cref="User"/></span><span style="color: green;">.</span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span></li>
<li style="background: #f3f3f3;"> <span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">AsyncController</span> : <span style="color: #2b91af;">ApiController</span></li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> Add a new </span><span style="color: grey;"><see cref="User"/></span><span style="color: green;"> to the collection.</span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><param name="user"></span><span style="color: green;">User to add.</span><span style="color: grey;"></param></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><returns></span><span style="color: green;">The added </span><span style="color: grey;"><see cref="User"/></span><span style="color: green;">.</span><span style="color: grey;"></returns></span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><remarks></span><span style="color: green;">GET http://xy.z/api/async/ </span><span style="color: grey;"></remarks></span></li>
<li style="background: #f3f3f3;"> [<span style="color: #2b91af;">HttpPost</span>]</li>
<li> <span style="color: blue;">public</span> <span style="color: #2b91af;">async</span> Task<HttpResponseMessage> Post(<span style="color: #2b91af;">User</span> user)</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">return</span> <span style="color: #2b91af;">await</span> <span style="color: #2b91af;">Task</span><<span style="color: #2b91af;">HttpResponseMessage</span>>.Factory.StartNew(() =></li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">if</span> (user == <span style="color: blue;">null</span>)</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">return</span> Request.CreateErrorResponse(<span style="color: #2b91af;">HttpStatusCode</span>.BadRequest, <span style="color: #a31515;">"Invalid user."</span>);</li>
<li style="background: #f3f3f3;"> }</li>
<li> </li>
<li style="background: #f3f3f3;"> user.Id = RandomGenerator.Instance.NextInt();</li>
<li> FakeDbContext.Instance.Users.Add(user);</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">return</span> Request.CreateResponse<User>(HttpStatusCode.Created, user);</li>
<li> });</li>
<li style="background: #f3f3f3;"> }</li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> Returns all users.</span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><returns></span><span style="color: green;">Collection of all users.</span><span style="color: grey;"></returns></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><remarks></span><span style="color: green;">GET http://xy.z/api/async/ </span><span style="color: grey;"></remarks></span></li>
<li> [HttpGet]</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">public</span> async Task<HttpResponseMessage> Get()</li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">return</span> await Task<HttpResponseMessage>.Factory.StartNew(() =></li>
<li> {</li>
<li style="background: #f3f3f3;"> var allUsers = FakeDbContext.Instance.Users.ToArray();</li>
<li> var resultCollection = <span style="color: blue;">new</span> Collection<User>(allUsers);</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">return</span> Request.CreateResponse<Collection<User>>(HttpStatusCode.OK, resultCollection);</li>
<li> });</li>
<li style="background: #f3f3f3;"> }</li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> Get user by user ID.</span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><param name="id"></span><span style="color: green;">Id of the user.</span><span style="color: grey;"></param></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><returns></span><span style="color: green;">User with specyfied ID.</span><span style="color: grey;"></returns></span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><remarks></span><span style="color: green;">GET http://xy.z/api/async/32</span><span style="color: grey;"></remarks></span></li>
<li style="background: #f3f3f3;"> [HttpGet]</li>
<li> <span style="color: blue;">public</span> async Task<HttpResponseMessage> GetById(<span style="color: blue;">int</span> id)</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">return</span> await Task<HttpResponseMessage>.Factory.StartNew(() =></li>
<li style="background: #f3f3f3;"> {</li>
<li> var selectedUser = FakeDbContext.Instance.Users.Find(u => u.Id == id);</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">return</span> Request.CreateResponse<User>(HttpStatusCode.OK, selectedUser);</li>
<li> });</li>
<li style="background: #f3f3f3;"> }</li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> Updates user.</span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><param name="user"></span><span style="color: green;">User to update.</span><span style="color: grey;"></param></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><returns></span><span style="color: green;">Updated user.</span><span style="color: grey;"></returns></span></li>
<li> [HttpPut]</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">public</span> async Task<HttpResponseMessage> Put(User user)</li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">return</span> await Task<HttpResponseMessage>.Factory.StartNew(() =></li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">if</span> (user == <span style="color: blue;">null</span> || user.Id == 0)</li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">return</span> Request.CreateErrorResponse(HttpStatusCode.BadRequest, <span style="color: #a31515;">"Invalid user."</span>);</li>
<li> }</li>
<li style="background: #f3f3f3;"> </li>
<li> var selectedUser = FakeDbContext.Instance.Users.Find(u => u.Id == user.Id);</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">if</span> (selectedUser == <span style="color: blue;">null</span>)</li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">return</span> Request.CreateErrorResponse(HttpStatusCode.NotFound, <span style="color: #a31515;">"User not found."</span>);</li>
<li> }</li>
<li style="background: #f3f3f3;"> </li>
<li> var index = FakeDbContext.Instance.Users.IndexOf(selectedUser);</li>
<li style="background: #f3f3f3;"> user.Id = selectedUser.Id;</li>
<li> </li>
<li style="background: #f3f3f3;"> FakeDbContext.Instance.Users.RemoveAt(index);</li>
<li> FakeDbContext.Instance.Users.Insert(index, user);</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: blue;">return</span> Request.CreateResponse<User>(HttpStatusCode.NoContent, user);</li>
<li style="background: #f3f3f3;"> });</li>
<li> }</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> Delete user from storage.</span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><param name="id"></span><span style="color: green;">ID of the user to remove.</span><span style="color: grey;"></param></span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><returns></span><span style="color: green;">Response without content.</span><span style="color: grey;"></returns></span></li>
<li style="background: #f3f3f3;"> [HttpDelete]</li>
<li> <span style="color: blue;">public</span> async Task<HttpResponseMessage> Delete(<span style="color: blue;">int</span> id)</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">return</span> await Task<HttpResponseMessage>.Factory.StartNew(() =></li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">if</span> (id == 0)</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">return</span> Request.CreateErrorResponse(HttpStatusCode.BadRequest, <span style="color: #a31515;">"Invalid ID."</span>);</li>
<li style="background: #f3f3f3;"> }</li>
<li> </li>
<li style="background: #f3f3f3;"> var selectedUser = FakeDbContext.Instance.Users.Find(u => u.Id == id);</li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: blue;">if</span> (selectedUser == <span style="color: blue;">null</span>)</li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">return</span> Request.CreateErrorResponse(HttpStatusCode.NotFound, <span style="color: #a31515;">"User not found."</span>);</li>
<li> }</li>
<li style="background: #f3f3f3;"> </li>
<li> FakeDbContext.Instance.Users.Remove(selectedUser);</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: blue;">return</span> Request.CreateResponse(HttpStatusCode.NoContent);</li>
<li style="background: #f3f3f3;"> });</li>
<li> }</li>
<li style="background: #f3f3f3;"> }</li>
<li>}</li>
</ol>
</div>
</div>
<br />
<b style="background-color: white; color: #222222; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18px; text-align: center;"><span style="font-size: x-small;">Whole source code of the project is available <a href="http://www.dzapart.com.pl/BlogFiles/WebApi.7z" style="color: #888888; text-decoration: none;">here</a>.</span></b><br />
<b style="background-color: white; color: #222222; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18px; text-align: center;"><span style="font-size: x-small;"><br /></span></b><span style="background-color: white; color: #222222; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18px;">Thank you.</span>Damian Zaparthttp://www.blogger.com/profile/17026397366973677672noreply@blogger.comtag:blogger.com,1999:blog-8522517990291142303.post-88644636747250412722013-07-08T21:40:00.000+01:002013-07-08T21:40:58.220+01:00Creating API with MVC ApiController part 2<div>
In my previous <a href="http://dzapart.blogspot.ie/2013/06/creating-api-with-mvc-apicontroller_20.html" target="_blank">post</a> I wrote about first steps in creating Rest-full API by using <a href="http://msdn.microsoft.com/en-us/library/system.web.http.apicontroller(v=vs.108).aspx" target="_blank">ApiController</a>. Now it`s time to make next step and go a little bit dipper inside web services created in MVC. In this post I want to describe two very important aspect:</div>
<ul>
<li>creating a real life scenario for web service implementation of <a href="https://www.google.ie/url?sa=t&rct=j&q=&esrc=s&source=web&cd=5&cad=rja&ved=0CEsQFjAE&url=http%3A%2F%2Fen.wikipedia.org%2Fwiki%2FPlain_Old_CLR_Object&ei=xbjZUfiRNYOR7AbC1oDADg&usg=AFQjCNFLh2Npn7Y6E9oyuPbcLZ7hIhi65A&sig2=kZhavkslWcX2R_5jeaWe1g" target="_blank">POCO </a>entity</li>
<li>extend presented scenario and make it asynchronous</li>
</ul>
<div>
To complete this tutorial one more class is needed. This class is a simple fake of some database which is wrapper around a very few collections and allow all CRUD operation. Moreover the implementation of this fake database uses a singleton design pattern to prevent creating instance of it each time and maintain state between web service calls.</div>
<div>
<br /></div>
<div>
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="86" style="background: #ffffff; margin: 0 0 0 3em; padding: 0 0 0 5px;">
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> Represents a fake database.</span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span></li>
<li style="background: #f3f3f3;"> <span style="color: blue;">public</span> <span style="color: blue;">sealed</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">FakeDbContext</span></li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">private</span> <span style="color: blue;">static</span> <span style="color: blue;">volatile</span> <span style="color: #2b91af;">FakeDbContext</span> instance;</li>
<li> <span style="color: blue;">private</span> <span style="color: blue;">static</span> <span style="color: blue;">object</span> syncRoot = <span style="color: blue;">new</span> <span style="color: #2b91af;">Object</span>();</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: blue;">private</span> FakeDbContext()</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">this</span>.Users = <span style="color: blue;">new</span> <span style="color: #2b91af;">List</span><<span style="color: #2b91af;">User</span>>();</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">this</span>.Dictionary = <span style="color: blue;">new</span> <span style="color: #2b91af;">Dictionary</span><<span style="color: blue;">string</span>, <span style="color: blue;">string</span>>();</li>
<li> }</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: blue;">public</span> <span style="color: blue;">static</span> <span style="color: #2b91af;">FakeDbContext</span> Instance</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">get</span></li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">if</span> (instance == <span style="color: blue;">null</span>)</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">lock</span> (syncRoot)</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">if</span> (instance == <span style="color: blue;">null</span>)</li>
<li style="background: #f3f3f3;"> instance = <span style="color: blue;">new</span> <span style="color: #2b91af;">FakeDbContext</span>();</li>
<li> }</li>
<li style="background: #f3f3f3;"> }</li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: blue;">return</span> instance;</li>
<li> }</li>
<li style="background: #f3f3f3;"> }</li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: blue;">public</span> <span style="color: #2b91af;">List</span><<span style="color: #2b91af;">User</span>> Users { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: blue;">public</span> <span style="color: #2b91af;">Dictionary</span><<span style="color: blue;">string</span>, <span style="color: blue;">string</span>> Dictionary { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</li>
<li> }</li>
</ol>
</div>
</div>
</div>
<br />
The real life scenario that we want to implement is a simple web service which expose all CRUD operation and of course it`s base on REST. In the following class each API functions return the same type <a href="http://msdn.microsoft.com/en-us/library/system.net.http.httpresponsemessage.aspx" target="_blank">HttpResponseMessage</a> which represent a standard HTTP response. This type contains two important properties: <b><a href="http://msdn.microsoft.com/en-us/library/system.net.httpstatuscode.aspx" target="_blank">StatusCode</a> </b>- which represent a HTTP response status code and <b>Content </b>- which store body of the response if any. The the easiest to produce a <a href="http://msdn.microsoft.com/en-us/library/system.net.http.httpresponsemessage.aspx" target="_blank">HttpResponseMessage</a> is calling one of many build-in functions which are responsible for creating a fully qualified response based on several input parameter:<br />
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/hh944545(v=vs.108).aspx" target="_blank">Request.CreateResponse</a> - the simplest method for returning any type of response with or without content</li>
<li><a href="http://msdn.microsoft.com/en-us/library/hh969014(v=vs.108).aspx" target="_blank">Request.CreateResponse<T></a> - create a success response with content of T type</li>
<li><a href="http://msdn.microsoft.com/en-us/library/jj130611(v=vs.108).aspx">Request.CreateErrorResponse</a> - create a error response and requires to specify HTTP code status and exception</li>
</ul>
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="125" style="background: #ffffff; margin: 0 0 0 3em; padding: 0 0 0 5px;">
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> Represent a controller for managing </span><span style="color: grey;"><see cref="User"/></span><span style="color: green;">.</span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span></li>
<li style="background: #f3f3f3;"> <span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">UserController</span> : <span style="color: #2b91af;">ApiController</span></li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">public</span> UserController()</li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">if</span> (!<span style="color: #2b91af;">FakeDbContext</span>.Instance.Users.Any())</li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: #2b91af;">FakeDbContext</span>.Instance.Users = <span style="color: blue;">new</span> <span style="color: #2b91af;">List</span><<span style="color: #2b91af;">User</span>>() </li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">new</span> <span style="color: #2b91af;">User</span>(){ Id = 1, FirstName = <span style="color: #a31515;">"Roberto"</span>, LastName=<span style="color: #a31515;">"Carlos"</span>, Email=<span style="color: #a31515;">"robi_carlo@gmail.com"}</span>,</li>
<li> <span style="color: blue;">new</span> <span style="color: #2b91af;">User</span>(){ Id = 2, FirstName = <span style="color: #a31515;">"Zinédine"</span>, LastName=<span style="color: #a31515;">"Zidane"</span>, Email=<span style="color: #a31515;">"zizu@live.com"}</span>,</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">new</span> <span style="color: #2b91af;">User</span>(){ Id = 2, FirstName = <span style="color: #a31515;">"Peter"</span>, LastName=<span style="color: #a31515;">"Schmeichel"</span>, Email=<span style="color: #a31515;">"scheisse@yahoo.com"}</span>,</li>
<li> };</li>
<li style="background: #f3f3f3;"> }</li>
<li> }</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: green;">// GET api/person</span></li>
<li style="background: #f3f3f3;"> [HttpGet]</li>
<li> <span style="color: blue;">public</span> <span style="color: #2b91af;">HttpResponseMessage</span> Get()</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">return</span> Request.CreateResponse<ReadOnlyCollection<<span style="color: #2b91af;">User</span>>>(<span style="color: #2b91af;">HttpStatusCode</span>.OK, <span style="color: #2b91af;">FakeDbContext</span>.Instance.Users.AsReadOnly());</li>
<li style="background: #f3f3f3;"> }</li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: green;">// GET api/person/5</span></li>
<li> [HttpGet]</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">public</span> <span style="color: #2b91af;">HttpResponseMessage</span> Get(<span style="color: blue;">int</span> id)</li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">var</span> resultUser = <span style="color: #2b91af;">FakeDbContext</span>.Instance.Users.FirstOrDefault(u => u.Id == id);</li>
<li> <span style="color: blue;">if</span> (resultUser == <span style="color: blue;">null</span>)</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">return</span> Request.CreateErrorResponse(<span style="color: #2b91af;">HttpStatusCode</span>.NotFound, <span style="color: #a31515;">"User dones`t exists."</span>);</li>
<li style="background: #f3f3f3;"> }</li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: blue;">return</span> Request.CreateResponse<<span style="color: #2b91af;">User</span>>(<span style="color: #2b91af;">HttpStatusCode</span>.OK, resultUser);</li>
<li> }</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: green;">// POST api/person</span></li>
<li style="background: #f3f3f3;"> [HttpPost]</li>
<li> <span style="color: blue;">public</span> <span style="color: #2b91af;">HttpResponseMessage</span> Post(<span style="color: #2b91af;">User</span> value)</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">if</span> (value == <span style="color: blue;">null</span>)</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">return</span> Request.CreateErrorResponse(<span style="color: #2b91af;">HttpStatusCode</span>.BadRequest, <span style="color: #a31515;">"Null User object."</span>);</li>
<li style="background: #f3f3f3;"> }</li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: green;">// Checking user already exists in a list.</span></li>
<li> <span style="color: blue;">if</span> (<span style="color: #2b91af;">FakeDbContext</span>.Instance.Users.Contains(value))</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">return</span> Request.CreateErrorResponse(<span style="color: #2b91af;">HttpStatusCode</span>.Conflict, <span style="color: #a31515;">"User already exists."</span>);</li>
<li style="background: #f3f3f3;"> }</li>
<li> <span style="color: blue;">else</span></li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: #2b91af;">FakeDbContext</span>.Instance.Users.Add(value);</li>
<li style="background: #f3f3f3;"> }</li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: blue;">return</span> Request.CreateResponse(<span style="color: #2b91af;">HttpStatusCode</span>.Created);</li>
<li> }</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: green;">// PUT api/person/5</span></li>
<li style="background: #f3f3f3;"> [HttpPut]</li>
<li> <span style="color: blue;">public</span> <span style="color: #2b91af;">HttpResponseMessage</span> Put(<span style="color: blue;">int</span> id, [<span style="color: #2b91af;">FromBody</span>] <span style="color: #2b91af;">User</span> value)</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">if</span> (value == <span style="color: blue;">null</span>)</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">return</span> Request.CreateErrorResponse(<span style="color: #2b91af;">HttpStatusCode</span>.BadRequest, <span style="color: #a31515;">"Null User object."</span>);</li>
<li style="background: #f3f3f3;"> }</li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: blue;">if</span> (!<span style="color: #2b91af;">FakeDbContext</span>.Instance.Users.Any(u => u.Id == id))</li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">return</span> Request.CreateErrorResponse(<span style="color: #2b91af;">HttpStatusCode</span>.NotFound, <span style="color: #a31515;">"User dones`t exists."</span>);</li>
<li> }</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">else</span></li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: #2b91af;">FakeDbContext</span>.Instance.Users.Remove(value);</li>
<li> <span style="color: #2b91af;">FakeDbContext</span>.Instance.Users.Add(value);</li>
<li style="background: #f3f3f3;"> }</li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: blue;">return</span> Request.CreateResponse(<span style="color: #2b91af;">HttpStatusCode</span>.OK);</li>
<li> }</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: green;">// DELETE api/person/5</span></li>
<li style="background: #f3f3f3;"> [HttpDelete]</li>
<li> <span style="color: blue;">public</span> <span style="color: #2b91af;">HttpResponseMessage</span> Delete(<span style="color: blue;">int</span> id)</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">var</span> personToDelete = <span style="color: #2b91af;">FakeDbContext</span>.Instance.Users.FirstOrDefault(u => u.Id == id);</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">if</span> (personToDelete == <span style="color: blue;">null</span>)</li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">return</span> Request.CreateErrorResponse(<span style="color: #2b91af;">HttpStatusCode</span>.NotFound, <span style="color: #a31515;">"User dones`t exists."</span>);</li>
<li> }</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">else</span></li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: #2b91af;">FakeDbContext</span>.Instance.Users.Remove(personToDelete);</li>
<li> }</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: blue;">return</span> Request.CreateResponse(<span style="color: #2b91af;">HttpStatusCode</span>.OK);</li>
<li style="background: #f3f3f3;"> }</li>
<li> }</li>
</ol>
</div>
</div>
<br />
Now our service is ready to use and we run it and we can call each GET, POST, PUT and DELETE function by using any of HTTP Client.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeY0fPMI6LdIaPEGwe0yWH8r5WlC7MLjAbIwAlCE2MYg6gnVOj-JtmqEBHO5NSH1Q6hQVHrgLXqIAD_97YNB3PNNN4HextcIsPmGDt6i_dTG2G6iEdDAVSFM6tP7PD_BFQpbafyanjJHSg/s1600/get_user.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeY0fPMI6LdIaPEGwe0yWH8r5WlC7MLjAbIwAlCE2MYg6gnVOj-JtmqEBHO5NSH1Q6hQVHrgLXqIAD_97YNB3PNNN4HextcIsPmGDt6i_dTG2G6iEdDAVSFM6tP7PD_BFQpbafyanjJHSg/s640/get_user.png" width="517" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Picture 1. Calling GET and POST API from test HTTP Client.</td></tr>
</tbody></table>
<b style="background-color: white; color: #222222; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18px; text-align: center;"><span style="font-size: small;">Whole source code of the project is available <a href="http://www.dzapart.com.pl/BlogFiles/WebApi.7z" style="color: #888888; text-decoration: none;">here</a>.</span></b><br />
<b style="background-color: white; color: #222222; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18px; text-align: center;"><span style="font-size: small;"><br /></span></b>
Thank you.Damian Zaparthttp://www.blogger.com/profile/17026397366973677672noreply@blogger.comDublin, Ireland53.3498053 -6.260309699999993453.0463133 -6.9057566999999933 53.6532973 -5.6148626999999935tag:blogger.com,1999:blog-8522517990291142303.post-57405305627517489212013-06-20T21:10:00.001+01:002013-08-05T11:05:53.162+01:00Creating API with MVC ApiController part 1 (with introducing to MVC design pattern)<b>Introduction to MVC</b><br />
<b><br /></b>
In the last few years a software architecture changed very heavily. From desktop (forms) application which were very popular in Windows XP users move to <a href="http://en.wikipedia.org/wiki/Service-oriented_architecture">SOA </a>and now completely start using web based solution hosting in a <a href="http://en.wikipedia.org/wiki/Cloud_computing">cloud</a>. Of course such evolution is not something bad, just the opposite in my opinion because web based application are highly scalable, better secured and available from each place in the Earth where user has an Internet connection. Such a big changes in software architecture cause that also programming model has to change. As response for this need, IT companies start working for on new technologies and improving existing ones. APIs became very popular tool in a developer hands and whole communication became much more lightweight (by switching from XML to JSON) - mainly because the emerging market of mobile devices.<br />
<br />
In a new MVC version 4 also Microsoft introduce some improvements which allow developers creating web services (APIs) in well known MVC environment - let`s start the with an <a href="http://msdn.microsoft.com/en-us/library/system.web.http.apicontroller(v=vs.108).aspx" target="_blank">ApiController</a>.<br />
<br />
Many of ASP.NET developers are familiar with MVC pattern because it`s very popular and also very easy to understand. The key thing/process (Picture 1.) which need to be understand is that based on URL an <b>controller </b>process user request and fill a <b>model </b>properties (optional) and then generate a <b>view </b>(with model data). After rendering HTML (<b>view</b>) its time for user interaction which will be finish when user send new request (synchronous or asynchronous) to the server - such request will be handle by a proper <b>controller</b>.To understand how URL address is translated into controller action please take a look <a href="http://msdn.microsoft.com/en-us/library/cc668201(v=vs.100).aspx" target="_blank">here</a>. Let`s take a look at he each component general definition:<br />
<ul>
<li>A <b>M</b>odel - represents the underlying, logical structure of data in a software application and the high-level class associated with it. This object model doesn`t contain any information about the user interface and also doesn`t contains any business logic.</li>
<li>A <b>V</b>iew - is a collection of HTML tags representing the elements in the user interface.</li>
<li>A <b>C</b>ontroller - represents the classes connecting the model and the view, and is used to communicate between classes in the model and view.</li>
</ul>
<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://upload.wikimedia.org/wikipedia/commons/f/fd/MVC-Process.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="http://upload.wikimedia.org/wikipedia/commons/f/fd/MVC-Process.png" width="292" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Picture 1. General schema o MVC pattern model.</td></tr>
</tbody></table>
MVC design pattern looks very easy, don`t you think? So why not extend this website technology to handle API for any kind of solution. To achieve this goal first of all we need to create a simple MVC project.First of all open Visual Studio 2012 and add new project of type ASP.NET MVC 4 Application (type some details like project name) and then select Basic application (Picture 2.).<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMAs38yQ51cZxzQt4kJyDm5RhyeAYIvidxpsp7dsBy15dDBNzTpIYswYZiQ9QKpT3lMqgpoHy62SLCbRelVUoAYDNrFGQwaIgQiLNxPRX3FFBTz_YivIRAm9wPexVaCgd47PoIbx5Py2H8/s1600/new_mvc_project.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="582" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMAs38yQ51cZxzQt4kJyDm5RhyeAYIvidxpsp7dsBy15dDBNzTpIYswYZiQ9QKpT3lMqgpoHy62SLCbRelVUoAYDNrFGQwaIgQiLNxPRX3FFBTz_YivIRAm9wPexVaCgd47PoIbx5Py2H8/s640/new_mvc_project.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Picture 2. Choosing proper MVC project template for API.</td></tr>
</tbody></table>
After creating a new project we should top for a while to understand project architecture (Picture 3.) which in details becomes from MVC architecture. There is a few folder which need to be described:<br />
<ul>
<li><b>App_Start</b>: store files with classes which logic will be executed on application start (not for session start). The file which is the most important from API creation point of view is <i>WebApiConfig.cs</i> . Inside it, in Register function default configuration for routing exists. By default all our API calls will be located at URL template like <i><b>http://website_address/api/controller_name/optional_id</b></i> for example <i>http://foo.com/api/user/1</i> will return details for user with ID = 1 if we send a <b>GET </b>request.</li>
</ul>
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="24" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li><span style="color: blue;">public</span> <span style="color: blue;">static</span> <span style="color: blue;">void</span> Register(<span style="color: #2b91af;">HttpConfiguration</span> config)</li>
<li style="background: #f3f3f3;"> {</li>
<li> config.Routes.MapHttpRoute(</li>
<li style="background: #f3f3f3;"> name: <span style="color: #a31515;">"DefaultApi"</span>,</li>
<li> routeTemplate: <span style="color: #a31515;">"api/{controller}/{id}"</span>,</li>
<li style="background: #f3f3f3;"> defaults: <span style="color: blue;">new</span> { id = <span style="color: #2b91af;">RouteParameter</span>.Optional }</li>
<li> );</li>
<li style="background: #f3f3f3;"> }</li>
</ol>
</div>
</div>
<br />
<br />
<ul>
<li><b>Controllers</b>: stores files with all controllers in the project. It`s very important to be familiar with controllers naming convention. By default controller name consist with two parts: prefix and 'Controller' sufix and in the URL we pass only prefix name (case insensitive). So if our controller has name like UserContoller we should us<span style="background-color: white;">e <i> <span style="color: #38761d;">api/user/ </span></i></span> instead <span style="color: red;">api/usercontroller/</span> in request URL.</li>
<li><b>Models</b>: this folder stores inforrmation about custom classes which will be used for passing data to the views.</li>
<li><b>Views</b>: stores all views but in pure API approach are useless.</li>
</ul>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDGHC8cVi_Op4TKVWsHZ4AeuufTxTVAjWZw1BO9nsUWLNvtaGo9XIHSb1gD46JyyndiwzvvHpuXiF8BqCk6JYrAtOCdiiHbEqmPmyl6NMTwxrAruR8wcXol_DLG62W6EKeZ3TxzbyNnhQa/s1600/solution.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDGHC8cVi_Op4TKVWsHZ4AeuufTxTVAjWZw1BO9nsUWLNvtaGo9XIHSb1gD46JyyndiwzvvHpuXiF8BqCk6JYrAtOCdiiHbEqmPmyl6NMTwxrAruR8wcXol_DLG62W6EKeZ3TxzbyNnhQa/s400/solution.png" width="270" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Picture 3. Default project architecture.</td></tr>
</tbody></table>
<br />
<h2>
Creating first RESTfull service</h2>
Now, we are more or less familiar with the project structure now we are on good way to start creating our REST API. First thing in all process is adding a new Controller (Picture 4.) to our project - it can be done by selecting Add -> Controllers and in new windows selecting ''<i>API controller with empty read/write actions</i>".<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-JA5eDfR2JOIERtGTr19ts2w9KLTYOImZ5UIduUjR_T46zSOWLSmRWY3aQeZwPGhKbYY9aa9uvu2PG67RVGlZ0zSyeosqOoQhAKlNzeNEqZXiTV6cxI5YyE7vIXg4vZk70nhi5CAm8w7l/s1600/controller.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="311" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-JA5eDfR2JOIERtGTr19ts2w9KLTYOImZ5UIduUjR_T46zSOWLSmRWY3aQeZwPGhKbYY9aa9uvu2PG67RVGlZ0zSyeosqOoQhAKlNzeNEqZXiTV6cxI5YyE7vIXg4vZk70nhi5CAm8w7l/s640/controller.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Picture 4. Adding new ApiController to Controllers folder.</td></tr>
</tbody></table>
<br />
By default a new empty controller is a simple class which derives from <a href="http://msdn.microsoft.com/en-us/library/system.web.http.apicontroller(v=vs.108).aspx" target="_blank">ApiContoller </a>base class. Inside this class we create several test functions, which manipulate on simple generic Dictionary<string,string>, as follow:<br />
<br />
<ul>
<li><span style="background-color: white; color: #2b91af; font-family: 'Courier New', Courier, monospace; font-size: 13px;">Dictionary</span><span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: 13px;"><</span><span style="background-color: white; color: blue; font-family: 'Courier New', Courier, monospace; font-size: 13px;">string</span><span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: 13px;">, </span><span style="background-color: white; color: blue; font-family: 'Courier New', Courier, monospace; font-size: 13px;">string</span><span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: 13px;">> Get(): [HttpGet] returns whole dictionary from fake DB context.</span></li>
<li><span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: 13px;"><span style="color: blue;">string</span> Get(<span style="color: blue;">string</span> id): </span><span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: 13px;">[HttpGet] returns single value basen on dictionary key.</span></li>
<li><span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: 13px;"><span style="color: blue;">void</span> Post(<span style="color: blue;">string</span> id, <span style="color: blue;">string</span> value):[HttpPost]</span><span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: 13px;"> create a new key-value pair.</span></li>
<li><span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: 13px;"><span style="color: blue;">void</span> Put(<span style="color: blue;">string</span> id, <span style="color: blue;">string</span> value): [HttpPut] updates existing key-value pair.</span></li>
<li><span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: 13px;"><span style="color: blue;">void</span><span style="background-color: #f3f3f3;"> Delete(</span><span style="color: blue;">string</span><span style="background-color: #f3f3f3;"> id): [HttpDelete] removes existing key-value pair based on a key.</span></span></li>
</ul>
<br />
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="38" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li><span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> Unsecured, very simple API for manipulating directory.</span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span></li>
<li style="background: #f3f3f3;"> <span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">SimpleController</span> : <span style="color: #2b91af;">ApiController</span></li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: green;">// GET api/simple</span></li>
<li> <span style="color: blue;">public</span> <span style="color: #2b91af;">Dictionary</span><<span style="color: blue;">string</span>, <span style="color: blue;">string</span>> Get()</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">return</span> <span style="color: #2b91af;">FakeDbContext</span>.Instance.Dictionary;</li>
<li style="background: #f3f3f3;"> }</li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: green;">// GET api/simple/5</span></li>
<li> <span style="color: blue;">public</span> <span style="color: blue;">string</span> Get(<span style="color: blue;">string</span> id)</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">return</span> <span style="color: #2b91af;">FakeDbContext</span>.Instance.Dictionary.FirstOrDefault(c => c.Key == id).Value;</li>
<li style="background: #f3f3f3;"> }</li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: green;">// POST http://localhost:38828/api/simple?id=1&value=5</span></li>
<li> <span style="color: blue;">public</span> <span style="color: blue;">void</span> Post(<span style="color: blue;">string</span> id, <span style="color: blue;">string</span> value)</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: #2b91af;">FakeDbContext</span>.Instance.Dictionary.Add(id, value);</li>
<li style="background: #f3f3f3;"> }</li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: green;">// PUT api/simple?id=1&value=5</span></li>
<li> <span style="color: blue;">public</span> <span style="color: blue;">void</span> Put(<span style="color: blue;">string</span> id, <span style="color: blue;">string</span> value)</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: #2b91af;">FakeDbContext</span>.Instance.Dictionary.Remove(id);</li>
<li style="background: #f3f3f3;"> <span style="color: #2b91af;">FakeDbContext</span>.Instance.Dictionary.Add(id, value);</li>
<li> }</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: green;">// DELETE api/simple/5</span></li>
<li style="background: #f3f3f3;"> <span style="color: blue;">public</span> <span style="color: blue;">void</span> Delete(<span style="color: blue;">string</span> id)</li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: #2b91af;">FakeDbContext</span>.Instance.Dictionary.Remove(id);</li>
<li> }</li>
<li style="background: #f3f3f3;"> }</li>
</ol>
</div>
</div>
<br />
As you can see in this example I have non descriptive function name (Get, Post, etc.). I decide to do that to show you easy you can create own API service. One thing you need to be aware of is <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html" target="_blank">HTTP method</a> which you are using to send a request - and there is only a few in common usage. Those methods are automatically mapped to the function name as I presented in the example, above but in a real world scenario you need to create much more descriptive function names. However if we change default function names we need to 'show' framework which method is suitable to handle specific type of method. We can do that by specifying one of the following function attributes:<br />
<ul>
<li>[<a href="http://msdn.microsoft.com/en-us/library/system.web.http.httpgetattribute(v=vs.108).aspx" target="_blank">HttpGet</a>]</li>
<li>[<a href="http://msdn.microsoft.com/en-us/library/system.web.http.httppostattribute(v=vs.108).aspx" target="_blank">HttpPost</a>]</li>
<li>[<a href="http://msdn.microsoft.com/en-us/library/system.web.http.httpputattribute(v=vs.108).aspx" target="_blank">HttpPut</a>]</li>
<li>[<a href="http://msdn.microsoft.com/en-us/library/system.web.http.httpdeleteattribute(v=vs.108).aspx" target="_blank">HttpDelete</a>]</li>
</ul>
Now it`s worth to test out solution - this is very easy and all you need to do is run the solution and send request using one of the HTTP methods to following URL template:<br />
<div style="text-align: center;">
<b>{Method} http://{local_address}:{local_port}/api/simple</b></div>
<div style="text-align: center;">
<b>for example</b></div>
<div style="text-align: center;">
<b><br /></b></div>
<div style="text-align: center;">
<span style="background-color: #f3f3f3; color: green; text-align: left;"><span style="font-family: inherit;">POST http://localhost:38828/api/simple?id=1&value=5</span></span></div>
<div style="text-align: center;">
<span style="background-color: #f3f3f3; color: green; font-family: 'Courier New', Courier, monospace; font-size: 13px; text-align: left;"><br /></span></div>
<i style="background-color: white;"><span style="color: #bf9000;">If someone of you is not familiar with sending HTTP requests by using other than GET (you send a GET request when you type some URL into browser address window) I can recommend very easy in use HTTP client (extension for Chrome) called <a href="https://chrome.google.com/webstore/detail/postman-rest-client/fdmmgilgnpjigdojojpjoooidkmcomcm" target="_blank">Postman</a>.</span></i><br />
<i style="background-color: white;"><span style="color: #bf9000;"><br /></span></i>
<span style="color: #38761d;">One more interesting thing is, as we can see on example presented below (Picture 3.), we are also able to modify result format just by manipulating value of the </span><a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html" target="_blank">Accept header</a><span style="color: #38761d;"> parameter. By passing response Accept header with value </span><i style="color: #38761d;"><b>application/xml </b></i><span style="color: #38761d;">or </span><i style="color: #38761d;"><b>application/json</b></i><span style="color: #38761d;"> we are changing whole response format.</span><br />
<span style="color: #38761d;"><br /></span>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLdRD12FLfviG9iTVhs_QSlG_wsSj2wYJocT7VuPI7l7u8HTcpSGqHC8R3nBbZSDR_jXSs51_8l6VTLaWWcOZdyls6H8TqUKCQDaeyKbbJwxClz14hBBHm4tc8gXjR63fFxNKyF5OoTbcU/s1600/controller.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLdRD12FLfviG9iTVhs_QSlG_wsSj2wYJocT7VuPI7l7u8HTcpSGqHC8R3nBbZSDR_jXSs51_8l6VTLaWWcOZdyls6H8TqUKCQDaeyKbbJwxClz14hBBHm4tc8gXjR63fFxNKyF5OoTbcU/s640/controller.png" width="405" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Picture 3. Testing simple API with results formatted as XML and JSON.</td></tr>
</tbody></table>
<div>
<div style="text-align: center;">
<b style="background-color: white; color: #222222; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18px;"><span style="font-size: medium;">Whole source code of the project is available <a href="http://www.dzapart.com.pl/BlogFiles/WebApi.7z" style="color: #888888; text-decoration: none;">here</a>.</span></b></div>
<br style="background-color: white; color: #222222; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18px;" />
<span style="background-color: white; color: #222222; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18px;">Thank you.</span></div>
Damian Zaparthttp://www.blogger.com/profile/17026397366973677672noreply@blogger.comDublin, Ireland53.3498053 -6.260309699999993453.0463133 -6.9057566999999933 53.6532973 -5.6148626999999935tag:blogger.com,1999:blog-8522517990291142303.post-49464301746238045092013-06-15T22:24:00.003+01:002013-06-15T22:24:49.642+01:00Asynchronous actions in ASP.NETAn asynchronous operations become very popular in modern programming because by using its developers can take full advantage of multicore processors and perform several operation at the same time. Multithreding exists in ASP.NET since 2.0 version but it was very sophisticated to use it. However starting from .NET 4.5, ASP.NET is fully compatible with <a href="http://www.asp.net/vnext/overview/aspnet/whats-new#_Toc318097376">all these great features</a>.<br />
<br />
To demonstrate how to start with the asynchronous operation in ASP.NET 4.5 I`ve created very simple solution which consist of three projects (Picture 1.):<br />
<ul>
<li><b>AsyncPageService </b>- REST service based on a <a href="http://msdn.microsoft.com/en-us/library/system.web.http.apicontroller(v=vs.108).aspx">ApiController</a>; provides function which will be called by the website.</li>
<li><b>AsyncPageWebsite </b>- main ASP.NET website.</li>
<li><b>Contracts </b>- contains shared type between service and website.</li>
</ul>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPBFwQ2qFH64yIdvcdy-ToyQOvHqzbUpWGO3v0j4xoQ2KFKl5fhOqiKQehmuHI9NkdFGCfngm-ShYIda-8oCWrQ45pEXQuyXQb9bh7IPIgGkCX_eeCSAyUi_SaNIpHoN2rgiPgvNmvpWSC/s1600/solution.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="126" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPBFwQ2qFH64yIdvcdy-ToyQOvHqzbUpWGO3v0j4xoQ2KFKl5fhOqiKQehmuHI9NkdFGCfngm-ShYIda-8oCWrQ45pEXQuyXQb9bh7IPIgGkCX_eeCSAyUi_SaNIpHoN2rgiPgvNmvpWSC/s400/solution.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Picture 1. Solution projects.</td></tr>
</tbody></table>
In my solution data is served by very simple REST web service, which is build by using <a href="http://msdn.microsoft.com/en-us/library/system.web.http.apicontroller(v=vs.108).aspx">ApiController</a> from ASP.NET MVC. Inside this I`ve created two controllers (first return N random integers and the second return hardcoded list of an <i>Contracts.User</i> - which is shared type from an Contracts library) for a GET requests and decided to stay with a default service configuration so response format (XML or JSON) relay on header '<a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html">accept</a>' value with XML by default. Below I presented action for generating random N random numbers - where N is determined by input function parameter with default value equals to 10.<br />
<br />
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li><span style="color: blue;">namespace</span> RestApi.Controllers</li>
<li style="background: #f3f3f3;">{</li>
<li> <span style="color: blue;">using</span> System;</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">using</span> System.Collections.Generic;</li>
<li> <span style="color: blue;">using</span> System.Collections.ObjectModel;</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">using</span> System.Web.Http;</li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: blue;">using</span> System.Web.Mvc;</li>
<li> <span style="color: blue;">using</span> MVC = System.Web.Mvc;</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">RandomController</span> : <span style="color: #2b91af;">ApiController</span></li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">public</span> <span style="color: #2b91af;">List</span><<span style="color: blue;">int</span>> GetRandomNumbers(<span style="color: blue;">int</span> count = 10)</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">var</span> result = <span style="color: blue;">new</span> <span style="color: #2b91af;">List</span><<span style="color: blue;">int</span>>();</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">var</span> random = <span style="color: blue;">new</span> <span style="color: #2b91af;">Random</span>();</li>
<li> <span style="color: blue;">var</span> tempRandom = 0;</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: blue;">for</span> (<span style="color: blue;">var</span> i = 0; i < count; i++)</li>
<li style="background: #f3f3f3;"> {</li>
<li> tempRandom = random.Next(0, 32);</li>
<li style="background: #f3f3f3;"> result.Add(tempRandom);</li>
<li> }</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: blue;">return</span> result;</li>
<li style="background: #f3f3f3;"> }</li>
<li> }</li>
<li style="background: #f3f3f3;">}</li>
</ol>
</div>
</div>
<br />
<br />After web services is ready it`s time to present how we can use it. To demonstrate working code I`ve created a Default.aspx page and put all logic in Page_Load function. This function has additional keyword '<a href="http://msdn.microsoft.com/en-us/library/vstudio/hh156513.aspx">async</a>' in the function signature because it needs to working with asynchronous calls. Inside that function body firstly HTTP client has been created to allow communication between web service and website. Secondly, to return JSON format from web service <i>accept </i>header need to be set to "<i>application/json</i>". Later in the code both endpoints are called by using build in asynchronous function <a href="http://msdn.microsoft.com/en-us/library/system.net.http.httpclient.getstringasync.aspx">GetStringAsync </a>(JSON is always a string) - return type of the both calls is <a href="http://msdn.microsoft.com/en-us/library/system.threading.tasks.task.aspx">Task </a>type. Next we need to wait until both until task complete and this functionality is provided by a built-in <a href="http://msdn.microsoft.com/en-us/library/hh194766.aspx">Task.WhenAll</a> function with <a href="http://msdn.microsoft.com/en-us/library/vstudio/hh156528.aspx">await</a> keyword - code will block in this line until both task finish. When both requests completed results of the tasks need to be deserialized to a proper objects type by using <a href="http://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.deserializeobject.aspx">DeserializeObject</a> extension function and target types will be use as DataSource for the a page controls.<br />
<br />
Last thing that needs to be done in Default.aspx is setting a new page property Async="true" to notify ASP.NET that page might handle asynchronous calls.<br />
<br />
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li> </li>
<li style="background: #f3f3f3;"><span style="color: blue;">namespace</span> AsyncPageWebsite</li>
<li>{</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">using</span> Contracts;</li>
<li> <span style="color: blue;">using</span> System;</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">using</span> System.Collections.Generic;</li>
<li> <span style="color: blue;">using</span> System.Diagnostics;</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">using</span> System.Net.Http;</li>
<li> <span style="color: blue;">using</span> System.Threading.Tasks;</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: blue;">public</span> <span style="color: blue;">partial</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">Default</span> : System.Web.UI.<span style="color: #2b91af;">Page</span></li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">private</span> <span style="color: #2b91af;">HttpClient</span> client;</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: blue;">protected</span> async <span style="color: blue;">void</span> Page_Load(<span style="color: blue;">object</span> sender, <span style="color: #2b91af;">EventArgs</span> e)</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: green;">// Creating HTTP Client for handling requests.</span></li>
<li style="background: #f3f3f3;"> <span style="color: blue;">this</span>.client = <span style="color: blue;">new</span> <span style="color: #2b91af;">HttpClient</span>();</li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: green;">// Setting return type from web service to JSON format.</span></li>
<li> <span style="color: blue;">this</span>.client.DefaultRequestHeaders.Accept.Add(<span style="color: blue;">new</span> System.Net.Http.Headers.<span style="color: #2b91af;">MediaTypeWithQualityHeaderValue</span>(<span style="color: #a31515;">"application/json"</span>));</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: green;">// Calling both services in asynchonous actions.</span></li>
<li style="background: #f3f3f3;"> <span style="color: blue;">var</span> getTeenRandomResultTask= <span style="color: blue;">this</span>.client.GetStringAsync(<span style="color: #a31515;">"http://localhost/AsyncPageService/api/random"</span>);</li>
<li> <span style="color: blue;">var</span> getUsersListStringTask = <span style="color: blue;">this</span>.client.GetStringAsync(<span style="color: #a31515;">"http://localhost/AsyncPageService/api/user"</span>);</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: green;">// Wait until all task finish.</span></li>
<li style="background: #f3f3f3;"> await Task.WhenAll(getTeenRandomResultTask, getUsersListStringTask);</li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: green;">// Deserializing strings from tasks results.</span></li>
<li> <span style="color: blue;">var</span> teenRandomResultList = Newtonsoft.Json.<span style="color: #2b91af;">JsonConvert</span>.DeserializeObject<<span style="color: #2b91af;">List</span><<span style="color: blue;">string</span>>>(getTeenRandomResultTask.Result);</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">var</span> userList = Newtonsoft.Json.<span style="color: #2b91af;">JsonConvert</span>.DeserializeObject<<span style="color: #2b91af;">List</span><User>>(getUsersListStringTask.Result);</li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: green;">// Bind IEnumerable types to the proper controls.</span></li>
<li> rRandomNumbers.DataSource = teenRandomResultList;</li>
<li style="background: #f3f3f3;"> gvUsers.DataSource = userList;</li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: green;">// Call the DataBind for whole page - cause call DataBind for each control on page.</span></li>
<li> <span style="color: blue;">this</span>.DataBind();</li>
<li style="background: #f3f3f3;"> }</li>
<li> }</li>
<li style="background: #f3f3f3;">}</li>
</ol>
</div>
</div>
<br />
Thank you.<br />
<br />
<b style="background-color: white; color: #222222; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18px;">Source code is available <a href="http://dzapart.com.pl/BlogFiles/AsyncPageWebsite.zip" style="color: #888888; text-decoration: none;" target="_blank">here</a>.</b><br />
<br />
Read more:<br />
<br />
<ul>
<li><a href="http://www.asp.net/web-forms/tutorials/aspnet-45/using-asynchronous-methods-in-aspnet-45">http://www.asp.net/web-forms/tutorials/aspnet-45/using-asynchronous-methods-in-aspnet-45</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx">http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx</a></li>
</ul>
<br />
<br />Damian Zaparthttp://www.blogger.com/profile/17026397366973677672noreply@blogger.comNaas, Co. Kildare, Ireland53.2205654 -6.659307899999930753.1825364 -6.7399888999999309 53.2585944 -6.5786268999999304tag:blogger.com,1999:blog-8522517990291142303.post-29947460391246520072013-05-10T15:26:00.000+01:002013-05-10T15:26:44.802+01:00Finding gaps in timeLet assume that we want to create a simple scheduler which allow user to plan meeting as long as he want with 1 minute precision. There is multiple ways to make such implementation but in this post I want to present an approach I used recently.<br />
<br />
In my implementation I`ve created separated type which represents any time period. I called it <i>Range </i>and it`s consists of three properties (one is read-only). Main idea behind creating this time is encapsulate state and end date of used defined time period.<br />
<br />
<pre style="background-color: white; margin: 0em; overflow: auto;"><code style="color: black; font-family: Consolas,"Courier New",Courier,Monospace; font-size: 10pt;"> <span style="color: green;">/// <summary></span>
<span style="color: green;">/// Represents range in time.</span>
<span style="color: green;">/// </summary></span>
<span style="color: blue;">public</span> <span style="color: blue;">class</span> Range
{
<span style="color: green;">/// <summary></span>
<span style="color: green;">/// Gets or sets represents range start time.</span>
<span style="color: green;">/// </summary></span>
<span style="color: blue;">public</span> DateTime StartTime { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }
<span style="color: green;">/// <summary></span>
<span style="color: green;">/// Gets or sets represents range end time.</span>
<span style="color: green;">/// </summary></span>
<span style="color: blue;">public</span> DateTime EndTime { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }
<span style="color: green;">/// <summary></span>
<span style="color: green;">/// Gets range period.</span>
<span style="color: green;">/// </summary></span>
<span style="color: blue;">public</span> TimeSpan Duration
{
<span style="color: blue;">get</span>
{
<span style="color: blue;">return</span> <span style="color: blue;">this</span>.EndTime.Subtract(<span style="color: blue;">this</span>.StartTime);
}
}
}</code></pre>
<br />
I`ve also created a <i>Scheduler </i>class. This class consists of only a few function as follow:<br />
<ul>
<li><i>AddRange </i>- add new date range to the collection on booked ranges if new range don`t overlapping with any existing range.</li>
<li><i>GetAllBookedDates </i>- returns all booked date ranges as <a href="http://msdn.microsoft.com/en-us/library/hh881542.aspx" target="_blank">IReadOnlyCollection<Range></a> collection</li>
<li><i>Overlaps </i>(with two overloads) - bool value which determines whether two time ranges are overlapping each other - also four <a href="http://msdn.microsoft.com/en-us/library/system.datetime.aspx" target="_blank">DateTime </a>objects can be used.</li>
<li><i>GetFreeTime </i>- searching for not booked ranges of time for given time boundary.</li>
</ul>
<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIX4ffC9HUUQf0m9QSA1BPYNvFqAroqdkM6S6J6v_jIeZKwmdXJPg-hsAyStfR4jTFaH_xmCRy7yY2Rb-hCZZkLHX17mlfKlEWZIEzsC0d6PuLgIoa5OXWyIwe_Ng1DFXEmimKPbIhjylo/s1600/dependencies.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="632" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIX4ffC9HUUQf0m9QSA1BPYNvFqAroqdkM6S6J6v_jIeZKwmdXJPg-hsAyStfR4jTFaH_xmCRy7yY2Rb-hCZZkLHX17mlfKlEWZIEzsC0d6PuLgIoa5OXWyIwe_Ng1DFXEmimKPbIhjylo/s640/dependencies.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Picture 1. Program dependencies.</td></tr>
</tbody></table>
<br />
Not it`s time for implementation part. Before creating core implementation of the gaps finding algorithm we need to create a simple static (can be also non-static) which allow to detect overlaps in a given period of time. An overload method of this function takes two parameters of Range type.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9ORWzBbSmfEZY1dWf9BUXCMFj6rQJufWTox3KXbgOZB9xY_Hdj0SRRIa8a2oQzeDSz7ZChTjQf1HrUoi6__f4X8H2cm09-yWrFbWFMmgZJnlAaua9SqMM9pijCumrbYMupAszMNv3R4Cx/s1600/time_overlap.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="90" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9ORWzBbSmfEZY1dWf9BUXCMFj6rQJufWTox3KXbgOZB9xY_Hdj0SRRIa8a2oQzeDSz7ZChTjQf1HrUoi6__f4X8H2cm09-yWrFbWFMmgZJnlAaua9SqMM9pijCumrbYMupAszMNv3R4Cx/s400/time_overlap.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Picture 2. Idea of overlapping a two time ranges.</td></tr>
</tbody></table>
<br />
<pre style="background-color: white; margin: 0em; overflow: auto;"><code style="color: black; font-family: Consolas,"Courier New",Courier,Monospace; font-size: 10pt;"><span style="color: blue;">public</span> <span style="color: blue;">static</span> <span style="color: blue;">bool</span> Overlaps(DateTime firstStart, DateTime firstEnd, DateTime secondStart, DateTime secondEnd)
{
<span style="color: blue;">return</span> (secondStart >= firstStart && secondStart < firstEnd) ||
(secondEnd <= firstEnd && secondEnd > firstStart) ||
(secondStart <= firstStart && secondEnd >= firstEnd) ||
(firstStart <= secondStart && firstEnd >= secondEnd);
}</code></pre>
<br />
<div>
<br /></div>
Now its time for the implementation of the most important function in whole program - finding free gaps in time. Assumption in this algorithm is precision up to 1 minute so it`s means that seconds and milliseconds are not taken under consideration while processing. After validating validity of the input, edge <i>DateTime </i>parameters a new collection of integer is created. Collection of integers is noting else but number of minutes inside edge <i>DateTime </i>range. Inside the for loop <b><i>i</i></b> variable is incremented and value of <b><i>i</i></b> represents number of minutes since lower boundary.<br />
<br />
<br />
<br />
<pre style="background-color: white; margin: 0em; overflow: auto;"><code style="color: black; font-family: Consolas,"Courier New",Courier,Monospace; font-size: 10pt;"> <span style="color: green;">/// <summary></span>
<span style="color: green;">/// Finds gaps in given time.</span>
<span style="color: green;">/// </summary></span>
<span style="color: green;">/// <param name="lowerBoundDate">Minimum date to get range for.</param></span>
<span style="color: green;">/// <param name="upperBoundDate">Maximum date to get range for.</param></span>
<span style="color: green;">/// <returns>Collection of free ranges.</returns></span>
<span style="color: blue;">public</span> IEnumerable<Range> GetFreeTime(DateTime lowerBoundDate, DateTime upperBoundDate)
{
<span style="color: blue;">if</span> (<span style="color: blue;">this</span>.BookedDates == <span style="color: blue;">null</span>)
{
<span style="color: blue;">throw</span> <span style="color: blue;">new</span> InvalidOperationException(<span style="color: #a31515;">"BookedDates can not be null"</span>);
}
<span style="color: blue;">if</span> (lowerBoundDate >= upperBoundDate)
{
<span style="color: blue;">throw</span> <span style="color: blue;">new</span> InvalidOperationException(<span style="color: #a31515;">"lowerBoundDate can not be greater or equals to upperBoundDate."</span>);
}
<span style="color: blue;">if</span> (!<span style="color: blue;">this</span>.BookedDates.Any())
{
<span style="color: blue;">return</span> <span style="color: blue;">new</span> List<Range>() { <span style="color: blue;">new</span> Range() { StartTime = lowerBoundDate, EndTime = upperBoundDate } };
}
<span style="color: blue;">var</span> resultList = <span style="color: blue;">new</span> List<Range>();
<span style="color: blue;">var</span> delta = upperBoundDate - lowerBoundDate;
<span style="color: blue;">var</span> totalRangeMinutes = Enumerable.Range(0, (<span style="color: blue;">int</span>)delta.TotalMinutes).ToArray();
<span style="color: blue;">var</span> currentDate = lowerBoundDate;
<span style="color: blue;">var</span> currentRange = <span style="color: blue;">new</span> Range();
Range freeRange = <span style="color: blue;">null</span>;
<span style="color: blue;">for</span> (<span style="color: blue;">var</span> i = 0; i < totalRangeMinutes.Count(); i++)
{
currentRange = <span style="color: blue;">new</span> Range() { StartTime = currentDate, EndTime = currentDate.AddMinutes(1) };
<span style="color: blue;">var</span> overlappingRange = <span style="color: blue;">this</span>.BookedDates.FirstOrDefault(c => <span style="color: blue;">this</span>.Overlaps(currentRange.StartTime, currentRange.EndTime, c.StartTime, c.EndTime));
<span style="color: blue;">if</span> (overlappingRange != <span style="color: blue;">null</span>)
{
<span style="color: green;">// Increment i to the end of current overlapping range.</span>
i = (<span style="color: blue;">int</span>)overlappingRange.EndTime.Subtract(lowerBoundDate).TotalMinutes + 1;
freeRange.EndTime = lowerBoundDate.AddMinutes((<span style="color: blue;">int</span>)overlappingRange.StartTime.Subtract(lowerBoundDate).TotalMinutes);
resultList.Add(freeRange);
freeRange = <span style="color: blue;">null</span>;
}
<span style="color: blue;">else</span>
{
<span style="color: blue;">if</span> (freeRange == <span style="color: blue;">null</span>)
{
freeRange = <span style="color: blue;">new</span> Range() { StartTime = currentDate };
}
}
currentDate = lowerBoundDate.AddMinutes(i);
}
<span style="color: green;">// Handle the case where we have free time until reach upper boundary.</span>
<span style="color: blue;">if</span> (freeRange != <span style="color: blue;">null</span> && freeRange.StartTime > lowerBoundDate)
{
<span style="color: blue;">if</span> (freeRange.EndTime < freeRange.StartTime)
{
freeRange.EndTime = upperBoundDate;
}
resultList.Add(freeRange);
}
<span style="color: blue;">return</span> resultList;
}</code></pre>
<br />
<br />
After these functions have been created it`s time for test it.<br />
<br />
<pre style="background-color: white; margin: 0em; overflow: auto;"><code style="color: black; font-family: Consolas,"Courier New",Courier,Monospace; font-size: 10pt;"><span style="color: blue;">static</span> <span style="color: blue;">void</span> Main(<span style="color: blue;">string</span>[] args)
{
<span style="color: blue;">var</span> scheduler = <span style="color: blue;">new</span> Scheduler();
scheduler.AddRange(<span style="color: blue;">new</span> Range() { StartTime = DateTime.UtcNow.AddDays(1), EndTime = DateTime.UtcNow.AddDays(1).AddHours(1) });
scheduler.AddRange(<span style="color: blue;">new</span> Range() { StartTime = DateTime.UtcNow.AddDays(1).AddHours(4), EndTime = DateTime.UtcNow.AddDays(1).AddHours(5) });
Console.WriteLine(<span style="color: #a31515;">"Booked dates."</span>);
<span style="color: blue;">var</span> usedDates = scheduler.GetAllBookedDates();
PrintDates(usedDates);
Console.WriteLine(<span style="color: #a31515;">"Free dates."</span>);
<span style="color: blue;">var</span> result = scheduler.GetFreeTime(DateTime.Today.AddDays(1), DateTime.Today.AddDays(2));
PrintDates(result);
}
<span style="color: green;">/// <summary></span>
<span style="color: green;">/// Prints result to the console.</span>
<span style="color: green;">/// </summary></span>
<span style="color: green;">/// <param name="ranges">Ranges to</param></span>
<span style="color: blue;">private</span> <span style="color: blue;">static</span> <span style="color: blue;">void</span> PrintDates(IEnumerable<Range> ranges)
{
<span style="color: blue;">foreach</span> (<span style="color: blue;">var</span> range <span style="color: blue;">in</span> ranges)
{
Console.WriteLine(<span style="color: #a31515;">"Start date: {0} - end date: {1}."</span>, range.StartTime, range.EndTime);
}
}</code></pre>
<br />
<b><span style="font-size: large;">Whole source code of the project is available <a href="https://docs.google.com/file/d/0Bxd_tNkfJQoLaUY0RElFeG1LeTA/edit?usp=sharing">here</a>.</span></b><br />
<br />
Thank you.Damian Zaparthttp://www.blogger.com/profile/17026397366973677672noreply@blogger.comtag:blogger.com,1999:blog-8522517990291142303.post-31835057503783429772013-04-13T00:46:00.002+01:002017-08-27T15:13:12.070+01:00Autocomplete control with ASP.NET MVC 4 and jQuery<div style="text-align: justify;">
Almost in each modern website project one of the feature is suggesting user possible items to select when he start typing one of them. Such functionality is done by using control named <b>autocomplete</b>. Under the hood it consists of at least three elements:</div>
<ul>
<li style="text-align: justify;">UI control which allow user to type some text - mainly this in HTML input of text type</li>
<li style="text-align: justify;">Server-side function which serves data to be auto-completed</li>
<li style="text-align: justify;">Client-side logic (written in JavaScript) which , by using AJAX, send request to the server asynchronously and then process the results.</li>
</ul>
<div>
<div style="text-align: justify;">
When we think about creating autocomplete control in ASP.NET MVC 4 we definitely should take a look at <a href="http://jqueryui.com/">jQueryUI </a>framework. One of the feature of this framework is autocomplete control which enables users to quickly find and select from a pre-populated list of values as they type, leveraging searching and filtering. That sounds very good and is excellently what we are looking for.</div>
</div>
<div>
<div style="text-align: justify;">
<br /></div>
</div>
<div>
<div style="text-align: justify;">
First step in autocomplete control creation is creating a new <a href="http://www.asp.net/mvc/mvc4" target="_blank">MVC 4</a> project in <a href="http://www.microsoft.com/visualstudio/eng/products/visual-studio-express-products" target="_blank">Visual Studio 2012</a> (picture 1.) and set it as Internet Application with Razor engine. After whole project created successfully , press F5 and validate build result - should complete without any error.</div>
</div>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiNx5tuZje0dyVbuIftAzRocK-6NF6OVrEDjGt-4U5-KIQIECvYmbDBNN-k1j8aSKgvkD9rLBrAVFm0L35ofhfMzvGxvbrVYfO1XrhS8GJuntMkQ89UeUkgTWyji_kL2K-9x4eU71Oluui/s1600/Mvc+Project.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="438" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiNx5tuZje0dyVbuIftAzRocK-6NF6OVrEDjGt-4U5-KIQIECvYmbDBNN-k1j8aSKgvkD9rLBrAVFm0L35ofhfMzvGxvbrVYfO1XrhS8GJuntMkQ89UeUkgTWyji_kL2K-9x4eU71Oluui/s1600/Mvc+Project.png" width="640"></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Picture 1. Creating MVC 4 project.</td></tr>
</tbody></table>
<div>
<div style="text-align: justify;">
Default ASP.MVC 4 project template already contains several very important features.One of them, which will be very usefull in our case, is predefined set of the JavaScript files (including jQuery and jQueryUI) located in the<i> ~/Scripts</i> folder. Other stuff is connected with membership provider and won`t be used in this tutorial, but to make it easier lets stay with template structure without removing anything.</div>
</div>
<div>
<div style="text-align: justify;">
<br /></div>
</div>
<div>
<div style="text-align: justify;">
First think we need to add to our solution in our custom model which will store information for view. The assumption here is we want to create two auto-completes that will be part of new AdminController. First one will be responsible for auto-completing car brand and the second will help with choosing proper globalization. Based on this information we can create our first class model which will be located in <i>~/Models/Admin/ManageModel.cs</i> .Our model will store ifnroation about SelectedCarBrandId and culture Id - very simple.</div>
<div style="text-align: justify;">
<br />
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<ins class="adsbygoogle"
style="display:block"
data-ad-format="fluid"
data-ad-layout="image-side"
data-ad-layout-key="-fg+5r+6l-ft+4e"
data-ad-client="ca-pub-2921101697945774"
data-ad-slot="9471661303"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li><span style="color: blue;">namespace</span> Autocomplete.Models.Admin</li>
<li style="background: #f3f3f3;">{</li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> Stores information for manage view.</span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span></li>
<li style="background: #f3f3f3;"> <span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">ManageModel</span></li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> Gets or sets the selected car brand id.</span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span></li>
<li> <span style="color: blue;">public</span> <span style="color: blue;">int</span>? SelectedCarBrandId { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> Gets or sets the selected culture code.</span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span></li>
<li style="background: #f3f3f3;"> <span style="color: blue;">public</span> <span style="color: blue;">string</span> SelectedCultureCode { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</li>
<li> }</li>
<li style="background: #f3f3f3;">}</li>
</ol>
</div>
</div>
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<ins class="adsbygoogle"
style="display:block"
data-ad-format="fluid"
data-ad-layout="image-side"
data-ad-layout-key="-fg+5r+6l-ft+4e"
data-ad-client="ca-pub-2921101697945774"
data-ad-slot="9471661303"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
<br />
<span style="color: #999999; font-size: x-small;"><b>Tip</b>:</span><br />
<span style="color: #999999; font-size: x-small;">For C# beginners worth to explain is type of the SelectedCarBrandId - this is <b> int?</b>. Integer is value type so this mean that has default value assigned after declaration (0 at this case). To allow put null value to object of integer type we need to declare our type as <a href="http://msdn.microsoft.com/en-us/library/1t3y8s4s(v=vs.110).aspx" target="_blank">Nullable<T></a> struct and this is equals with the <b>int?</b> syntax. Thanks doing that we can type<i> int? integerValue = null;</i></span><br />
<br />
After we done with model, now it`s time for creating new controller (in <i>~/Controller/AdminController.cs</i>). Creating new controller cause that we have new route value available (<i>http://localhost/Admin/</i>) in our project but there is no view to present. But focus at the controller first. Our <i>AdminController</i> containts two function and both of them returns <i>ActionResults </i>(read - returns view). Name of this function is also the same (so we can expect new action available on website <i>http://localhost/Admin/Manage)</i> but whole signature is different. First of all second fuction takes model as parameter and additionally is decorated with <a href="http://msdn.microsoft.com/en-us/library/system.web.mvc.httppostattribute(v=vs.108).aspx" target="_blank">HttpPostAttribute</a> . The reason why it is done in that way is difference between how to get this two action. When user open page under the hood uses GET request without any parameters (in this case). Then he changing something on the website and click the submit button - it causes POST request and sends HTML form to the server. That is why we have two function where first (GET) function just render the view and the second (POST) process provider by user data (this data is binded to the model of the <i>ManageModel </i>type at this case).<br />
<br /></div>
</div>
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
<div style="text-align: justify;">
Code Snippet</div>
</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li style="text-align: justify;"><span style="color: blue;">namespace</span> Autocomplete.Controllers</li>
<li style="background-color: #f3f3f3; background-position: initial initial; background-repeat: initial initial; text-align: justify;">{</li>
<li style="text-align: justify;"> <span style="color: blue;">using</span> System.Collections.Generic;</li>
<li style="background-color: #f3f3f3; background-position: initial initial; background-repeat: initial initial; text-align: justify;"> <span style="color: blue;">using</span> System.Globalization;</li>
<li style="text-align: justify;"> <span style="color: blue;">using</span> System.Linq;</li>
<li style="background-color: #f3f3f3; background-position: initial initial; background-repeat: initial initial; text-align: justify;"> <span style="color: blue;">using</span> System.Web.Mvc;</li>
<li style="text-align: justify;"> </li>
<li style="background-color: #f3f3f3; background-position: initial initial; background-repeat: initial initial; text-align: justify;"> <span style="color: blue;">using</span> Autocomplete.Models.Admin;</li>
<li style="text-align: justify;"> </li>
<li style="background-color: #f3f3f3; background-position: initial initial; background-repeat: initial initial; text-align: justify;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span></li>
<li style="text-align: justify;"> <span style="color: grey;">///</span><span style="color: green;"> Controlles for admini purposes.</span></li>
<li style="background-color: #f3f3f3; background-position: initial initial; background-repeat: initial initial; text-align: justify;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span></li>
<li style="text-align: justify;"> <span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">AdminController</span> : Controller</li>
<li style="background-color: #f3f3f3; background-position: initial initial; background-repeat: initial initial; text-align: justify;"> {</li>
<li style="text-align: justify;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span></li>
<li style="background-color: #f3f3f3; background-position: initial initial; background-repeat: initial initial; text-align: justify;"> <span style="color: grey;">///</span><span style="color: green;"> Generate view for main admin page.</span></li>
<li style="text-align: justify;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span></li>
<li style="background-color: #f3f3f3; background-position: initial initial; background-repeat: initial initial; text-align: justify;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><returns></span><span style="color: green;">View of the main page.</span><span style="color: grey;"></returns></span></li>
<li style="text-align: justify;"> <span style="color: blue;">public</span> ActionResult Manage()</li>
<li style="background-color: #f3f3f3; background-position: initial initial; background-repeat: initial initial; text-align: justify;"> {</li>
<li style="text-align: justify;"> ManageModel model = <span style="color: blue;">new</span> ManageModel();</li>
<li style="background-color: #f3f3f3; background-position: initial initial; background-repeat: initial initial; text-align: justify;"> <span style="color: blue;">return</span> View(model);</li>
<li style="text-align: justify;"> }</li>
<li style="background-color: #f3f3f3; background-position: initial initial; background-repeat: initial initial; text-align: justify;"> </li>
<li style="text-align: justify;"> [HttpPost]</li>
<li style="background-color: #f3f3f3; background-position: initial initial; background-repeat: initial initial; text-align: justify;"> <span style="color: blue;">public</span> ActionResult Manage(ManageModel model)</li>
<li style="text-align: justify;"> {</li>
<li style="background-color: #f3f3f3; background-position: initial initial; background-repeat: initial initial; text-align: justify;"> <span style="color: blue;">return</span> View();</li>
<li style="text-align: justify;"> }</li>
<li style="background-color: #f3f3f3; background-position: initial initial; background-repeat: initial initial; text-align: justify;"> }</li>
<li style="text-align: justify;">}</li>
</ol>
</div>
</div>
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<ins class="adsbygoogle"
style="display:block"
data-ad-format="fluid"
data-ad-layout="image-side"
data-ad-layout-key="-fg+5r+6l-ft+4e"
data-ad-client="ca-pub-2921101697945774"
data-ad-slot="9471661303"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
<div>
<div style="text-align: justify;">
<br />
Next step is create a simple view to display UI for the user. Our view, called Manage.cshtml (picture 2.) will be stored in the following location <i>~/Views/Admin/Manage.cshtml </i>and will take main layout from parent page which in this case will be<i> _Layout.cshtml</i>.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjV9vLuOx69i_uiLdyYgzfbSaRfGGmWzKon8IjKL7v_iheslX7wDkXZ3kLGNwMHWHXIsKFrQwa-zPsdvau_9ZoS89LJrE-T-trCx_WlBY7b9rz-4gerccU7UC_5qFDNOXZU3lYO3csnzME3/s1600/new_view.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="392" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjV9vLuOx69i_uiLdyYgzfbSaRfGGmWzKon8IjKL7v_iheslX7wDkXZ3kLGNwMHWHXIsKFrQwa-zPsdvau_9ZoS89LJrE-T-trCx_WlBY7b9rz-4gerccU7UC_5qFDNOXZU3lYO3csnzME3/s1600/new_view.png" width="400"></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Picture 2. Adding view with default layout.</td></tr>
</tbody></table>
Just after creation our new Manage view contains some predefined tags and the most important at this stage is connection between a view and their layout (line 5). On this view we wish to create our two auto-completes (which calls separate actions) but before during that we need to create a form. The reason why we wan to use form is that we want to send data from UI to server and this need to be done thanks form element. Form can be generated easily by using <a href="http://msdn.microsoft.com/en-us/library/dd492590(v=vs.108).aspx" target="_blank"><i>BeginForm</i></a> function from <i>HtmlHelper </i>(line 8). The first parameter of this function represent action name (function on the controller that we want to call after a POST) and controller name as the second. To make a POST to the sever we need also provide submit button which is simple input of submit type (line 13).<br />
<br />
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li><span style="background: #ffff00;">@</span><span style="color: blue;">using</span> Autocomplete.Helpers;</li>
<li style="background: #f3f3f3;"><span style="background: #ffff00;">@model </span>Autocomplete.Models.Admin.ManageModel</li>
<li><span style="background: #ffff00;">@{</span></li>
<li style="background: #f3f3f3;"> ViewBag.Title = <span style="color: #a31515;">"Manage"</span>;</li>
<li> Layout = <span style="color: #a31515;">"~/Views/Shared/_Layout.cshtml"</span>;</li>
<li style="background: #f3f3f3;">}</li>
<li><br /></li>
<li style="background: #f3f3f3;"><span style="background: #ffff00;">@</span><span style="color: blue;">using</span> (Html.BeginForm(<span style="color: #a31515;">"Manage"</span>, <span style="color: #a31515;">"Admin"</span>))</li>
<li>{</li>
<li style="background: #f3f3f3;"> <span style="color: blue;"><</span><span style="color: maroon;">h2</span><span style="color: blue;">></span></li>
<li> Manage<span style="color: blue;"></</span><span style="color: maroon;">h2</span><span style="color: blue;">></span></li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: blue;"><</span><span style="color: maroon;">input</span> <span style="color: red;">type</span><span style="color: blue;">="submit"</span> <span style="color: red;">value</span><span style="color: blue;">="Submit"</span> <span style="color: blue;">/></span></li>
<li style="background: #f3f3f3;">}</li>
</ol>
</div>
</div>
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- dzapart_main_Blog1_300x250_as -->
<ins class="adsbygoogle"
style="display:inline-block;width:300px;height:250px"
data-ad-client="ca-pub-2921101697945774"
data-ad-slot="7528309165"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
<br />
Now it`s time for achieve our goal and introduce auto-completes controls. Before we do that we need make sure that we provided model for our view already (we want to use <i>ManageModel </i>for <i>Manage </i>view) which allow us to work with a strongly typed view later. Making such connection is quite easy and its noting else then putting namespace declaration for model and calling model type with a <i><b>@model</b></i> directive (line 1 and 2 above). Next we switch to implementation of our helper method which will extend standard <a href="http://msdn.microsoft.com/en-us/library/system.web.mvc.htmlhelper(v=vs.108).aspx" target="_blank">HtmlHelper</a> by adding new extension function with partial signature <b><i><a href="http://msdn.microsoft.com/en-us/library/system.web.mvc.mvchtmlstring(v=vs.108).aspx" target="_blank">MvcHtmlString</a> AutocompleteFor<TModel, TValue></i></b>. The most important thing in the function signature is that it takes model type (<b>TModel</b>) and by expression also takes model properties as <b>TValue</b>. Method has two overloaded definition (simple and more advance) but in both cases the most important thing is <b><i>actionUrl </i></b>parameters which defines controller action which will be called when user types more then two characters into auto-complete (will be introduced later).<br />
<br />
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li><span style="color: blue;">namespace</span> Autocomplete.Helpers</li>
<li style="background: #f3f3f3;">{</li>
<li> <span style="color: blue;">using</span> System.Linq.Expressions;</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">using</span> System.Text;</li>
<li> <span style="color: blue;">using</span> System.Web.Mvc;</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">using</span> System.Web.Mvc.Html;</li>
<li> <span style="color: blue;">using</span> System;</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">using</span> System.Collections.Generic;</li>
<li> <span style="color: blue;">using</span> System.Linq;</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">using</span> System.Web;</li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: blue;">public</span> <span style="color: blue;">static</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">AutocompleteHelper</span></li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> Create autocomplete control by using jQueryUi.</span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><typeparam name="TModel"></span><span style="color: green;">Type of the view model.</span><span style="color: grey;"></typeparam></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><typeparam name="TValue"></span><span style="color: green;">Selected properties type.</span><span style="color: grey;"></typeparam></span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><param name="helper"></span><span style="color: green;">Html helper to extend.</span><span style="color: grey;"></param></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><param name="expression"></span><span style="color: green;">The HTML helper instance that this method extends.</span><span style="color: grey;"></param></span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><param name="actionUrl"></span><span style="color: green;">Controller action to call after user start typing.</span><span style="color: grey;"></param></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><returns></span><span style="color: green;">Autocomplete HTML string.</span><span style="color: grey;"></returns></span></li>
<li> <span style="color: blue;">public</span> <span style="color: blue;">static</span> <span style="color: #2b91af;">MvcHtmlString</span> AutocompleteFor<TModel, TValue>(<span style="color: blue;">this</span> <span style="color: #2b91af;">HtmlHelper</span><TModel> helper, <span style="color: #2b91af;">Expression</span><<span style="color: #2b91af;">Func</span><TModel, TValue>> expression, <span style="color: blue;">string</span> actionUrl)</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">return</span> CreateAutocomplete(helper, expression, actionUrl, <span style="color: blue;">null</span>, <span style="color: blue;">null</span>);</li>
<li style="background: #f3f3f3;"> }</li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> Create autocomplete control by using jQueryUi with additional parameters.</span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><typeparam name="TModel"></span><span style="color: green;">Type of the view model.</span><span style="color: grey;"></typeparam></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><typeparam name="TValue"></span><span style="color: green;">Selected properties type.</span><span style="color: grey;"></typeparam></span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><param name="helper"></span><span style="color: green;">Html helper to extend.</span><span style="color: grey;"></param></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><param name="expression"></span><span style="color: green;">The HTML helper instance that this method extends.</span><span style="color: grey;"></param></span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><param name="actionUrl"></span><span style="color: green;">Controller action to call after user start typing.</span><span style="color: grey;"></param></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><param name="isRequired"></span><span style="color: green;">Determines field is required.</span><span style="color: grey;"></param></span></li>
<li> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><param name="placeholder"></span><span style="color: green;">Placeholder text to present when control containts no data.</span><span style="color: grey;"></param></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><returns></span><span style="color: green;">Autocomplete HTML string.</span><span style="color: grey;"></returns></span></li>
<li> <span style="color: blue;">public</span> <span style="color: blue;">static</span> <span style="color: #2b91af;">MvcHtmlString</span> AutocompleteFor<TModel, TValue>(<span style="color: blue;">this</span> <span style="color: #2b91af;">HtmlHelper</span><TModel> helper, <span style="color: #2b91af;">Expression</span><<span style="color: #2b91af;">Func</span><TModel, TValue>> expression, <span style="color: blue;">string</span> actionUrl, <span style="color: blue;">bool</span>? isRequired, <span style="color: blue;">string</span> placeholder)</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">return</span> CreateAutocomplete(helper, expression, actionUrl, placeholder, isRequired);</li>
<li style="background: #f3f3f3;"> }</li>
<li> }</li>
<li style="background: #f3f3f3;">}</li>
</ol>
</div>
</div>
<br />
In the implementation above both function calls the same method in the function body. That function is responsible for creating HTML tags for auto-complete control based of passed parameters. There is several important places inside this function that is worth to discuss:<br />
<ul>
<li>line 49: contains adding attribute for the input control that will be kind of representative for auto-complete control in whole solution.</li>
<li>line 50: URL action to be called after user typed more then two characters in control. </li>
<li>line 66: creating <input type='hidden' /> for storing value (not label) selected by user from auto-complete. Name of the value is equal to the property name indicated in expression (field of the model). This also set default value based on model value.</li>
<li>line 68: add to the auto-complete attribute which will store name of the associated hidden control.</li>
<li>line 71: creating input with set of attributes that will be used by JavaScript to detect and generate auto-complete during run-time.</li>
</ul>
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="45" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li> <span style="color: blue;">private</span> <span style="color: blue;">static</span> <span style="color: #2b91af;">MvcHtmlString</span> CreateAutocomplete<TModel, TValue>(<span style="color: #2b91af;">HtmlHelper</span><TModel> helper, <span style="color: #2b91af;">Expression</span><<span style="color: #2b91af;">Func</span><TModel, TValue>> expression, <span style="color: blue;">string</span> actionUrl, <span style="color: blue;">string</span> placeholder, <span style="color: blue;">bool</span>? isRequired)</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">var</span> attributes = <span style="color: blue;">new</span> <span style="color: #2b91af;">Dictionary</span><<span style="color: blue;">string</span>, <span style="color: blue;">object</span>></li>
<li style="background: #f3f3f3;"> {</li>
<li> { <span style="color: #a31515;">"data-autocomplete"</span>, <span style="color: blue;">true</span> },</li>
<li style="background: #f3f3f3;"> { <span style="color: #a31515;">"data-action"</span>, actionUrl }</li>
<li> };</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: blue;">if</span> (<span style="color: blue;">string</span>.IsNullOrWhiteSpace(placeholder))</li>
<li style="background: #f3f3f3;"> {</li>
<li> attributes.Add(<span style="color: #a31515;">"placeholder"</span>, placeholder);</li>
<li style="background: #f3f3f3;"> }</li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: blue;">if</span> (isRequired.HasValue && isRequired.Value)</li>
<li> {</li>
<li style="background: #f3f3f3;"> attributes.Add(<span style="color: #a31515;">"required"</span>, <span style="color: #a31515;">"required"</span>);</li>
<li> }</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: #2b91af;">Func</span><TModel, TValue> method = expression.Compile();</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">var</span> value = method((TModel)helper.ViewData.Model);</li>
<li> <span style="color: blue;">var</span> baseProperty=((<span style="color: #2b91af;">MemberExpression</span>) expression.Body).Member.Name;</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">var</span> hidden = helper.Hidden(baseProperty, value);</li>
<li> </li>
<li style="background: #f3f3f3;"> attributes.Add(<span style="color: #a31515;">"data-value-name"</span>, baseProperty);</li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: blue;">var</span> automcompleteName = baseProperty + <span style="color: #a31515;">"_autocomplete"</span>;</li>
<li> <span style="color: blue;">var</span> textBox = helper.TextBox(automcompleteName, <span style="color: blue;">null</span>, <span style="color: blue;">string</span>.Empty, attributes);</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: blue;">var</span> builder = <span style="color: blue;">new</span> <span style="color: #2b91af;">StringBuilder</span>();</li>
<li style="background: #f3f3f3;"> builder.AppendLine(hidden.ToHtmlString());</li>
<li> builder.AppendLine(textBox.ToHtmlString());</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: blue;">return</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">MvcHtmlString</span>(builder.ToString());</li>
<li style="background: #f3f3f3;"> }</li>
</ol>
</div>
</div>
<br />
Lets now focus on the auto-complete logic. Because some action of an auto-complete takes place on the client-side we need to use JavaScript code to create such behavior and also to send AJAX request and process data from a response. First of all lets then create new file <b>AutocompleteScript.js</b> located in the path <i>~/Script/AutocompleteScript.js </i>(code below). After website is fully loaded we call <i>CreateAutocomplete </i>function (line 1-3). This function under the hood by using jQuery attribute selector gathers all elements with a <i>data-autocomplete</i> attribute (and our auto-complete will have such one). Later it iterates through selected collection by using <a href="http://api.jquery.com/jQuery.each/" target="_blank">each</a> function and process each element separately. During processing is takes URL action form which point to controller function (line 7) in the next line call auto-complete creation. Inside that creation, except <i>success </i>function that will be called after user select item from suggestion list, we have <i>source </i>which is simple AJAX call with parameters:<br />
<ul>
<li><i>url</i>: action on the controller.</li>
<li><i>dataType</i>:<i> </i>set as jSon.</li>
<li><i>data</i>: provided by the user text inside the control which will be used to filter the result set.</li>
<li><span style="font-family: Courier New, Courier, monospace; font-size: x-small;">success</span>: process the response and fill suggestion list</li>
</ul>
</div>
</div>
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li>$(document).ready(<span style="color: blue;">function</span> () {</li>
<li style="background: #f3f3f3;"> CreateAutocomplete();</li>
<li>});</li>
<li style="background: #f3f3f3;"> </li>
<li><span style="color: blue;">function</span> CreateAutocomplete() {</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">var</span> inputsToProcess = $(<span style="color: maroon;">'[data-autocomplete]'</span>).each(<span style="color: blue;">function</span> (index, element) {</li>
<li> <span style="color: blue;">var</span> requestUrl = $(element).attr(<span style="color: maroon;">'data-action'</span>);</li>
<li style="background: #f3f3f3;"> </li>
<li> $(element).autocomplete({</li>
<li style="background: #f3f3f3;"> minLength: 2,</li>
<li> source: <span style="color: blue;">function</span> (request, response) {</li>
<li style="background: #f3f3f3;"> $.ajax({</li>
<li> url: requestUrl,</li>
<li style="background: #f3f3f3;"> dataType: <span style="color: maroon;">"json"</span>,</li>
<li> data: { query: request.term },</li>
<li style="background: #f3f3f3;"> success: <span style="color: blue;">function</span> (data) {</li>
<li> response($.map(data, <span style="color: blue;">function</span> (item) {</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">return</span> {</li>
<li> label: item.Label,</li>
<li style="background: #f3f3f3;"> value: item.Label,</li>
<li> realValue: item.Value</li>
<li style="background: #f3f3f3;"> };</li>
<li> }));</li>
<li style="background: #f3f3f3;"> },</li>
<li> });</li>
<li style="background: #f3f3f3;"> },</li>
<li> select: <span style="color: blue;">function</span> (event, ui) {</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">var</span> hiddenFieldName = $(<span style="color: blue;">this</span>).attr(<span style="color: maroon;">'data-value-name'</span>);</li>
<li> $(<span style="color: maroon;">'#'</span>+hiddenFieldName).val(ui.item.realValue);</li>
<li style="background: #f3f3f3;"> }</li>
<li> });</li>
<li style="background: #f3f3f3;"> });</li>
<li>}</li>
</ol>
</div>
</div>
<br />
We almost done and our solution is almost ready. We heed to complete just several step more:<br />
<br />
<div style="text-align: justify;">
1) We put client-side auto-complete login in separated JavaScript file that is why we need to attach it to our view. To do that first of all it need to become part of the <a href="http://msdn.microsoft.com/en-us/library/system.web.optimization.scriptbundle.aspx" target="_blank">ScriptBundle</a> object - so the code presented below need to be added to the <i style="text-align: justify;">~/App_Start/</i><i>BundleConfig.cs</i> file. Thanks doing that on our <i>Manage </i>view we can then put line <b>@Scripts.Render("~/bundles/jquery")</b>.</div>
<br />
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="26" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li>bundles.Add(<span style="color: blue;">new</span> <span style="color: #2b91af;">ScriptBundle</span>(<span style="color: #a31515;">"~/bundles/custom"</span>).Include(</li>
<li style="background: #f3f3f3;"> <span style="color: #a31515;">"~/Scripts/AutocompleteScript.js"</span>));</li>
</ol>
</div>
</div>
<br />
2) Create two <i>AdminController </i>methods that will provide data for auto-completes. Remember here that parameter name have to be equals '<b><i>query</i></b>' and jSon result must <b>AllowGet</b>.<br />
<br />
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li><span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span></li>
<li style="background: #f3f3f3;"><span style="color: grey;">///</span><span style="color: green;"> Autocompletes car brand</span></li>
<li><span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span></li>
<li style="background: #f3f3f3;"><span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><param name="query"></span><span style="color: green;">Search term.</span><span style="color: grey;"></param></span></li>
<li><span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><returns></span><span style="color: green;">Json with search result.</span><span style="color: grey;"></returns></span></li>
<li style="background: #f3f3f3;">[<span style="color: #2b91af;">HttpGet</span>]</li>
<li><span style="color: blue;">public</span> <span style="color: #2b91af;">JsonResult</span> AutocompleteCars(<span style="color: blue;">string</span> query)</li>
<li style="background: #f3f3f3;">{</li>
<li> <span style="color: blue;">var</span> data = <span style="color: blue;">new</span> <span style="color: #2b91af;">Dictionary</span><<span style="color: blue;">int</span>, <span style="color: blue;">string</span>></li>
<li style="background: #f3f3f3;"> {</li>
<li> { 1, <span style="color: #a31515;">"Audi"</span> },</li>
<li style="background: #f3f3f3;"> { 2, <span style="color: #a31515;">"BMW"</span> },</li>
<li> { 3, <span style="color: #a31515;">"Opel"</span> },</li>
<li style="background: #f3f3f3;"> { 4, <span style="color: #a31515;">"Citroen"</span> },</li>
<li> { 5, <span style="color: #a31515;">"Toyota"</span> }</li>
<li style="background: #f3f3f3;"> };</li>
<li> query = query.ToLower();</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">var</span> result = data.Where(c => c.Value.ToLower().StartsWith(query)).Select(c => <span style="color: blue;">new</span> { Value = c.Key, Label = c.Value });</li>
<li> <span style="color: blue;">return</span> <span style="color: blue;">this</span>.Json(result, <span style="color: #2b91af;">JsonRequestBehavior</span>.AllowGet);</li>
<li style="background: #f3f3f3;">}</li>
<li> </li>
<li style="background: #f3f3f3;"><span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span></li>
<li><span style="color: grey;">///</span><span style="color: green;"> Autocomplete culture by term.</span></li>
<li style="background: #f3f3f3;"><span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span></li>
<li><span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><param name="query"></span><span style="color: green;">Term to search.</span><span style="color: grey;"></param></span></li>
<li style="background: #f3f3f3;"><span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><returns></span><span style="color: green;">Json with cultures.</span><span style="color: grey;"></returns></span></li>
<li>[<span style="color: #2b91af;">HttpGet</span>]</li>
<li style="background: #f3f3f3;"><span style="color: blue;">public</span> <span style="color: #2b91af;">JsonResult</span> AutocompleteCulture(<span style="color: blue;">string</span> query)</li>
<li>{</li>
<li style="background: #f3f3f3;"> query = query.ToLower().Trim();</li>
<li> <span style="color: blue;">var</span> result = <span style="color: #2b91af;">CultureInfo</span>.GetCultures(<span style="color: #2b91af;">CultureTypes</span>.SpecificCultures)</li>
<li style="background: #f3f3f3;"> .Where(c => c.DisplayName.ToLower().StartsWith(query))</li>
<li> .Select(c => <span style="color: blue;">new</span> { Value = c.LCID, Label = c.DisplayName });</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: blue;">return</span> <span style="color: blue;">this</span>.Json(result, <span style="color: #2b91af;">JsonRequestBehavior</span>.AllowGet);</li>
<li style="background: #f3f3f3;">}</li>
</ol>
</div>
</div>
<br />
3) Add our auto-complete extension function to the view and provide required parameters:<br />
<br />
<ul>
<li>Model property indicated by the expression</li>
<li>Controller function generated by <a href="http://msdn.microsoft.com/en-us/library/system.web.mvc.urlhelper.action(v=vs.108).aspx" target="_blank">Action</a>.</li>
</ul>
<br />
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="6" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li> </li>
<li style="background: #f3f3f3;"><span style="background: #ffff00;">@</span><span style="color: #2b91af;">Styles</span>.Render(<span style="color: #a31515;">"~/Content/themes/base/css"</span>)</li>
<li><span style="background: #ffff00;">@</span><span style="color: blue;">using</span> (Html.BeginForm(<span style="color: #a31515;">"Manage"</span>, <span style="color: #a31515;">"Admin"</span>))</li>
<li style="background: #f3f3f3;">{</li>
<li> <span style="color: blue;"><</span><span style="color: maroon;">h2</span><span style="color: blue;">></span></li>
<li style="background: #f3f3f3;"> Manage<span style="color: blue;"></</span><span style="color: maroon;">h2</span><span style="color: blue;">></span></li>
<li> <span style="color: blue;"><</span><span style="color: maroon;">span</span><span style="color: blue;">></span>Car brand:<span style="color: blue;"></</span><span style="color: maroon;">span</span><span style="color: blue;">></span> <span style="background: #ffff00;">@</span>Html.AutocompleteFor(c => c.SelectedCarId, Url.Action(<span style="color: #a31515;">"AutocompleteCars"</span>, <span style="color: #a31515;">"Admin"</span>))</li>
<li style="background: #f3f3f3;"> <span style="color: blue;"><</span><span style="color: maroon;">br</span> <span style="color: blue;">/></span></li>
<li> <span style="color: blue;"><</span><span style="color: maroon;">span</span><span style="color: blue;">></span>Globalization name:<span style="color: blue;"></</span><span style="color: maroon;">span</span><span style="color: blue;">></span><span style="background: #ffff00;">@</span>Html.AutocompleteFor(c => c.SelectedCultureCode, Url.Action(<span style="color: #a31515;">"AutocompleteCulture"</span>, <span style="color: #a31515;">"Admin"</span>), <span style="color: blue;">true</span>, <span style="color: #a31515;">"Start typing culture name...."</span>)</li>
<li style="background: #f3f3f3;"> <span style="color: blue;"><</span><span style="color: maroon;">br</span> <span style="color: blue;">/></span></li>
<li> <span style="color: blue;"><</span><span style="color: maroon;">input</span> <span style="color: red;">type</span><span style="color: blue;">="submit"</span> <span style="color: red;">value</span><span style="color: blue;">="Submit"</span> <span style="color: blue;">/></span></li>
<li style="background: #f3f3f3;">}</li>
</ol>
</div>
</div>
<br />
4) Run the solution and go to the http://localhost:port/Admin/Manage and feel free to test.<br />
<br />
<b>Source code is available <a href="http://dzapart.com.pl/BlogFiles/Autocomplete.zip" target="_blank">here</a>.</b><br />
<br />
Enjoy<br />
<br />
<br />Damian Zaparthttp://www.blogger.com/profile/17026397366973677672noreply@blogger.comDublin, Co. Dublin, Ireland53.3498053 -6.260309699999993453.0463208 -6.9057566999999933 53.6532898 -5.6148626999999935tag:blogger.com,1999:blog-8522517990291142303.post-64395375383162360982013-01-13T13:48:00.004+00:002013-01-13T13:48:39.988+00:00Custom configuration in Web.configAlmost all projects have come configuration which is mostly unique and absolutely custom. That configuration allow to customize some application behaviors, settings and switching some parts of implementation. In Microsoft .NET Framework configuration can be stored in two types of files:<br />
<br />
<ul>
<li><b>*.config</b> - XML based file which differ depending on project type. In web application such ASP.NET or WCF we working with <b>Web.config</b> file and in desktop application use <b>App.config</b>.</li>
<li><b>*.<a href="http://msdn.microsoft.com/en-us/library/aa730869(v=vs.80).aspx" target="_blank">setting </a></b>- deprecated type of file which allow to store custom settings in XML based, strongly typed file. </li>
</ul>
<div>
In this post I focus on Web.config file and demonstrate how to create custom section for this type of file. </div>
<div>
At the beginning we need some basic configuration file which is easy to get one because after we created new ASP.NET project from a template we already should have one. Simplified version on Web.config looks like as resented below.</div>
<div>
<br />
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="1" style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px;">
<li><span style="color: blue;"><?</span><span style="color: #a31515;">xml</span><span style="color: blue;"> </span><span style="color: red;">version</span><span style="color: blue;">=</span>"<span style="color: blue;">1.0</span>"<span style="color: blue;">?></span></li>
<li style="background: #f3f3f3;"><span style="color: blue;"><</span><span style="color: #a31515;">configuration</span><span style="color: blue;">></span></li>
<li> <span style="color: blue;"><</span><span style="color: #a31515;">connectionStrings</span><span style="color: blue;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: blue;"></</span><span style="color: #a31515;">connectionStrings</span><span style="color: blue;">></span></li>
<li> <span style="color: blue;"><</span><span style="color: #a31515;">system.web</span><span style="color: blue;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: blue;"><</span><span style="color: #a31515;">compilation</span><span style="color: blue;"> </span><span style="color: red;">debug</span><span style="color: blue;">=</span>"<span style="color: blue;">true</span>"<span style="color: blue;"> </span><span style="color: red;">targetFramework</span><span style="color: blue;">=</span>"<span style="color: blue;">4.0</span>"<span style="color: blue;"> /></span></li>
<li> <span style="color: blue;"></</span><span style="color: #a31515;">system.web</span><span style="color: blue;">></span></li>
<li style="background: #f3f3f3;"><span style="color: blue;"></</span><span style="color: #a31515;">configuration</span><span style="color: blue;">></span></li>
</ol>
</div>
</div>
<br /></div>
<div>
On code snippet we can see some initial XML tags including XML declaration (line 1) and <b>configuration </b>tag which is a root node. Because meaning of <b>connectionString </b>and <b>compilation </b>node is quite obvious I not going to focus about its and if you want you can read more about its <a href="http://go.microsoft.com/fwlink/?LinkId=169433" target="_blank">here</a>. Additionally I want to notice that many developers have very bad habit and put custom configuration settings in <b>appSettings </b>section in inside <b>configuration </b>section. I understand that in many project there are very short deadline but such solution is not correct and also is not consistent with good practices. Because developers put all custom settings in a <b><a href="http://msdn.microsoft.com/en-us/library/system.collections.specialized.namevaluecollection.aspx" target="_blank">NameValueCollection </a></b>type there is no strongly type definition for each single setting and this may cause problem and its very hard to maintenance. As I mentioned before such approach does not guarantee that type of value stored in setting will be correct that is why additional implementation of type checking and handling exceptions is required in this case.<br />
<br />
<b><span style="color: red;">BAD CODE. Do not use.</span></b><br />
<div style="border: 1px solid rgb(0, 0, 128); font-family: 'Courier New', Courier, monospace; font-size: 10pt;">
<div style="background-color: navy; background-position: initial initial; background-repeat: initial initial; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background-color: #dddddd; max-height: 300px; overflow: auto;">
<ol start="1" style="background-color: white; margin: 0px 0px 0px 2em; padding: 0px 0px 0px 5px;">
<li style="color: black;"><span style="color: blue;"><?</span><span style="color: #a31515;">xml</span><span style="color: blue;"> </span><span style="color: red;">version</span><span style="color: blue;">=</span>"<span style="color: blue;">1.0</span>"<span style="color: blue;">?></span></li>
<li style="background-color: #f3f3f3; background-position: initial initial; background-repeat: initial initial; color: black;"><span style="color: blue;"><</span><span style="color: #a31515;">configuration</span><span style="color: blue;">></span></li>
<li style="color: black;"> <span style="color: blue;"><</span><span style="color: #a31515;">appSettings</span><span style="color: blue;">></span></li>
<li style="background-color: #f3f3f3;"> <span style="color: blue;"><</span><span style="color: #a31515;">add</span><span style="color: blue;"> </span><span style="color: red;">key</span><span style="color: blue;">=</span>"<span style="color: blue;">some_int</span>"<span style="color: blue;"> </span><span style="color: red;">value</span><span style="color: blue;">=</span>"<span style="color: blue;">1</span>"<span style="color: blue;">/></span></li>
<li style="color: black;"> <span style="color: blue;"></</span><span style="color: #a31515;">appSettings</span><span style="color: blue;">></span></li>
<li style="background-color: #f3f3f3; background-position: initial initial; background-repeat: initial initial; color: black;"><span style="color: blue;"></</span><span style="color: #a31515;">configuration</span><span style="color: blue;">></span></li>
</ol>
</div>
</div>
<b><span style="color: red;">BAD CODE. Do not use.</span></b><br />
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="12" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li><span style="color: blue;">protected</span> <span style="color: blue;">void</span> Page_Load(<span style="color: blue;">object</span> sender, <span style="color: #2b91af;">EventArgs</span> e)</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">int</span> i = <span style="color: #2b91af;">Convert</span>.ToInt32(System.Configuration.<span style="color: #2b91af;">ConfigurationManager</span>.AppSettings[<span style="color: #a31515;">"some_int"</span>]);</li>
<li style="background: #f3f3f3;"> }</li>
</ol>
</div>
</div>
<br />
Now it`s time for a good news. We can write our own custom sections on Web.config which is strongly typed, contains default values and are required or not. Let's start with creating a new DLL project named <b>Common </b>(picture 1.) and (<b>which is very important</b>) add reference to <b>System.Configuration</b> namespace. Also remember to add reference to a new project to our ASP.NET application.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNX3RgijUdNb2jkTAtJXSBlFuhQCMGIzqW-HdODJM-lkZup_8Yvx1v4WtQ2xRTBKGhyphenhyphenRD9WloFynn2jxdVEy2rgsbTrTe7mPBQUmEKJYUZgvZODu_5FRPooBLthi01Mgtf_Boo1xLCIwD8/s1600/Solution.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNX3RgijUdNb2jkTAtJXSBlFuhQCMGIzqW-HdODJM-lkZup_8Yvx1v4WtQ2xRTBKGhyphenhyphenRD9WloFynn2jxdVEy2rgsbTrTe7mPBQUmEKJYUZgvZODu_5FRPooBLthi01Mgtf_Boo1xLCIwD8/s640/Solution.png" width="418" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Picture 1. Solution overview.</td></tr>
</tbody></table>
Simply solution architecture is done already so now its time for some implementation. Let`s assume that we want to create custom setting for email sending. We need to introduce some basic configuration parameters for SMTP server as well as some default email provider such .NET <a href="http://msdn.microsoft.com/en-us/library/system.net.mail.aspx" target="_blank">SMTPClient </a>class. First of all we create class for accessing information about email general settings such: mechanism enabled, default timeout, etc.<br />
To make such implementation we must derive from <a href="http://msdn.microsoft.com/en-us/library/system.configuration.configurationelement.aspx" target="_blank">ConfigurationElement </a>class.<br />
<br />
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="9" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">EmailConfiguration</span> : <span style="color: #2b91af;">ConfigurationElement</span></li>
<li style="background: #f3f3f3;">{</li>
<li> [<span style="color: #2b91af;">ConfigurationProperty</span>(<span style="color: #a31515;">"emailMessageEnabled"</span>), <span style="color: #2b91af;">SettingsDescription</span>(<span style="color: #a31515;">"Enabled of sending sended emails."</span>)]</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">public</span> <span style="color: blue;">bool</span> EmailMessageEnabled</li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">get</span> { <span style="color: blue;">return</span> (<span style="color: blue;">bool</span>)<span style="color: blue;">this</span>[<span style="color: #a31515;">"emailMessageEnabled"</span>]; }</li>
<li> }</li>
<li style="background: #f3f3f3;"> </li>
<li> [<span style="color: #2b91af;">ConfigurationProperty</span>(<span style="color: #a31515;">"timeOut"</span>, DefaultValue = 60), <span style="color: #2b91af;">SettingsDescription</span>(<span style="color: #a31515;">"Default value of timeout."</span>)]</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">public</span> <span style="color: blue;">int</span> TimeOut</li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">get</span> { <span style="color: blue;">return</span> (<span style="color: blue;">int</span>)<span style="color: blue;">this</span>[<span style="color: #a31515;">"timeOut"</span>]; }</li>
<li> }</li>
<li style="background: #f3f3f3;"> </li>
<li> [<span style="color: #2b91af;">ConfigurationProperty</span>(<span style="color: #a31515;">"provider"</span>, DefaultValue = <span style="color: #a31515;">"Custom"</span>), <span style="color: #2b91af;">SettingsDescription</span>(<span style="color: #a31515;">"Mechanism for email sending."</span>)]</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">public</span> <span style="color: blue;">string</span> DefaultProvider</li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">get</span> { <span style="color: blue;">return</span> (<span style="color: blue;">string</span>)<span style="color: blue;">this</span>[<span style="color: #a31515;">"provider"</span>]; }</li>
<li> }</li>
<li style="background: #f3f3f3;"> </li>
<li>}</li>
</ol>
</div>
</div>
<br />
As you can see on the code snippet above I added some custom properties and all of them is strongly typed. Also all have <a href="http://msdn.microsoft.com/en-us/library/system.configuration.configurationproperty.aspx" target="_blank">ConfigurationProperty</a> attribute which allow to set following properties for each setting:<br />
<br />
<ul>
<li><b>Name</b>: name of configuration element in Web.config</li>
<li><b>DefaultValue</b>: determine default value as object with null as default</li>
<li><b>IsRequired</b>: section is required or can me omitted</li>
<li><b>IsDefaultCollection</b>: determine property as default collection of settings (this value is ignored if the property is not a collection)</li>
</ul>
<div>
Inside each properties I`m accessing to the configuration attribute and convert it to coreesponding type. In Web.config this class is represented as following XML.</div>
<div>
<br />
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="4" style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px;">
<li><span style="color: blue;"><</span><span style="color: #a31515;">mailConfiguration</span><span style="color: blue;"> </span><span style="color: red;">emailMessageEnabled</span><span style="color: blue;">=</span>"<span style="color: blue;">true</span>" <span style="color: blue;"></span><span style="color: red;">timeOut</span><span style="color: blue;">=</span>"<span style="color: blue;">1000</span>"<span style="color: blue;"> </span><span style="color: red;">provider</span><span style="color: blue;">=</span>"<span style="color: blue;">Custom</span>"<span style="color: blue;">></</span><span style="color: #a31515;">mailConfiguration</span><span style="color: blue;">></span></li>
</ol>
</div>
</div>
<br />
This no everything because still there is no configuration for custom email sender mechanism. To make such implementation I add new class <b>CustomEmailConfiguration</b> which is defined as presented below.<br />
<br />
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="9" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">CustomEmailConfiguration</span> : <span style="color: #2b91af;">ConfigurationElement</span></li>
<li style="background: #f3f3f3;"> {</li>
<li> [<span style="color: #2b91af;">ConfigurationProperty</span>(<span style="color: #a31515;">"customLogin"</span>), <span style="color: #2b91af;">SettingsDescription</span>(<span style="color: #a31515;">"Login to mail server."</span>)]</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">public</span> <span style="color: blue;">string</span> Login { <span style="color: blue;">get</span> { <span style="color: blue;">return</span> (<span style="color: blue;">string</span>)<span style="color: blue;">this</span>[<span style="color: #a31515;">"customLogin"</span>]; } }</li>
<li> </li>
<li style="background: #f3f3f3;"> [<span style="color: #2b91af;">ConfigurationProperty</span>(<span style="color: #a31515;">"customPassword"</span>), <span style="color: #2b91af;">SettingsDescription</span>(<span style="color: #a31515;">"Password to mail server."</span>)]</li>
<li> <span style="color: blue;">public</span> <span style="color: blue;">string</span> Password { <span style="color: blue;">get</span> { <span style="color: blue;">return</span> (<span style="color: blue;">string</span>)<span style="color: blue;">this</span>[<span style="color: #a31515;">"customPassword"</span>]; } }</li>
<li style="background: #f3f3f3;"> </li>
<li> [<span style="color: #2b91af;">ConfigurationProperty</span>(<span style="color: #a31515;">"customHost"</span>), <span style="color: #2b91af;">SettingsDescription</span>(<span style="color: #a31515;">"Address of mail server."</span>)]</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">public</span> <span style="color: blue;">string</span> Url { <span style="color: blue;">get</span> { <span style="color: blue;">return</span> (<span style="color: blue;">string</span>)<span style="color: blue;">this</span>[<span style="color: #a31515;">"customHost"</span>]; } }</li>
<li> </li>
<li style="background: #f3f3f3;"> [<span style="color: #2b91af;">ConfigurationProperty</span>(<span style="color: #a31515;">"customSenderEmail"</span>), <span style="color: #2b91af;">SettingsDescription</span>(<span style="color: #a31515;">"Email of sender."</span>)]</li>
<li> <span style="color: blue;">public</span> <span style="color: blue;">string</span> CustomSenderEmail { <span style="color: blue;">get</span> { <span style="color: blue;">return</span> (<span style="color: blue;">string</span>)<span style="color: blue;">this</span>[<span style="color: #a31515;">"customSenderEmail"</span>]; } }</li>
<li style="background: #f3f3f3;"> }</li>
</ol>
</div>
</div>
<br />
Is stores information about login, password and so on. So now all I need to to is put it inside my mail configuration node (see below) and because I neested this part iniside other, additionally I should add new property to the <b>EmailConfiguration </b> class.<br />
<br />
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="4" style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px;">
<li><span style="color: blue;"> <</span><span style="color: #a31515;">mailConfiguration</span><span style="color: blue;"> </span><span style="color: red;">emailMessageEnabled</span><span style="color: blue;">=</span>"<span style="color: blue;">true</span>"<span style="color: blue;"></span><span style="color: red;">timeOut</span><span style="color: blue;">=</span>"<span style="color: blue;">1000</span>"<span style="color: blue;"> </span><span style="color: red;">provider</span><span style="color: blue;">=</span>"<span style="color: blue;">Custom</span>"<span style="color: blue;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: blue;"><</span><span style="color: #a31515;">Custom</span><span style="color: blue;"> </span><span style="color: red;">customLogin</span><span style="color: blue;">=</span>"<span style="color: blue;">damian.zapart</span>"<span style="color: blue;"> </span><span style="color: red;">customPassword</span><span style="color: blue;">=</span>"<span style="color: blue;">blogger123</span>"<span style="color: blue;"> </span><span style="color: red;">customSenderEmail</span><span style="color: blue;">=</span>"<span style="color: blue;">damian.zapart@gmail.com</span>"<span style="color: blue;"> </span><span style="color: red;">customHost</span><span style="color: blue;">=</span>"<span style="color: blue;">mail.google.pl</span>"<span style="color: blue;">></span></li>
<li> <span style="color: blue;"></</span><span style="color: #a31515;">Custom</span><span style="color: blue;">></span></li>
<li style="background: #f3f3f3;"><span style="color: blue;"></</span><span style="color: #a31515;">mailConfiguration</span><span style="color: blue;">></span></li>
</ol>
</div>
</div>
<br />
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="29" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li>[<span style="color: #2b91af;">ConfigurationProperty</span>(<span style="color: #a31515;">"Custom"</span>, IsRequired = <span style="color: blue;">false</span>), <span style="color: #2b91af;">SettingsDescription</span>(<span style="color: #a31515;">"Custom email sender configuration."</span>)]</li>
<li style="background: #f3f3f3;"><span style="color: blue;">public</span> <span style="color: #2b91af;">CustomEmailConfiguration</span> CustomConfiguration { <span style="color: blue;">get</span> { <span style="color: blue;">return</span> (<span style="color: #2b91af;">CustomEmailConfiguration</span>)<span style="color: blue;">this</span>[<span style="color: #a31515;">"Custom"</span>]; } }</li>
</ol>
</div>
</div>
<br />
My new, custom configuration section for emails is ready so now it is time to start using it. First of all I want to locate it inside more generic section just to put all my further configuration elements in one section. To do that I need to create one more class named <b>RootSection </b>presented below. Thank such approach in the future if I will need to add an other custom configuration element I just put it as new property of <b>RootSection </b>section with new type.<br />
<br />
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="9" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">RootSection</span> : <span style="color: #2b91af;">ConfigurationSection</span></li>
<li style="background: #f3f3f3;"> {</li>
<li> [<span style="color: #2b91af;">ConfigurationProperty</span>(<span style="color: #a31515;">"mailConfiguration"</span>), <span style="color: #2b91af;">SettingsDescription</span>(<span style="color: #a31515;">"Email configuration"</span>)]</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">public</span> <span style="color: #2b91af;">EmailConfiguration</span> EmailConfiguration</li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">get</span> { <span style="color: blue;">return</span> (<span style="color: #2b91af;">EmailConfiguration</span>)<span style="color: blue;">this</span>[<span style="color: #a31515;">"mailConfiguration"</span>]; }</li>
<li> }</li>
<li style="background: #f3f3f3;"> }</li>
</ol>
</div>
</div>
<br />
Whole solution is almost ready. We have created general email settings in <b>EmailConfiguration</b>, define <b>CustomEmailConfiguration </b>inside it and also create <b>RootSection </b>which will store all our custom configuration settings. Now it`s time to create wrapper class for accessing its. Presented below <b>SystemConfiguration </b>class is a classic example of the singleton design pattern. In static properties I refreshing my custom section by using <a href="http://msdn.microsoft.com/en-us/library/system.configuration.configurationmanager.aspx" target="_blank">ConfigurationManager</a> .NET Framework class and than get this section as type of my <b>RootSection</b>. Due to my <b>RootSection </b>contains property of type <b>EmailConfiguration </b>I can simply navigate to it and all it properties.<br />
<br />
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="9" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li> <span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">SystemConfiguration</span></li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">private</span> <span style="color: blue;">static</span> <span style="color: #2b91af;">RootSection</span> rootSection;</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">private</span> <span style="color: blue;">static</span> <span style="color: #2b91af;">RootSection</span> RootSection</li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">get</span></li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">if</span> (rootSection == <span style="color: blue;">null</span>)</li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: #2b91af;">ConfigurationManager</span>.RefreshSection(<span style="color: #a31515;">"customConfiguration"</span>);</li>
<li> <span style="color: blue;">object</span> o = <span style="color: #2b91af;">ConfigurationManager</span>.GetSection(<span style="color: #a31515;">"customConfiguration"</span>);</li>
<li style="background: #f3f3f3;"> rootSection = (<span style="color: #2b91af;">RootSection</span>)o;</li>
<li> }</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">return</span> rootSection;</li>
<li> }</li>
<li style="background: #f3f3f3;"> }</li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: blue;">public</span> <span style="color: blue;">static</span> <span style="color: #2b91af;">EmailConfiguration</span> EmailConfiguration</li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">get</span></li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">return</span> RootSection.EmailConfiguration;</li>
<li> }</li>
<li style="background: #f3f3f3;"> }</li>
<li> }</li>
</ol>
</div>
</div>
<br />
For now, project compile well but we still can`t use our configuration because we not register our new section. Registering section is process of mapping XML node to .NET framework type. This is very easy and all I need to do is put three lines in Web.config (line 3,4 and 5).<br />
<br />
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li><span style="color: blue;"><?</span><span style="color: #a31515;">xml</span><span style="color: blue;"> </span><span style="color: red;">version</span><span style="color: blue;">=</span>"<span style="color: blue;">1.0</span>"<span style="color: blue;">?></span></li>
<li style="background: #f3f3f3;"><span style="color: blue;"><</span><span style="color: #a31515;">configuration</span><span style="color: blue;">></span></li>
<li> <span style="color: blue;"><</span><span style="color: #a31515;">configSections</span><span style="color: blue;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: blue;"><</span><span style="color: #a31515;">section</span><span style="color: blue;"> </span><span style="color: red;">name</span><span style="color: blue;">=</span>"<span style="color: blue;">systemConfiguration</span>"<span style="color: blue;"> </span><span style="color: red;">type</span><span style="color: blue;">=</span>"<span style="color: blue;">Common.RootSection, Common</span>"<span style="color: blue;"> /></span></li>
<li> <span style="color: blue;"></</span><span style="color: #a31515;">configSections</span><span style="color: blue;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: blue;"><</span><span style="color: #a31515;">systemConfiguration</span><span style="color: blue;">></span></li>
<li> <span style="color: blue;"> <</span><span style="color: #a31515;">mailConfiguration</span><span style="color: blue;"> </span><span style="color: red;">emailMessageEnabled</span><span style="color: blue;">=</span>"<span style="color: blue;">true</span>"<span style="color: blue;"></span><span style="color: red;">timeOut</span><span style="color: blue;">=</span>"<span style="color: blue;">1000</span>"<span style="color: blue;"> </span><span style="color: red;">provider</span><span style="color: blue;">=</span>"<span style="color: blue;">Custom</span>"<span style="color: blue;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: blue;"><</span><span style="color: #a31515;">Custom</span><span style="color: blue;"> </span><span style="color: red;">customLogin</span><span style="color: blue;">=</span>"<span style="color: blue;">damian.zapart</span>"<span style="color: blue;"> </span><span style="color: red;">customPassword</span><span style="color: blue;">=</span>"<span style="color: blue;">blogger123</span>"<span style="color: blue;"> </span><span style="color: red;">customSenderEmail</span><span style="color: blue;">=</span>"<span style="color: blue;">damian.zapart@gmail.com</span>"<span style="color: blue;"> </span><span style="color: red;">customHost</span><span style="color: blue;">=</span>"<span style="color: blue;">mail.google.pl</span>"<span style="color: blue;">></span></li>
<li> <span style="color: blue;"></</span><span style="color: #a31515;">Custom</span><span style="color: blue;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: blue;"></</span><span style="color: #a31515;">mailConfiguration</span><span style="color: blue;">></span></li>
<li> <span style="color: blue;"></</span><span style="color: #a31515;">systemConfiguration</span><span style="color: blue;">></span></li>
<li style="background: #f3f3f3;"><span style="color: blue;"></</span><span style="color: #a31515;">configuration</span><span style="color: blue;">></span></li>
</ol>
</div>
</div>
<br />
It done. Now we are able to use it.<br />
<br />
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="14" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li><span style="color: blue;">if</span> (Common.<span style="color: #2b91af;">SystemConfiguration</span>.EmailConfiguration.EmailMessageEnabled)</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">string</span> senderEmail = Common.<span style="color: #2b91af;">SystemConfiguration</span>.EmailConfiguration.CustomConfiguration.CustomSenderEmail;</li>
<li style="background: #f3f3f3;"> <span style="color: green;">//TODO: some logic for sending emails.</span></li>
<li> }</li>
</ol>
</div>
</div>
<br />
<div style="text-align: center;">
<span style="background-color: white; color: #222222; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: medium; line-height: 25px; text-align: center;">Full projects source code is free available </span><a href="https://docs.google.com/file/d/0Bxd_tNkfJQoLMExwcHdMTnUzdFk/edit" style="background-color: white; color: #888888; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: large; line-height: 25px; text-align: center; text-decoration: initial;" target="_blank">here</a><span style="background-color: white; color: #222222; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: medium; line-height: 25px; text-align: center;">.</span></div>
<div style="text-align: center;">
<br /></div>
Thank you<br />
<br /></div>
</div>
Damian Zaparthttp://www.blogger.com/profile/17026397366973677672noreply@blogger.comtag:blogger.com,1999:blog-8522517990291142303.post-2555588584059104342013-01-12T23:55:00.001+00:002013-01-12T23:55:16.407+00:00Compression in BAT by using 7zTo compress direcotry or files in batch program all You need to do is to install <a href="http://www.7-zip.org/">7z </a>opensource and create simple 'task.bat' file with only few line of code:<br />
<br />
<br />
@echo Start processing<br />
"C:\Program Files\7-Zip"\7zg.exe a C:\Backup\important_data_%date:~0,4%%date:~5,2%%date:~8,2%.7z C:\inetpub\wwwroot\BestWebsite -t7z -mx9 -m0=LZMA -pMYPassword<br />
@echo End<br />
PAUSE<br />
<br />
What we do here is:<br />
1) Run 7zg.exe program<br />
2) Create target file important_data_(current data).7z in C:\Backup\ directory<br />
3) Indicate file or folder to compress in this ex we compress 'BestWebsite' directory<br />
4) Set compression parameter in this example we have-t7z -mx9 -m0=LZMA<br />
5) Optionally set a password to compressed document<br />
<br />
Thank you<br />
<br />Damian Zaparthttp://www.blogger.com/profile/17026397366973677672noreply@blogger.comtag:blogger.com,1999:blog-8522517990291142303.post-25331256648358415652013-01-12T23:52:00.001+00:002013-01-12T23:52:12.609+00:00WCF PaginationIn many of my projects including last one I need to user N-Tier architecture for my application. This is very good approach because you can centralize your business logic and have many type of clients (WWW, mobile devices) thanks WCF and REST technology. The other thing is that most of business solutions displays some data in tabular format knows as grids and grid has always one problem: number of records increasing in time. So we need to ask ourselves do we really need to display all the data together to user on one page? Of course not! Such approach is incorrect and not against best practices because its extends the time of response and send a much more data to client. To deal with that problem many developers uses pagination mechanism which is part of ASP.NET (ex. asp:Grid) but such approach is not correct when working with N-Tier architecture and its not supported in any mobile devices.<br />
<br />
In my approach I wish to implement all my business logic and services by using <a href="http://msdn.microsoft.com/en-us/magazine/cc163481.aspx" target="_blank">Service Factory</a> design pattern for WCF. Because I going to focus only at the pagination mechanism there is no need to add additional classes for accessing an database that is why I going to use mocking to create some data except.<br />
<br />
At the beginning take a look at solution high level architecture (picture 1.). The solution contains two separated solution folder. <b>Tests </b>folders contains only one console application project for web service testing purposes. Folder WCF contains following projects:<br />
<br />
<ul>
<li><b>Common: </b>dll with implementation of public interfaces and classes shared across whole solution.</li>
<li><b>Contracts</b>: dll with definitions for classes uses as parameters for services methods. According best practices all service methods take 0 or only one parameter(which always derive from <b>BaseRequest </b>class) and returns type of response (which always derive from <b>BaseResponse </b>class).</li>
<li><b>DataTransferObjects</b>: dll with types uses in communication in requests and responses. These types implements interfaces from namespaces Common.DTO and database entities also should implements its.</li>
<li><b>Namespaces</b>: dll with constans namespaces for services, services contracts, service interfaces and so on.</li>
<li><b>ServiceImplementation</b>: dll, core library with implementation of business logic for WCF services where classes implements service contracts.</li>
<li><b>ServiceInterfaces</b>: dll, services contracts.</li>
<li><b>Services</b>: WCF application, stores .svc files and configuration file (Web.config)</li>
</ul>
<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2pMk_gwpYh6JF2aNEw6Ge_HDwx4zf3Pxn1LCTIUIvy8uZyUrjjKICOuI1CLRVyQHmV_kGyygNP7dWBb-sj2R0dfjEzL5Me5_E4f4aSWXINgyC3nltfGO5UTt_r7ywOnR1FVLqtCCNuayP/s1600/solution_high_level.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2pMk_gwpYh6JF2aNEw6Ge_HDwx4zf3Pxn1LCTIUIvy8uZyUrjjKICOuI1CLRVyQHmV_kGyygNP7dWBb-sj2R0dfjEzL5Me5_E4f4aSWXINgyC3nltfGO5UTt_r7ywOnR1FVLqtCCNuayP/s400/solution_high_level.png" width="398" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Picture 1. solution high level architecture.</td></tr>
</tbody></table>
Now when we know all solution we can focus on details of pagination. For presentation purpose I created one service called <b>UserService </b>with only one method <b>GetUsers</b>. This method returns list of users which will be paginated according to request parameters.<br />
<br />
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="13" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li> [<span style="color: #2b91af;">ServiceContract</span>(Namespace = <span style="color: #2b91af;">ConstNamespaces</span>.ServiceRoot, SessionMode = <span style="color: #2b91af;">SessionMode</span>.Allowed)]</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">public</span> <span style="color: blue;">interface</span> <span style="color: #2b91af;">IUserService</span></li>
<li> {</li>
<li style="background: #f3f3f3;"> [<span style="color: #2b91af;">OperationContract</span>]</li>
<li> <span style="color: #2b91af;">GetUsersResponse</span> GetUsers(<span style="color: #2b91af;">GetUsersRequest</span> request);</li>
<li style="background: #f3f3f3;"> }</li>
</ol>
</div>
</div>
<br />
To enable pagination for list some additional implementation had to be introduced (picture 2.). The most important class for that is generic<b> ListRequest<T></b> which implements a generic interface <b>IRaginationRequest<T></b>. Those interface has only two int null-able properties which determine number of page to display and number of result per page - by default pagination return first page with maximum 20 results. Because we I use here genetic types in <b>GetUserRequest </b>declaration I simply can declare type of T as <b>User </b>type which is my DTO object.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEx60QZJ167uCUFG-b-k57qR6DqwsDqpz2_5IsDR8DFV5tl1DcdhsEEKzMJjYtAms5rufCdFNSXP2P2yoAaWQKH99zQRE_DH012SUUavLhoRGpQSz9MOJu2O7BQLv0t0EOm1Llj4bmJ-Rn/s1600/Requests.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="309" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEx60QZJ167uCUFG-b-k57qR6DqwsDqpz2_5IsDR8DFV5tl1DcdhsEEKzMJjYtAms5rufCdFNSXP2P2yoAaWQKH99zQRE_DH012SUUavLhoRGpQSz9MOJu2O7BQLv0t0EOm1Llj4bmJ-Rn/s640/Requests.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Picture 2. Structure of a pagination request.<br />
<br />
<br /></td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeUlVy6tlloG11oYgXz9xX1MWJIqKORAEYBnEiEhpRO4Sr_o_webkZx4gwlhQdyUuZY_J1rX2LvKJo5A1jAZpZce9xhYfOl2jvWus4z1ouRiETZusJPvpu_lIpf0-v73PvAdSErn3Za29s/s1600/Response.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="235" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeUlVy6tlloG11oYgXz9xX1MWJIqKORAEYBnEiEhpRO4Sr_o_webkZx4gwlhQdyUuZY_J1rX2LvKJo5A1jAZpZce9xhYfOl2jvWus4z1ouRiETZusJPvpu_lIpf0-v73PvAdSErn3Za29s/s640/Response.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 13px;">Picture 3. Structure for a pagination response.</td></tr>
</tbody></table>
<br />
Now its time to implement service logic for returning paginated list of users. As I mentioned before in this post, I using mocking except of database that is why I create 100 users in for loop with some test properties. After filling the list it`s time for apply pagination mechanism on it. For pagination I`ve created extension generic method called <b>AsPagination </b>which extend <b>IEnumerable </b>interface of T type and takes one generic parameter of type <b>IPaginationRequest</b>. This is quite obvious because in the request (which implements that interface) we pass all required data for pagination. Because pagination function returns value of generic type <b>IPagination </b>and there is no possibility to pass interface by WCF it need to be converted to class type and this explains <b>GetUserResponse </b>structure (Picture 3.).<br />
<br />
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="14" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li>[<span style="color: #2b91af;">AspNetCompatibilityRequirements</span>(RequirementsMode = <span style="color: #2b91af;">AspNetCompatibilityRequirementsMode</span>.Allowed)]</li>
<li style="background: #f3f3f3;"> [<span style="color: #2b91af;">ServiceBehavior</span>(InstanceContextMode = <span style="color: #2b91af;">InstanceContextMode</span>.PerSession)]</li>
<li> <span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">UserService</span> : <span style="color: #2b91af;">IUserService</span></li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">public</span> <span style="color: #2b91af;">GetUsersResponse</span> GetUsers(<span style="color: #2b91af;">GetUsersRequest</span> request)</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: #2b91af;">List</span><<span style="color: #2b91af;">User</span>> users = <span style="color: blue;">new</span> <span style="color: #2b91af;">List</span><<span style="color: #2b91af;">User</span>>();</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: green;">//Mocking response from DB. </span></li>
<li style="background: #f3f3f3;"> <span style="color: blue;">for</span> (<span style="color: blue;">int</span> i = 0; i < 100; i++)</li>
<li> users.Add(<span style="color: blue;">new</span> <span style="color: #2b91af;">User</span>()</li>
<li style="background: #f3f3f3;"> {</li>
<li> Id = <span style="color: #2b91af;">Guid</span>.NewGuid(),</li>
<li style="background: #f3f3f3;"> Email = <span style="color: blue;">string</span>.Format(<span style="color: #a31515;">"test{0}.test.com"</span>, i),</li>
<li> FirstName = <span style="color: blue;">string</span>.Format(<span style="color: #a31515;">"Name_For_User_{0}"</span>, i),</li>
<li style="background: #f3f3f3;"> LastName = <span style="color: blue;">string</span>.Format(<span style="color: #a31515;">"Last_Name_For_User_{0}"</span>, i),</li>
<li> });</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: blue;">var</span> result = users.AsPagination<<span style="color: #2b91af;">User</span>>(request);</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">return</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">GetUsersResponse</span>() { ResultList = <span style="color: blue;">new</span> <span style="color: #2b91af;">Pagination</span><<span style="color: #2b91af;">User</span>>(result) };</li>
<li> }</li>
<li style="background: #f3f3f3;"> }</li>
</ol>
</div>
</div>
<br />
To fully understand pagination mechanism you must be familiar with IQueryable interface and deferred execution on queries because both are used in the implementation. Pagination mechanism is <b>optimized </b>which means that you get only records which you really requested. For example, if you want to see 10 record on 5th page you need get from database only 10 records. You can achieve this by using <a href="http://msdn.microsoft.com/en-us/library/bb357513.aspx" target="_blank">Skip </a>and <a href="http://msdn.microsoft.com/en-us/library/bb503062.aspx" target="_blank">Take</a> LINQ functions and know page size and number.If know both value of these variables you can simply use following LINQ query:<br />
<br />
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="128" style="background: #ffffff; margin: 0 0 0 3em; padding: 0 0 0 5px;">
<li>Query.Skip(numberToSkip).Take(PageSize);</li>
</ol>
</div>
</div>
<br />
<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_E_8xyEejg3KJgLalFwjxT31WhqlwAzfEkaGmGqyFkEgHOH-3NaX3WXPAr4cjkmWkuWVSBFq8nJUyKYEUqvnyAJBx_QuG03Kh58Jrv_7OPQj99EgAxe3kYlZC3Md5zy5EBXWW5trOF1oh/s1600/Pagination.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="602" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_E_8xyEejg3KJgLalFwjxT31WhqlwAzfEkaGmGqyFkEgHOH-3NaX3WXPAr4cjkmWkuWVSBFq8nJUyKYEUqvnyAJBx_QuG03Kh58Jrv_7OPQj99EgAxe3kYlZC3Md5zy5EBXWW5trOF1oh/s640/Pagination.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Picture 4. Pagination mechanism overview.</td></tr>
</tbody></table>
<div style="text-align: center;">
<span style="color: #990000;">At this stage there is no sorting and ordering in pagination list because it will be introduced in further post. </span></div>
<span style="font-size: large;"><br /></span>
<div style="text-align: center;">
<span style="font-size: large;">Full projects source code is free available <a href="https://docs.google.com/file/d/0Bxd_tNkfJQoLbWtXX3VUY3g5RFU/edit" target="_blank">here</a>.</span></div>
<span style="font-size: large;"><br /></span>
<span style="background-color: white; color: #222222; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18px;">Thank you.</span><br />
<span style="background-color: white; color: #222222; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18px;"><br /></span>
<span style="background-color: white; color: #222222; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18px;">Read more:</span><br />
<br />
<br />
<ul>
<li><span style="color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: x-small;"><span style="line-height: 18px;">IQueryable: <a href="http://msdn.microsoft.com/en-us/library/system.linq.iqueryable(v=vs.100).aspx">http://msdn.microsoft.com/en-us/library/system.linq.iqueryable(v=vs.100).aspx</a></span></span></li>
</ul>
<br />
<br />
<ul>
<li><span style="color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: x-small;">Deferred query execution: <a href="http://msdn.microsoft.com/en-us/library/bb738633(v=vs.100).aspx">http://msdn.microsoft.com/en-us/library/bb738633(v=vs.100).aspx</a></span></li>
</ul>
<br />
<br />
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: x-small;">WCF Service Factory: <a href="http://msdn.microsoft.com/en-us/magazine/cc163481.aspx">http://msdn.microsoft.com/en-us/magazine/cc163481.aspx</a></span></li>
</ul>
<br />
Damian Zaparthttp://www.blogger.com/profile/17026397366973677672noreply@blogger.comtag:blogger.com,1999:blog-8522517990291142303.post-72957095074424301032012-04-09T20:34:00.000+01:002017-08-27T15:14:59.178+01:00Full-Text Search with PDF in Microsoft SQL ServerLast week I get interesting task to develop. The task was to search input text in PDF file stored in database as FileStream. The task implementation took me some time so I decided to share it with other developers.<br />
<div>
<br /></div>
<div>
Here we are going to use SQL Server 2008 R2 (x64 Developers Edition), external driver from Adobe, Full-Text Search technology and FileStream technology.Because this sems a little bit comlicated let`s make this topic clear and do it step by step.</div>
<div>
<br /></div>
<div>
1) <b>Enable FileStream</b> - this part is pretty easy, just check wheter You already have enabled filestream on Your SQL Server instance - if no simply enable it as in the picture below.</div>
<div>
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgChdThHJuRwNZifKbNB2MCRlgmcBsEK8FBwW72lB4Qsuw49SCALxkc_57xyc-lKlFAIsHQB3gQ3WTd4Lx_CCgKuZ43ocJeOEF2OQHQKqx6o3DOqqcNXtvv_nzcEJuirXoqVrQNwCWGps-2/s1600/fs.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="265" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgChdThHJuRwNZifKbNB2MCRlgmcBsEK8FBwW72lB4Qsuw49SCALxkc_57xyc-lKlFAIsHQB3gQ3WTd4Lx_CCgKuZ43ocJeOEF2OQHQKqx6o3DOqqcNXtvv_nzcEJuirXoqVrQNwCWGps-2/s640/fs.png" width="640" /></a></td></tr>
<tr><td class="tr-caption">Picture 1. Enable filestream in SQL Server instance.</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div>
2) <b>Create SQL table to store files</b> - mainly ther will be PDF file stored but some others is also be allright. Out table DocumentFile will be created in dbo schema and contain one column primary key with default value as sequential GUID. Important this is out table contains FileStream_Id and FileSource columns which are required do FileStream. Additionaly don`t miss the Extension column because we going need it for Full-Text Search.</div>
<div>
<br /></div>
<div>
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li><span style="color: blue;">CREATE</span> <span style="color: blue;">TABLE</span> <span style="color: teal;">dbo</span><span style="color: grey;">.</span><span style="color: teal;">DocumentFiles</span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">(</span></li>
<li> <span style="color: teal;">DocumentId</span> <span style="color: blue;">uniqueidentifier</span> <span style="color: blue;">Primary</span> <span style="color: blue;">KEY</span> <span style="color: blue;">DEFAULT</span> <span style="color: magenta;">newsequentialid</span><span style="color: grey;">(),</span></li>
<li style="background: #f3f3f3;"> <span style="color: teal;">AddDate</span> <span style="color: blue;">datetime</span> <span style="color: grey;">NOT</span> <span style="color: grey;">NULL,</span></li>
<li> <span style="color: teal;">Name</span> <span style="color: blue;">nvarchar</span><span style="color: grey;">(</span>50<span style="color: grey;">)</span> <span style="color: grey;">NOT</span> <span style="color: grey;">NULL,</span></li>
<li style="background: #f3f3f3;"> <span style="color: teal;">Extension</span> <span style="color: blue;">nvarchar</span><span style="color: grey;">(</span>10<span style="color: grey;">)</span> <span style="color: grey;">NOT</span> <span style="color: grey;">NULL,</span></li>
<li> <span style="color: blue;">Description</span> <span style="color: blue;">nvarchar</span><span style="color: grey;">(</span>1000<span style="color: grey;">)</span> <span style="color: grey;">NULL,</span></li>
<li style="background: #f3f3f3;"> <span style="color: teal;">FileStream_Id</span> <span style="color: blue;">uniqueidentifier</span> <span style="color: grey;">NOT</span> <span style="color: grey;">NULL,</span></li>
<li> <span style="color: teal;">FileSource</span> <span style="color: blue;">varbinary</span><span style="color: grey;">(</span><span style="color: magenta;">MAX</span><span style="color: grey;">)</span> <span style="color: grey;">NOT</span> <span style="color: grey;">NULL DEFAULT (0x)</span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">)</span> <span style="color: blue;">ON</span> <span style="color: teal;">[PRIMARY]</span> <span style="color: blue;">TEXTIMAGE_ON</span> <span style="color: teal;">[PRIMARY]</span></li>
<li><span style="color: green;">--Add default add date for document </span></li>
<li style="background: #f3f3f3;"><span style="color: blue;">ALTER</span> <span style="color: blue;">TABLE</span> <span style="color: teal;">dbo</span><span style="color: grey;">.</span><span style="color: teal;">DocumentFiles</span> <span style="color: blue;">ADD</span> <span style="color: blue;">CONSTRAINT</span></li>
<li> <span style="color: teal;">DF_DocumentFiles_AddDate</span> <span style="color: blue;">DEFAULT</span> <span style="color: magenta;">sysdatetime</span><span style="color: grey;">()</span> <span style="color: blue;">FOR</span> <span style="color: teal;">AddDate</span></li>
</ol>
</div>
</div>
</div>
<br />
3) <b>Installing additional component for PDF file support - </b>by default PDF files is not supported in SQL Server. To check PDF support installed status just execute following T-SQL command:<br />
<br />
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="1" style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px;">
<li><span style="color: blue;">SELECT</span> <span style="color: teal;">document_type</span><span style="color: grey;">,</span> <span style="color: blue;">path</span> <span style="color: blue;">FROM</span> <span style="color: lime;">sys</span><span style="color: grey;">.</span><span style="color: lime;">fulltext_document_types</span> <span style="color: blue;">WHERE</span> <span style="color: teal;">document_type</span> <span style="color: grey;">=</span> <span style="color: red;">'.pdf'</span></li>
</ol>
</div>
</div>
<br />
If after query execution You have no rows returned, this means You have to install PDF support for SQL Server from <a href="http://www.adobe.com/support/downloads/detail.jsp?ftpID=4025" rel="nofollow" target="_blank">here</a> (version for x64). When installation complete, to see PDF file support is int the <b>sys.fulltext_document_types </b>You must restart You SQL Server instance and then validate extension is in the supported type list.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjrzNB2vwfUB-3B9sXXhVQHNglPTFQx1KFw5AJ4fyHcePpU7G_8XiJ78etHggrzUfuSu1z1i6eLVZVD6jnYxM2q0abzb4DgVB1-F9pmATnPfYIQPSZEioAxMUPjV5EDAfrV81nq4VrSw04/s1600/installedPdf.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="78" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjrzNB2vwfUB-3B9sXXhVQHNglPTFQx1KFw5AJ4fyHcePpU7G_8XiJ78etHggrzUfuSu1z1i6eLVZVD6jnYxM2q0abzb4DgVB1-F9pmATnPfYIQPSZEioAxMUPjV5EDAfrV81nq4VrSw04/s640/installedPdf.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Picture 2. Properly installed PDF extension.</td></tr>
</tbody></table>
4) <b>Creating Full-Text Search (FTS) index</b> on <b>DocumentFiles </b>table.<br />
<br />
T-SQL query below, enable FTS on databse and then create full-text catalog named <b>Document_Catalog </b>which is required for creating any FTS index on any table in database.<br />
<br />
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="1" style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px;">
<li><span style="color: blue;">EXEC</span> <span style="color: maroon;">sp_fulltext_database</span><span style="color: blue;"> </span><span style="color: red;">'enable'</span></li>
<li style="background: #f3f3f3;"><span style="color: blue;">GO</span></li>
<li><span style="color: blue;">IF</span> <span style="color: grey;">NOT</span> <span style="color: grey;">EXISTS</span><span style="color: blue;"> </span><span style="color: grey;">(</span><span style="color: blue;">SELECT</span> <span style="color: blue;">TOP</span> 1 1 <span style="color: blue;">FROM</span> <span style="color: lime;">sys</span><span style="color: grey;">.</span><span style="color: lime;">fulltext_catalogs</span> <span style="color: blue;">WHERE</span> <span style="color: teal;">name</span> <span style="color: grey;">=</span> <span style="color: red;">'Ducuments_Catalog'</span><span style="color: grey;">)</span></li>
<li style="background: #f3f3f3;"><span style="color: blue;">BEGIN</span></li>
<li> <span style="color: blue;">EXEC</span> <span style="color: maroon;">sp_fulltext_catalog</span><span style="color: blue;"> </span><span style="color: red;">'Ducuments_Catalog'</span><span style="color: grey;">,</span> <span style="color: red;">'create'</span><span style="color: grey;">;</span></li>
<li style="background: #f3f3f3;"><span style="color: blue;">END</span></li>
</ol>
</div>
</div>
<script async="" src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- dzapart_main_Blog1_300x250_as -->
<br />
<ins class="adsbygoogle" data-ad-client="ca-pub-2921101697945774" data-ad-slot="7528309165" style="display: inline-block; height: 250px; width: 300px;"></ins><script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
Now it`s time for creating full-text index. But before this, its time for a small inclusion because when You are using Entity Framework Code-First name of You primary key in any table vary between each time table is created. The problem is when creating FTS index on table we have to specified primary key index name. Query presented below retrieves primary key name from system tables and pass it further queries. Other important thing, as I write above, is <b>Extension </b>column. Here stored file extension have to be stored in the following format '<b>.pdf</b>'. This is required because SQL Server uses it to determine which Full-Text Search driver should be use. Out newly created index has change tracking set to auto so each time new document is added to index it`s automatically added to it. If you want to decide by You own when documents are updated in index set change tracking mode to manually.<br />
<br />
<br />
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="7" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li><span style="color: blue;">DECLARE</span> <span style="color: teal;">@indexName</span> <span style="color: blue;">nvarchar</span><span style="color: grey;">(</span>255<span style="color: grey;">)</span> <span style="color: grey;">=</span><span style="color: blue;"> </span><span style="color: grey;">(</span><span style="color: blue;">SELECT</span> <span style="color: blue;">Top</span> 1 <span style="color: teal;">i</span><span style="color: grey;">.</span><span style="color: teal;">Name</span> <span style="color: blue;">from</span> <span style="color: lime;">sys</span><span style="color: grey;">.</span><span style="color: lime;">indexes</span> <span style="color: teal;">i</span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">Join</span> <span style="color: lime;">sys</span><span style="color: grey;">.</span><span style="color: lime;">tables</span> <span style="color: teal;">t</span> <span style="color: blue;">on</span> <span style="color: teal;">i</span><span style="color: grey;">.</span><span style="color: magenta;">object_id</span> <span style="color: grey;">=</span> <span style="color: teal;">t</span><span style="color: grey;">.</span><span style="color: magenta;">object_id</span></li>
<li> <span style="color: blue;">WHERE</span> <span style="color: teal;">t</span><span style="color: grey;">.</span><span style="color: teal;">Name</span> <span style="color: grey;">=</span> <span style="color: red;">'DocumentFiles'</span> <span style="color: grey;">AND</span> <span style="color: teal;">i</span><span style="color: grey;">.</span><span style="color: teal;">type_desc</span> <span style="color: grey;">=</span> <span style="color: red;">'CLUSTERED'</span><span style="color: grey;">)</span></li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: blue;">PRINT</span> <span style="color: teal;">@indexName</span></li>
<li style="background: #f3f3f3;"> </li>
<li><span style="color: blue;">EXEC</span> <span style="color: maroon;">sp_fulltext_table</span><span style="color: blue;"> </span><span style="color: red;">'DocumentFiles'</span><span style="color: grey;">,</span> <span style="color: red;">'create'</span><span style="color: grey;">,</span> <span style="color: red;">'Ducuments_Catalog'</span><span style="color: grey;">,</span> <span style="color: teal;">@indexName</span></li>
<li style="background: #f3f3f3;"><span style="color: blue;">EXEC</span> <span style="color: maroon;">sp_fulltext_column</span><span style="color: blue;"> </span><span style="color: red;">'DocumentFiles'</span><span style="color: grey;">,</span> <span style="color: red;">'FileSource'</span><span style="color: grey;">,</span> <span style="color: red;">'add'</span><span style="color: grey;">,</span> 0<span style="color: grey;">,</span> <span style="color: red;">'Extension'</span></li>
<li><span style="color: blue;">EXEC</span> <span style="color: maroon;">sp_fulltext_table</span><span style="color: blue;"> </span><span style="color: red;">'DocumentFiles'</span><span style="color: grey;">,</span> <span style="color: red;">'activate'</span></li>
<li style="background: #f3f3f3;"><span style="color: blue;">EXEC</span> <span style="color: maroon;">sp_fulltext_catalog</span><span style="color: blue;"> </span><span style="color: red;">'Ducuments_Catalog'</span><span style="color: grey;">,</span> <span style="color: red;">'start_full'</span></li>
<li> </li>
<li style="background: #f3f3f3;"><span style="color: blue;">ALTER</span> <span style="color: blue;">FULLTEXT</span> <span style="color: blue;">INDEX</span> <span style="color: blue;">ON</span> <span style="color: teal;">[dbo]</span><span style="color: grey;">.</span><span style="color: teal;">[DocumentFiles]</span> <span style="color: blue;">ENABLE</span></li>
<li><span style="color: blue;">ALTER</span> <span style="color: blue;">FULLTEXT</span> <span style="color: blue;">INDEX</span> <span style="color: blue;">ON</span> <span style="color: teal;">[dbo]</span><span style="color: grey;">.</span><span style="color: teal;">[DocumentFiles]</span> <span style="color: blue;">SET</span> <span style="color: blue;">CHANGE_TRACKING</span> <span style="color: grey;">=</span> <span style="color: blue;">AUTO</span></li>
</ol>
</div>
</div>
<br />
<br />
After section four completed its time for our solution testing. For insert file to <b>DocumentFiles</b> table first insert simple data (Insert Into....) except <b>FileStream_Id</b> and <b>FileSource</b>. After it next upload file to FileStream directly from SQL Server as presented <a href="http://arcanecode.com/2009/05/20/creating-tables-and-inserting-rows-with-filestream/" rel="nofollow" target="_blank">here</a> or from <a href="http://msdn.microsoft.com/en-us/library/cc716724.aspx" rel="nofollow" target="_blank">C# code</a>.<br />
<br />
When You have data inserted You are able to query it as simple Full-Text data by using query as in example below.<br />
<br />
<br />
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="1" style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px;">
<li><span style="color: blue;">SELECT</span> <span style="color: teal;">d</span><span style="color: grey;">.*</span> <span style="color: blue;">FROM</span> <span style="color: teal;">dbo</span><span style="color: grey;">.</span><span style="color: teal;">DocumentFiles</span> <span style="color: teal;">d</span></li>
<li style="background: #f3f3f3;"><span style="color: blue;">WHERE</span> <span style="color: blue;">Contains</span><span style="color: grey;">(</span><span style="color: teal;">d</span><span style="color: grey;">.</span><span style="color: teal;">FileSource</span><span style="color: grey;">,</span> <span style="color: red;">'%Word%'</span><span style="color: grey;">)</span></li>
</ol>
</div>
</div>
<br />
<br />
Thank you.<br />
<br />
Read more...<br />
<br />
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/ms142571.aspx">http://msdn.microsoft.com/en-us/library/ms142571.aspx</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/ms142583.aspx">http://msdn.microsoft.com/en-us/library/ms142583.aspx</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/cc716724.aspx">http://msdn.microsoft.com/en-us/library/cc716724.aspx</a></li>
</ul>
<br />
<br />
<br />Damian Zaparthttp://www.blogger.com/profile/17026397366973677672noreply@blogger.comSosnowiec, Polska50.2862638 19.104079150.2050983 18.9461506 50.3674293 19.2620076tag:blogger.com,1999:blog-8522517990291142303.post-54091214347228206762012-03-10T18:52:00.001+00:002012-03-10T18:52:15.534+00:00Unexpected error while debugging Windows Phone 7.1Today I`ve some strange which occurred before my debugger attached to the Windows Mobile emulator.<br />
Exception message text was:<br />
<br />
<div style="text-align: center;">
"<span class="Apple-style-span" style="color: red;"><i>File or assembly name 'System.Windows.debug.resources, Version=2.0.5.0, Culture=en-US, PublicKeyToken=7cec85d7bea7798e', or one of its dependencies, was not found</i>.</span>"</div>
<br />
As You can see this in not helpful and hard to resolve. But after some investigation I remembered that I changed some exception settings in my Visual Studio.<br />
<br />
All thing You need to do, when you get such error is to turn off any other exception types than '<b>CLR Exceptions</b>". To change this in Visual Studio go to the Debug->Exceptions.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicCiPenQQPSR4fUCekLIG_nKdYCGkt1QdRDqc2oBtd2bcmSMEKSn5kmrtyUgQ1mQjIVPBk1P6oaEnk6sXJe_pj8stRe7XX1JHg1Oschlk4Xj2EhOcYBVVlQ4F2SRZOk1yPySb1Te6FWkOy/s1600/clrex.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="322" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicCiPenQQPSR4fUCekLIG_nKdYCGkt1QdRDqc2oBtd2bcmSMEKSn5kmrtyUgQ1mQjIVPBk1P6oaEnk6sXJe_pj8stRe7XX1JHg1Oschlk4Xj2EhOcYBVVlQ4F2SRZOk1yPySb1Te6FWkOy/s640/clrex.png" width="640" /></a></div>
<br />
Thank You.Damian Zaparthttp://www.blogger.com/profile/17026397366973677672noreply@blogger.comtag:blogger.com,1999:blog-8522517990291142303.post-73101925127280998852011-11-27T16:36:00.001+00:002011-11-27T18:40:42.746+00:00Creating common partial class with Entity FrameworkWhen we use the Entity Framework (EF) in multilayer information systems sometimes we want to extend classes generated by EF by adding some common properties or functions. Such operation can`t be conduct on *.edmx data model so we need to make some improvement in our solution. Let`s begin...<br />
<div>
<br /></div>
<div>
Lets assumed that in our soulution we have only three layer (three project):</div>
<div>
<ol>
<li>Client console application which has reference to the second layer - '<b>ConsoleApplication</b>' project name</li>
<li>Class library project with class interfaces only - '<b>Interfaces</b>' project name</li>
<li>Class library class implementation and data model referenced to 'Interfaces' project - '<b>Classes</b>' project name.</li>
</ol>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWvMiWF9J8ZHcx-y6TTGZVN3PZI41WJ732EzA_izbVRtb3pXJyKCMkWTezUfwmVhv2xcpYdsI-i8E6HpHRHt9dgxbp0PLUhJRXJLCY61x79X5I7X5_UbkIplshFlmco5eLWJMVe6fjAbEQ/s1600/solutionexplorer.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWvMiWF9J8ZHcx-y6TTGZVN3PZI41WJ732EzA_izbVRtb3pXJyKCMkWTezUfwmVhv2xcpYdsI-i8E6HpHRHt9dgxbp0PLUhJRXJLCY61x79X5I7X5_UbkIplshFlmco5eLWJMVe6fjAbEQ/s640/solutionexplorer.png" width="283" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Picture 1. Solution structure.</td></tr>
</tbody></table>
<div>
Now when we have all solution structure we can focus on data model. In the '<b>Classes</b>' project we create a new folder named '<b>Model</b>' and inside add new item of <b>ADO.NET Entity Data Model</b> named '<b>Learning.edmx</b>' - it may be empty or generated from database (in this example I created the empty one). Now it`s time to add some new entities to our model so lets assumed that we want to create a CarBrand entity and a CarModel with one to many relation (i hope You know how to do that). </div>
</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRRVPpZaCYEa4ClsFoYIjcB9dlJ_Bl9naArfBeBmEOAGzZAVgcoixS01yQ58xVcskcw3hXAWW5efB57tKESUx1tC4Tj9-3gxqXY2DCXvEkdRRx2OAzDQBksKc-aEBjasnzmNkZvJxvuTVx/s1600/entitymodel.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="276" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRRVPpZaCYEa4ClsFoYIjcB9dlJ_Bl9naArfBeBmEOAGzZAVgcoixS01yQ58xVcskcw3hXAWW5efB57tKESUx1tC4Tj9-3gxqXY2DCXvEkdRRx2OAzDQBksKc-aEBjasnzmNkZvJxvuTVx/s640/entitymodel.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Picture 2. Entity data model.</td></tr>
</tbody></table>
<div>
Next step is to create a new folder named '<b>Objects</b>' (name is not matter) and inside it create two partial classes as presented in the code-sniped below. (For this example I type the class definition in one file but in real project always create separated file for each class!!).</div>
<div>
<br /></div>
<div>
<div style="border-bottom-color: rgb(0, 0, 128); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(0, 0, 128); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(0, 0, 128); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(0, 0, 128); border-top-style: solid; border-top-width: 1px; font-family: 'Courier New', Courier, monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="6" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li><span style="color: blue;">namespace</span> Classes.Objects</li>
<li style="background: #f3f3f3;">{</li>
<li> <span style="color: blue;">public</span> <span style="color: blue;">partial</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">CarBrand</span></li>
<li style="background: #f3f3f3;"> {</li>
<li> }</li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: blue;">public</span> <span style="color: blue;">partial</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">CarModel</span></li>
<li style="background: #f3f3f3;"> {</li>
<li> }</li>
<li style="background: #f3f3f3;">}</li>
</ol>
</div>
</div>
</div>
<div>
<br /></div>
<div>
After complete class implementation we can create an interfaces for each of them. We do this in the '<b>Interfaces</b>' project.</div>
<div>
<br /></div>
<div>
<div style="border-bottom-color: rgb(0, 0, 128); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(0, 0, 128); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(0, 0, 128); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(0, 0, 128); border-top-style: solid; border-top-width: 1px; font-family: 'Courier New', Courier, monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="6" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li><span style="color: blue;">namespace</span> Interfaces.IObjects</li>
<li style="background: #f3f3f3;">{</li>
<li> <span style="color: blue;">public</span> <span style="color: blue;">interface</span> <span style="color: #2b91af;">ICarBrand</span></li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">int</span> CarBrandID { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">string</span> Name { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</li>
<li> <span style="color: #2b91af;">IList</span><<span style="color: #2b91af;">ICarModel</span>> CarModels { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</li>
<li style="background: #f3f3f3;"> }</li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: blue;">public</span> <span style="color: blue;">interface</span> <span style="color: #2b91af;">ICarModel</span></li>
<li> {</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">int</span> CarModelID { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</li>
<li> <span style="color: blue;">string</span> Name { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</li>
<li style="background: #f3f3f3;"> <span style="color: #2b91af;">ICarBrand</span> ParentBrand { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</li>
<li> }</li>
<li style="background: #f3f3f3;">}</li>
</ol>
</div>
</div>
</div>
<div>
<br /></div>
<div>
Please notice that in the line 12 and 19 I added two new properties. First one is list of car models for a single car brand object instance and the second one is parent car brad for car model. Both interfaces as public and are located in the 'IObject' folder.</div>
<div>
<br /></div>
<div>
Not it`s time to connect interfaces with the class definitions. Because the 'Classes' project has a reference to the 'Interfaces' by using using Interfaces.IObjects we are able to add suitable interface to each class. But it`s end because to connect custom our class to entity generated class we must inherit from special Entity type named <b>EntityObject </b>which is located int System.Data.Objects.DataClasses namespace. So after all changed we already have done out classes presents as follow...</div>
<div>
<br /></div>
<div>
<div style="border-bottom-color: rgb(0, 0, 128); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(0, 0, 128); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(0, 0, 128); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(0, 0, 128); border-top-style: solid; border-top-width: 1px; font-family: 'Courier New', Courier, monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li><span style="color: blue;">using</span> System;</li>
<li style="background: #f3f3f3;"><span style="color: blue;">using</span> System.Collections.Generic;</li>
<li><span style="color: blue;">using</span> System.Linq;</li>
<li style="background: #f3f3f3;"><span style="color: blue;">using</span> System.Text;</li>
<li><span style="color: blue;">using</span> Interfaces.IObjects;</li>
<li style="background: #f3f3f3;"><span style="color: blue;">using</span> System.Data.Objects.DataClasses;</li>
<li> </li>
<li style="background: #f3f3f3;"><span style="color: blue;">namespace</span> Classes.Objects</li>
<li>{</li>
<li style="background: #f3f3f3;"> <span style="color: blue;">public</span> <span style="color: blue;">partial</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">CarBrand</span> : <span style="color: #2b91af;">EntityObject</span>, <span style="color: #2b91af;">ICarBrand</span></li>
<li> {</li>
<li> <span style="color: blue;">public</span> <span style="color: #2b91af;">IList</span><<span style="color: #2b91af;">ICarModel</span>> CarModels</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">get</span></li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">throw</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">NotImplementedException</span>();</li>
<li style="background: #f3f3f3;"> }</li>
<li> <span style="color: blue;">set</span></li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">throw</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">NotImplementedException</span>();</li>
<li style="background: #f3f3f3;"> }</li>
<li> }</li>
<li style="background: #f3f3f3;"> }</li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: blue;">public</span> <span style="color: blue;">partial</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">CarModel</span> : <span style="color: #2b91af;">EntityObject</span>, <span style="color: #2b91af;">ICarModel</span></li>
<li> {</li>
<li> <span style="color: blue;">public</span> <span style="color: #2b91af;">ICarBrand</span> ParentBrand</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">get</span></li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">throw</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">NotImplementedException</span>();</li>
<li style="background: #f3f3f3;"> }</li>
<li> <span style="color: blue;">set</span></li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">throw</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">NotImplementedException</span>();</li>
<li style="background: #f3f3f3;"> }</li>
<li> }</li>
<li style="background: #f3f3f3;"> }</li>
<li>}</li>
</ol>
</div>
</div>
</div>
<div>
<br /></div>
<div>
Notice that we have implement both interfaces but also leave default implementation (line 15 and 33) - we back on it. Now it`s time to make a connection between out classes and classes generated by EF. After open data model press F4 on empty space and set Namespace property to Classes.Objects (namespace which contains are custom classes). After this do the same after clicking F4 on selected *.edmx file in Solution Explorer - example below. When both task completed just rebuild '<b>Classes</b>' project.</div>
<div>
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPbnLRwKuGj2opM9pia8yW01kxFCuwJ0sDsaVP4uZSuAXtEwlwrXq7gF4Q4MsMQL8ThSXn_6bATbH56qlp64b89h1B7lZB8eJUV9YigGAcT5aNntcf3TnSRJqd3qoLg7eNvh4K0cDSOyxT/s1600/Namespace.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPbnLRwKuGj2opM9pia8yW01kxFCuwJ0sDsaVP4uZSuAXtEwlwrXq7gF4Q4MsMQL8ThSXn_6bATbH56qlp64b89h1B7lZB8eJUV9YigGAcT5aNntcf3TnSRJqd3qoLg7eNvh4K0cDSOyxT/s640/Namespace.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Picture 3. Setting custom namespace to model.</td></tr>
</tbody></table>
<div>
<br /></div>
<div>
Now it`s time to make last implementation in out custom class.<b> Please notice that each of out custom class has now a properties defined in data model!!</b> We have to implement two properties <span class="Apple-style-span" style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: 13px;">ParentBrand </span>in CarModel class and <span class="Apple-style-span" style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: 13px;">CarModels </span>in CarBrand class. Because out classes (generated by EF and our custom) see each other properties so we can call their own properties as follow.</div>
<div>
<div style="border-bottom-color: rgb(0, 0, 128); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(0, 0, 128); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(0, 0, 128); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(0, 0, 128); border-top-style: solid; border-top-width: 1px; font-family: 'Courier New', Courier, monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="9" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li><span style="color: blue;">namespace</span> Classes.Objects</li>
<li style="background: #f3f3f3;">{</li>
<li> <span style="color: blue;">public</span> <span style="color: blue;">partial</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">CarModel</span> : <span style="color: #2b91af;">EntityObject</span>, <span style="color: #2b91af;">ICarModel</span></li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">public</span> <span style="color: #2b91af;">ICarBrand</span> ParentBrand</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">get</span></li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">return</span> <span style="color: blue;">this</span>.CarBrand <span style="color: blue;">as</span> <span style="color: #2b91af;">ICarBrand</span>; <span style="color: green;">//conver to Interface</span></li>
<li style="background: #f3f3f3;"> }</li>
<li> <span style="color: blue;">set</span></li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">this</span>.CarBrand = <span style="color: blue;">value</span> <span style="color: blue;">as</span> <span style="color: #2b91af;">CarBrand</span>; <span style="color: green;">//convert to class</span></li>
<li style="background: #f3f3f3;"> }</li>
<li> }</li>
<li style="background: #f3f3f3;"> }</li>
<li> <span style="color: blue;">public</span> <span style="color: blue;">partial</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">CarBrand</span> : <span style="color: #2b91af;">EntityObject</span>, <span style="color: #2b91af;">ICarBrand</span></li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">public</span> <span style="color: #2b91af;">IList</span><<span style="color: #2b91af;">ICarModel</span>> CarModels</li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">get</span></li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">return</span> <span style="color: blue;">this</span>.CarModels.Cast<<span style="color: #2b91af;">ICarModel</span>>().ToList();</li>
<li style="background: #f3f3f3;"> }</li>
<li> <span style="color: blue;">set</span></li>
<li style="background: #f3f3f3;"> {</li>
<li> <span style="color: blue;">this</span>.CarModels = (<span style="color: #2b91af;">IList</span><<span style="color: #2b91af;">ICarModel</span>>)<span style="color: blue;">value</span>;</li>
<li style="background: #f3f3f3;"> }</li>
<li> }</li>
<li style="background: #f3f3f3;"> }</li>
<li>}</li>
<li><br /></li>
</ol>
</div>
</div>
</div>
<br />
Now, when our classes are connected to each other we can simple call it`s instance in our Console Application. But to do this we need to create an instance on Model at runtime and create object factory so we implement to in future:) I hope You understood the principle.<br />
<br />
<a href="http://dzapart.com.pl/blogfiles/EntityTest.rar">Source code</a><br />
<br />
Thank You.Damian Zaparthttp://www.blogger.com/profile/17026397366973677672noreply@blogger.comtag:blogger.com,1999:blog-8522517990291142303.post-47907454314079524302011-10-31T21:57:00.000+00:002011-10-31T21:57:56.565+00:00Formatting XML in SQL Server 2008<div style="text-align: justify;">
Since SQL SERVER 2005 it is possible to store XML data in database by using dedicated data type - XML. This type solved many programming problems such storing XML data as simple text which was very unpleasant to maintenance and detecting errors in document structure. Now stroring XML data is very simple and requires only the creation of column in XML data type. But sometimes we may want to do reverse operation. I mean generating XML document or fragment from non XML columns in a single SELECT statement. Of course SQL Server meets our expectations and allow to transform any results of SELECT statement (which always returns table) to XML structure.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
To start transforming selected results to XML format we must use <a href="http://msdn.microsoft.com/en-us/library/ms173812.aspx">FOR XML</a> clause right after last statemnt in normal SELECT. For example instead of using:</div>
<br />
<div style="border-bottom-color: rgb(0, 0, 128); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(0, 0, 128); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(0, 0, 128); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(0, 0, 128); border-top-style: solid; border-top-width: 1px; font-family: 'Courier New', Courier, monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="2" style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px;">
<li><span style="color: blue;">SELECT</span> <span style="color: teal;">ProductNumber</span><span style="color: grey;">,</span><span style="color: teal;">Name</span><span style="color: grey;">,</span><span style="color: teal;">ListPrice</span><span style="color: grey;">,</span><span style="color: teal;">Color</span></li>
<li style="background: #f3f3f3;"><span style="color: blue;">FROM</span> <span style="color: teal;">Production</span><span style="color: grey;">.</span><span style="color: teal;">Product</span></li>
</ol>
</div>
</div>
<br />
<br />
we should use:<br />
<br />
<div style="border-bottom-color: rgb(0, 0, 128); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(0, 0, 128); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(0, 0, 128); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(0, 0, 128); border-top-style: solid; border-top-width: 1px; font-family: 'Courier New', Courier, monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="1" style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px;">
<li><span style="color: blue;">USE</span> <span style="color: teal;">[AdventureWorks]</span></li>
<li style="background: #f3f3f3;"><span style="color: blue;">SELECT</span> <span style="color: teal;">ProductNumber</span><span style="color: grey;">,</span><span style="color: teal;">Name</span><span style="color: grey;">,</span><span style="color: teal;">ListPrice</span><span style="color: grey;">,</span><span style="color: teal;">Color</span></li>
<li><span style="color: blue;">FROM</span> <span style="color: teal;">Production</span><span style="color: grey;">.</span><span style="color: teal;">Product</span></li>
<li style="background: #f3f3f3;"><span style="color: blue;">FOR</span> <span style="color: blue;">XML</span></li>
</ol>
</div>
</div>
<br />
<br />
<div style="text-align: justify;">
But if we want run this query server going to return an error 'Incorrect syntax near 'XML'. So now we realize that it is so easy - sorry :) We just tell SQL Server to prepare XML for us but we didn`t tell them how to do that. In SQL Server 2005 and above there is a short list of modes in this topic:</div>
<div style="text-align: justify;">
<br /></div>
<ul>
<li style="text-align: justify;"><b>FOR XML RAW</b> - generate a single <row> for each single row in result table returned by SELECT statement.</li>
<li style="text-align: justify;"><b>FOR XML AUTO</b> - generate nesting structure of XML document based on structure of the SELECT statement. </li>
<li style="text-align: justify;"><b>FOR XML EXPLICIT</b> - allow to generate complex structure which we can control. This provides a lot of flexibility but does so at the cost of much more greater complexity and performance.</li>
<li style="text-align: justify;"><b>FOR XML PATH</b> - as EXPLICIT its allow to customize output XML but here we can do it much more easier - queries are less complex.</li>
</ul>
<div>
<div style="text-align: justify;">
Ok, so now we are able to fix our last query so lets do this by using each of them:</div>
</div>
<div>
<br /></div>
<div>
<div style="border-bottom-color: rgb(0, 0, 128); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(0, 0, 128); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(0, 0, 128); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(0, 0, 128); border-top-style: solid; border-top-width: 1px; font-family: 'Courier New', Courier, monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li><span style="color: blue;">USE</span> <span style="color: teal;">[AdventureWorks]</span></li>
<li style="background: #f3f3f3;"><span style="color: blue;">SELECT</span> <span style="color: teal;">ProductNumber</span><span style="color: grey;">,</span><span style="color: teal;">Name</span><span style="color: grey;">,</span><span style="color: teal;">ListPrice</span><span style="color: grey;">,</span><span style="color: teal;">Color</span> <span style="color: blue;">FROM</span> <span style="color: teal;">Production</span><span style="color: grey;">.</span><span style="color: teal;">Product</span></li>
<li><span style="color: blue;">FOR</span> <span style="color: blue;">XML</span> <span style="color: blue;">RAW</span> </li>
<li style="background: #f3f3f3;"> </li>
<li><span style="color: grey;"><</span><span style="color: blue;">row</span> <span style="color: teal;">ProductNumber</span><span style="color: grey;">=</span><span style="color: teal;">"AR-5381"</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"Adjustable Race"</span> <span style="color: teal;">ListPrice</span><span style="color: grey;">=</span><span style="color: teal;">"0.0000"</span> <span style="color: grey;">/></span></li>
<li style="background: #f3f3f3;"><span style="color: grey;"><</span><span style="color: blue;">row</span> <span style="color: teal;">ProductNumber</span><span style="color: grey;">=</span><span style="color: teal;">"BA-8327"</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"Bearing Ball"</span> <span style="color: teal;">ListPrice</span><span style="color: grey;">=</span><span style="color: teal;">"0.0000"</span> <span style="color: grey;">/></span></li>
<li><span style="color: grey;"><</span><span style="color: blue;">row</span> <span style="color: teal;">ProductNumber</span><span style="color: grey;">=</span><span style="color: teal;">"BE-2349"</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"BB Ball Bearing"</span> <span style="color: teal;">ListPrice</span><span style="color: grey;">=</span><span style="color: teal;">"0.0000"</span> <span style="color: grey;">/></span></li>
<li style="background: #f3f3f3;"><span style="color: green;">------------------------------------------------------------------------------</span></li>
<li><span style="color: blue;">SELECT</span> <span style="color: teal;">ProductNumber</span><span style="color: grey;">,</span><span style="color: teal;">Name</span><span style="color: grey;">,</span><span style="color: teal;">ListPrice</span><span style="color: grey;">,</span><span style="color: teal;">Color</span> <span style="color: blue;">FROM</span> <span style="color: teal;">Production</span><span style="color: grey;">.</span><span style="color: teal;">Product</span></li>
<li style="background: #f3f3f3;"><span style="color: blue;">FOR</span> <span style="color: blue;">XML</span> <span style="color: blue;">AUTO</span> </li>
<li> </li>
<li style="background: #f3f3f3;"><span style="color: grey;"><</span><span style="color: teal;">Production</span><span style="color: grey;">.</span><span style="color: teal;">Product</span> <span style="color: teal;">ProductNumber</span><span style="color: grey;">=</span><span style="color: teal;">"AR-5381"</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"Adjustable Race"</span> <span style="color: teal;">ListPrice</span><span style="color: grey;">=</span><span style="color: teal;">"0.0000"</span> <span style="color: grey;">/></span></li>
<li><span style="color: grey;"><</span><span style="color: teal;">Production</span><span style="color: grey;">.</span><span style="color: teal;">Product</span> <span style="color: teal;">ProductNumber</span><span style="color: grey;">=</span><span style="color: teal;">"BA-8327"</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"Bearing Ball"</span> <span style="color: teal;">ListPrice</span><span style="color: grey;">=</span><span style="color: teal;">"0.0000"</span> <span style="color: grey;">/></span></li>
<li style="background: #f3f3f3;"><span style="color: grey;"><</span><span style="color: teal;">Production</span><span style="color: grey;">.</span><span style="color: teal;">Product</span> <span style="color: teal;">ProductNumber</span><span style="color: grey;">=</span><span style="color: teal;">"BE-2349"</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"BB Ball Bearing"</span> <span style="color: teal;">ListPrice</span><span style="color: grey;">=</span><span style="color: teal;">"0.0000"</span> <span style="color: grey;">/></span></li>
<li><span style="color: green;">------------------------------------------------------------------------------</span></li>
<li style="background: #f3f3f3;"><span style="color: blue;">SELECT</span> <span style="color: teal;">ProductNumber</span><span style="color: grey;">,</span><span style="color: teal;">Name</span><span style="color: grey;">,</span><span style="color: teal;">ListPrice</span><span style="color: grey;">,</span><span style="color: teal;">Color</span> <span style="color: blue;">FROM</span> <span style="color: teal;">Production</span><span style="color: grey;">.</span><span style="color: teal;">Product</span></li>
<li><span style="color: blue;">FOR</span> <span style="color: blue;">XML</span> <span style="color: blue;">EXPLICIT</span> </li>
<li style="background: #f3f3f3;"> </li>
<li><span style="color: green;">--Msg 6803, Level 16, State 1, Line 1</span></li>
<li style="background: #f3f3f3;"><span style="color: green;">--FOR XML EXPLICIT requires the first column to hold positive integers that represent XML tag IDs.</span></li>
<li><span style="color: green;">------------------------------------------------------------------------------</span></li>
<li style="background: #f3f3f3;"><span style="color: blue;">SELECT</span> <span style="color: teal;">ProductNumber</span><span style="color: grey;">,</span><span style="color: teal;">Name</span><span style="color: grey;">,</span><span style="color: teal;">ListPrice</span><span style="color: grey;">,</span><span style="color: teal;">Color</span> <span style="color: blue;">FROM</span> <span style="color: teal;">Production</span><span style="color: grey;">.</span><span style="color: teal;">Product</span></li>
<li><span style="color: blue;">FOR</span> <span style="color: blue;">XML</span> <span style="color: blue;">PATH</span> </li>
<li style="background: #f3f3f3;"><span style="color: grey;"><</span><span style="color: blue;">row</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">ProductNumber</span><span style="color: grey;">></span><span style="color: teal;">AR</span><span style="color: grey;">-</span>5381<span style="color: grey;"></</span><span style="color: teal;">ProductNumber</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">Name</span><span style="color: grey;">></span><span style="color: teal;">Adjustable</span> <span style="color: teal;">Race</span><span style="color: grey;"></</span><span style="color: teal;">Name</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">ListPrice</span><span style="color: grey;">></span>0.0000<span style="color: grey;"></</span><span style="color: teal;">ListPrice</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"><span style="color: grey;"></</span><span style="color: blue;">row</span><span style="color: grey;">></span></li>
<li><span style="color: grey;"><</span><span style="color: blue;">row</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"><span style="color: green;">------------------------------------------------------------------------------</span></li>
</ol>
</div>
</div>
</div>
<div>
<br /></div>
<br />
<div style="text-align: justify;">
You can see that three FOR XML type returns different XML structure (RAW, AUTO, PATH) and one returns error message (EXPLICIT). To explain behavior of each type we need to look at them more precisely.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<b><a href="http://msdn.microsoft.com/en-us/library/ms175140.aspx"><span class="Apple-style-span" style="font-size: large;">RAW</span></a></b></div>
<div style="text-align: justify;">
This mode returns a single XML fragment (not whole document) which consist of many <row ... /> nodes with many attributes (each column or alias from base SELECT command related to one attribute in output XML) but this was only default behavior. We may tell SQL SERVER to generate sub-nodes insted of attributes by using <i>FOR XML RAW, ELEMENTS</i> clause.</div>
<br />
<div style="border-bottom-color: rgb(0, 0, 128); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(0, 0, 128); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(0, 0, 128); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(0, 0, 128); border-top-style: solid; border-top-width: 1px; font-family: 'Courier New', Courier, monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li><span style="color: blue;">SELECT</span> <span style="color: teal;">ProductNumber</span><span style="color: grey;">,</span><span style="color: teal;">Name</span><span style="color: grey;">,</span><span style="color: teal;">ListPrice</span><span style="color: grey;">,</span><span style="color: teal;">Color</span> <span style="color: blue;">FROM</span> <span style="color: teal;">Production</span><span style="color: grey;">.</span><span style="color: teal;">Product</span></li>
<li style="background: #f3f3f3;"><span style="color: blue;">FOR</span> <span style="color: blue;">XML</span> <span style="color: blue;">RAW</span><span style="color: grey;">,</span> <span style="color: blue;">ELEMENTS</span> </li>
<li> </li>
<li style="background: #f3f3f3;"><span style="color: grey;"><</span><span style="color: blue;">row</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">ProductNumber</span><span style="color: grey;">></span><span style="color: teal;">AR</span><span style="color: grey;">-</span>5381<span style="color: grey;"></</span><span style="color: teal;">ProductNumber</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">Name</span><span style="color: grey;">></span><span style="color: teal;">Adjustable</span> <span style="color: teal;">Race</span><span style="color: grey;"></</span><span style="color: teal;">Name</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">ListPrice</span><span style="color: grey;">></span>0.0000<span style="color: grey;"></</span><span style="color: teal;">ListPrice</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"><span style="color: grey;"></</span><span style="color: blue;">row</span><span style="color: grey;">></span></li>
<li><span style="color: grey;"><</span><span style="color: blue;">row</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">ProductNumber</span><span style="color: grey;">></span><span style="color: teal;">BA</span><span style="color: grey;">-</span>8327<span style="color: grey;"></</span><span style="color: teal;">ProductNumber</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">Name</span><span style="color: grey;">></span><span style="color: teal;">Bearing</span> <span style="color: teal;">Ball</span><span style="color: grey;"></</span><span style="color: teal;">Name</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">ListPrice</span><span style="color: grey;">></span>0.0000<span style="color: grey;"></</span><span style="color: teal;">ListPrice</span><span style="color: grey;">></span></li>
<li><span style="color: grey;"></</span><span style="color: blue;">row</span><span style="color: grey;">></span></li>
</ol>
</div>
</div>
<div style="text-align: justify;">
We may use much more options in RAW mode and these are:</div>
<div style="text-align: justify;">
<br /></div>
<ul>
<li style="text-align: justify;"><b>FOR XML RAW ('custom_name')</b> - rename <row /> node to name given in brackets but we can using white space in node name</li>
<li style="text-align: justify;"><b>FOR XML RAW, ROOT </b>- result XML has exactly one root node. By default root is named <root /> but this may be changes to custom name in the same way as in case <row/> (ex. <i>FOR XML RAW ('node'), ROOT ('my_root')</i>)</li>
</ul>
<div>
<div style="text-align: justify;">
<span class="Apple-style-span" style="color: orange;">If You want to use RAW mode to obtain hierarchical structure this is not god idea....</span></div>
</div>
<div>
<div style="text-align: justify;">
<br /></div>
</div>
<div>
<div style="text-align: justify;">
<a href="http://msdn.microsoft.com/en-us/library/ms188273.aspx"><span class="Apple-style-span" style="font-size: large;"><b>AUTO</b></span></a></div>
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
This mode by default creates list on nodes without root, but unlike the RAW by default generates nodes named the same as in SELECT statement. Additionally allow to create nesting structure of XML document depends of the structure of the SELECT. The root,elements and custom root name rules are the same as in RAW mode. To demonstrate how AUTO mode works lets focus on following example.</div>
<br />
<div style="border-bottom-color: rgb(0, 0, 128); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(0, 0, 128); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(0, 0, 128); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(0, 0, 128); border-top-style: solid; border-top-width: 1px; font-family: 'Courier New', Courier, monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li><span style="color: blue;">SELECT</span> <span style="color: teal;">pm</span><span style="color: grey;">.</span><span style="color: teal;">Name</span><span style="color: grey;">,</span> <span style="color: teal;">p</span><span style="color: grey;">.</span><span style="color: teal;">ProductNumber</span><span style="color: grey;">,</span><span style="color: teal;">p</span><span style="color: grey;">.</span><span style="color: teal;">Name</span><span style="color: grey;">,</span><span style="color: teal;">p</span><span style="color: grey;">.</span><span style="color: teal;">Color</span> </li>
<li style="background: #f3f3f3;"><span style="color: blue;">FROM</span> <span style="color: teal;">Production</span><span style="color: grey;">.</span><span style="color: teal;">ProductModel</span> <span style="color: blue;">as</span> <span style="color: teal;">pm</span></li>
<li><span style="color: grey;">JOIN</span> <span style="color: teal;">Production</span><span style="color: grey;">.</span><span style="color: teal;">Product</span> <span style="color: blue;">as</span> <span style="color: teal;">p</span> <span style="color: blue;">on</span> <span style="color: teal;">p</span><span style="color: grey;">.</span><span style="color: teal;">ProductModelID</span> <span style="color: grey;">=</span> <span style="color: teal;">pm</span><span style="color: grey;">.</span><span style="color: teal;">ProductModelID</span></li>
<li style="background: #f3f3f3;"><span style="color: blue;">FOR</span> <span style="color: blue;">XML</span> <span style="color: blue;">AUTO</span><span style="color: grey;">,</span><span style="color: blue;">ROOT </span><span style="color: grey;">(</span><span style="color: red;">'Inventory'</span><span style="color: grey;">)</span></li>
<li> </li>
<li style="background: #f3f3f3;"><span style="color: grey;"><</span><span style="color: teal;">Inventory</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">pm</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"HL Road Frame"</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">p</span> <span style="color: teal;">ProductNumber</span><span style="color: grey;">=</span><span style="color: teal;">"FR-R92B-58"</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"HL Road Frame - Black, 58"</span> <span style="color: grey;">/></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">p</span> <span style="color: teal;">ProductNumber</span><span style="color: grey;">=</span><span style="color: teal;">"FR-R92R-58"</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"HL Road Frame - Red, 58"</span> <span style="color: teal;">Color</span><span style="color: grey;">=</span><span style="color: teal;">"Red"</span> <span style="color: grey;">/></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"></</span><span style="color: teal;">pm</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">pm</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"Sport-100"</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">p</span> <span style="color: teal;">ProductNumber</span><span style="color: grey;">=</span><span style="color: teal;">"HL-U509-R"</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"Sport-100 Helmet, Red"</span> <span style="color: teal;">Color</span><span style="color: grey;">=</span><span style="color: teal;">"Red"</span> <span style="color: grey;">/></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">p</span> <span style="color: teal;">ProductNumber</span><span style="color: grey;">=</span><span style="color: teal;">"HL-U509"</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"Sport-100 Helmet, Black"</span> <span style="color: teal;">Color</span><span style="color: grey;">=</span><span style="color: teal;">"Black"</span> <span style="color: grey;">/></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"></</span><span style="color: teal;">pm</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">pm</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"Mountain Bike Socks"</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">p</span> <span style="color: teal;">ProductNumber</span><span style="color: grey;">=</span><span style="color: teal;">"SO-B909-M"</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"Mountain Bike Socks, M"</span> <span style="color: teal;">Color</span><span style="color: grey;">=</span><span style="color: teal;">"White"</span> <span style="color: grey;">/></span></li>
<li> <span style="color: grey;"></</span><span style="color: teal;">pm</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"><span style="color: grey;"></</span><span style="color: teal;">Inventory</span><span style="color: grey;">></span></li>
</ol>
</div>
</div>
<br />
<div style="text-align: justify;">
As we can see by using AUTO mode we are able to generate hierarchical XML structure. But here we have several problem to fix. Firstly we not descriptive node names. This because AUTO mode uses name/aliases from original SELECT to name result nodes. To fix this just use more descriptive aliases for columns. Second things is sorting, because we don`t use any ordering nodes in result XML are non sorted and whole document looks like unpleasant. Just use ORDER BY clause to fix problem. Last problem is that first product 'FR-R92B-58' in their node haven`t attribute Color. Such thing may occur if value in database was set to NULL and SQL SERVER omit this value. Fix is very simple, just add special keyword <b>XSINIL </b>(we can use this only with ELEMENTS directive) at the end of FOR XML - this will add the schema to handle <span class="Apple-style-span" style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: 13px;"> </span><span style="background-color: white; color: blue; font-family: 'Courier New', Courier, monospace; font-size: 13px;">xsi:</span><span style="background-color: white; color: teal; font-family: 'Courier New', Courier, monospace; font-size: 13px;">nil</span><span style="background-color: white; color: grey; font-family: 'Courier New', Courier, monospace; font-size: 13px;">=</span><span style="background-color: white; color: teal; font-family: 'Courier New', Courier, monospace; font-size: 13px;">"true"</span>.<span style="background-color: white; color: teal; font-family: 'Courier New', Courier, monospace; font-size: 13px;"> </span>After all changes result presents as follow.</div>
<br />
<br />
<div style="border-bottom-color: rgb(0, 0, 128); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(0, 0, 128); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(0, 0, 128); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(0, 0, 128); border-top-style: solid; border-top-width: 1px; font-family: 'Courier New', Courier, monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li><span style="color: blue;">SELECT</span> <span style="color: teal;">[ProductModel]</span><span style="color: grey;">.</span><span style="color: teal;">Name</span><span style="color: grey;">,</span> <span style="color: teal;">[Product]</span><span style="color: grey;">.</span><span style="color: teal;">ProductNumber</span><span style="color: grey;">,</span><span style="color: teal;">[Product]</span><span style="color: grey;">.</span><span style="color: teal;">Name</span><span style="color: grey;">,</span><span style="color: teal;">[Product]</span><span style="color: grey;">.</span><span style="color: teal;">Color</span> </li>
<li style="background: #f3f3f3;"><span style="color: blue;">FROM</span> <span style="color: teal;">Production</span><span style="color: grey;">.</span><span style="color: teal;">ProductModel</span> <span style="color: blue;">as</span> <span style="color: teal;">[ProductModel]</span></li>
<li><span style="color: grey;">JOIN</span> <span style="color: teal;">Production</span><span style="color: grey;">.</span><span style="color: teal;">Product</span> <span style="color: blue;">as</span> <span style="color: teal;">[Product]</span> <span style="color: blue;">on</span> <span style="color: teal;">[Product]</span><span style="color: grey;">.</span><span style="color: teal;">ProductModelID</span> <span style="color: grey;">=</span> <span style="color: teal;">[ProductModel]</span><span style="color: grey;">.</span><span style="color: teal;">ProductModelID</span></li>
<li style="background: #f3f3f3;"><span style="color: blue;">ORDER</span> <span style="color: blue;">BY</span> <span style="color: teal;">[ProductModel]</span><span style="color: grey;">.</span><span style="color: teal;">Name</span><span style="color: grey;">,</span><span style="color: teal;">[Product]</span><span style="color: grey;">.</span><span style="color: teal;">Name</span></li>
<li><span style="color: blue;">FOR</span> <span style="color: blue;">XML</span> <span style="color: blue;">AUTO</span> <span style="color: grey;">,</span> <span style="color: blue;">ROOT</span><span style="color: grey;">(</span><span style="color: red;">'inventory'</span><span style="color: grey;">),</span> <span style="color: blue;">ELEMENTS</span> <span style="color: blue;">XSINIL</span> </li>
<li style="background: #f3f3f3;"> </li>
<li><span style="color: grey;"><</span><span style="color: teal;">inventory</span> <span style="color: blue;">xmlns:</span><span style="color: teal;">xsi</span><span style="color: grey;">=</span><span style="color: teal;">"http://www.w3.org/2001/XMLSchema-instance"</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">ProductModel</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">Name</span><span style="color: grey;">>All-</span><span style="color: teal;">Purpose</span> <span style="color: teal;">Bike</span> <span style="color: teal;">Stand</span><span style="color: grey;"></</span><span style="color: teal;">Name</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">Product</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">ProductNumber</span><span style="color: grey;">></span><span style="color: teal;">ST</span><span style="color: grey;">-</span>1401<span style="color: grey;"></</span><span style="color: teal;">ProductNumber</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">Name</span><span style="color: grey;">>All-</span><span style="color: teal;">Purpose</span> <span style="color: teal;">Bike</span> <span style="color: teal;">Stand</span><span style="color: grey;"></</span><span style="color: teal;">Name</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">Color</span> <span style="color: blue;">xsi:</span><span style="color: teal;">nil</span><span style="color: grey;">=</span><span style="color: teal;">"true"</span> <span style="color: grey;">/></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"></</span><span style="color: teal;">Product</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"></</span><span style="color: teal;">ProductModel</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">ProductModel</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">Name</span><span style="color: grey;">></span><span style="color: teal;">Bike</span> <span style="color: teal;">Wash</span><span style="color: grey;"></</span><span style="color: teal;">Name</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">Product</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">ProductNumber</span><span style="color: grey;">></span><span style="color: teal;">CL</span><span style="color: grey;">-</span>9009<span style="color: grey;"></</span><span style="color: teal;">ProductNumber</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">Name</span><span style="color: grey;">></span><span style="color: teal;">Bike</span> <span style="color: teal;">Wash</span> <span style="color: grey;">-</span> <span style="color: teal;">Dissolver</span><span style="color: grey;"></</span><span style="color: teal;">Name</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">Color</span> <span style="color: blue;">xsi:</span><span style="color: teal;">nil</span><span style="color: grey;">=</span><span style="color: teal;">"true"</span> <span style="color: grey;">/></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"></</span><span style="color: teal;">Product</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"></</span><span style="color: teal;">ProductModel</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">ProductModel</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">Name</span><span style="color: grey;">></span><span style="color: teal;">Cable</span> <span style="color: teal;">Lock</span><span style="color: grey;"></</span><span style="color: teal;">Name</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">Product</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">ProductNumber</span><span style="color: grey;">></span><span style="color: teal;">LO</span><span style="color: grey;">-</span><span style="color: teal;">C100</span><span style="color: grey;"></</span><span style="color: teal;">ProductNumber</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">Name</span><span style="color: grey;">></span><span style="color: teal;">Cable</span> <span style="color: teal;">Lock</span><span style="color: grey;"></</span><span style="color: teal;">Name</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">Color</span> <span style="color: blue;">xsi:</span><span style="color: teal;">nil</span><span style="color: grey;">=</span><span style="color: teal;">"true"</span> <span style="color: grey;">/></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"></</span><span style="color: teal;">Product</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"></</span><span style="color: teal;">ProductModel</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">ProductModel</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">Name</span><span style="color: grey;">></span><span style="color: teal;">Chain</span><span style="color: grey;"></</span><span style="color: teal;">Name</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">Product</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">ProductNumber</span><span style="color: grey;">></span><span style="color: teal;">CH</span><span style="color: grey;">-</span>0234<span style="color: grey;"></</span><span style="color: teal;">ProductNumber</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">Name</span><span style="color: grey;">></span><span style="color: teal;">Chain</span><span style="color: grey;"></</span><span style="color: teal;">Name</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">Color</span><span style="color: grey;">></span><span style="color: teal;">Silver</span><span style="color: grey;"></</span><span style="color: teal;">Color</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"></</span><span style="color: teal;">Product</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"></</span><span style="color: teal;">ProductModel</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">ProductModel</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">Name</span><span style="color: grey;">></span><span style="color: teal;">Classic</span> <span style="color: teal;">Vest</span><span style="color: grey;"></</span><span style="color: teal;">Name</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">Product</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">ProductNumber</span><span style="color: grey;">></span><span style="color: teal;">VE</span><span style="color: grey;">-</span><span style="color: teal;">C304</span><span style="color: grey;">-</span><span style="color: teal;">L</span><span style="color: grey;"></</span><span style="color: teal;">ProductNumber</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">Name</span><span style="color: grey;">></span><span style="color: teal;">Classic</span> <span style="color: teal;">Vest</span><span style="color: grey;">,</span> <span style="color: teal;">L</span><span style="color: grey;"></</span><span style="color: teal;">Name</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">Color</span><span style="color: grey;">></span><span style="color: teal;">Blue</span><span style="color: grey;"></</span><span style="color: teal;">Color</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"></</span><span style="color: teal;">Product</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"></</span><span style="color: teal;">ProductModel</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"><span style="color: grey;"></</span><span style="color: teal;">inventory</span><span style="color: grey;">></span></li>
</ol>
</div>
</div>
<br />
<span class="Apple-style-span" style="font-size: large;"><a href="http://msdn.microsoft.com/en-us/library/ms189068.aspx">EXPLICIT</a></span><br />
<div style="text-align: justify;">
This mode gives the greatest control over result XML document but requires work the most. It`s good in the situation where you want to have hierarchical and complex document. Because this mode requires special table structure returned by SELECT statement good idea is firstly create appropriate table and then add for command to construct XML. But what 'special table structure' does mean? As we can see in picture 1. if we want to use EXPLICIT mode we have to create table that contains:</div>
<div style="text-align: justify;">
<br /></div>
<ul>
<li style="text-align: justify;"><b>TAG </b>column at first position: this column is used by SQL SERVER to detect nesting level of each row.</li>
<li style="text-align: justify;"><b>Parent</b>: this column at second position tell SQL SERVER into which node each of children node is located. For top level nodes (not root node!) we pass NULL and for each next node in nesting hierarchy we increment this value at 1 point.</li>
<li style="text-align: justify;"><b>Rest of columns</b>: each columns from position 3 in table will be converted into node or attribute in result XML. But as You can see naming of those columns play the very important role and general pattern of naming looks <b>NodeName!TagID!AttributeName</b> for store value as attribute or <b>NodeName!TagID!AttributeName!Element</b> for store value as element text - please notice that in this case 'Element' is constant.</li>
</ul>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4w4Kcgu9A0A5ne60ntiXFAvS0JQw2mjeNVZALUlzpZQfvErt4y1m9A3j5CaXJAffXMaKo59d-mJRbVuX3VsbaRe7FZYRlUPUR4uYqi42sFWoDqRtZFI0zN0-YCpH-ehyrc1z0YDzh9H9N/s1600/Explicity.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="216" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4w4Kcgu9A0A5ne60ntiXFAvS0JQw2mjeNVZALUlzpZQfvErt4y1m9A3j5CaXJAffXMaKo59d-mJRbVuX3VsbaRe7FZYRlUPUR4uYqi42sFWoDqRtZFI0zN0-YCpH-ehyrc1z0YDzh9H9N/s640/Explicity.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Pic.1. 'Special table structure'.</td></tr>
</tbody></table>
Now when we have our 'special table' we can add<i> FOR XML EXPLICIT</i> clause to produce XML document (additionally with the root element). Please remembaer abut sorting to produce more readable output.<br />
<br />
<br />
<div style="border-bottom-color: rgb(0, 0, 128); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(0, 0, 128); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(0, 0, 128); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(0, 0, 128); border-top-style: solid; border-top-width: 1px; font-family: 'Courier New', Courier, monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li><span style="color: blue;">SELECT</span> 1 <span style="color: blue;">as</span> <span style="color: teal;">TAG</span><span style="color: grey;">,</span> <span style="color: grey;">NULL</span> <span style="color: blue;">as</span> <span style="color: teal;">Parent</span><span style="color: grey;">,</span></li>
<li style="background: #f3f3f3;"> <span style="color: teal;">[ProductModel]</span><span style="color: grey;">.</span><span style="color: teal;">ProductModelID</span> <span style="color: blue;">as</span> <span style="color: teal;">[Model!1!ID]</span><span style="color: grey;">,</span></li>
<li> <span style="color: teal;">[ProductModel]</span><span style="color: grey;">.</span><span style="color: teal;">Name</span> <span style="color: blue;">as</span> <span style="color: teal;">[Model!1!Name]</span><span style="color: grey;">,</span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">NULL</span> <span style="color: blue;">as</span> <span style="color: teal;">[Product!2!Number!Element]</span><span style="color: grey;">,</span></li>
<li> <span style="color: grey;">NULL</span> <span style="color: blue;">as</span> <span style="color: teal;">[Product!2!Name]</span><span style="color: grey;">,</span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">NULL</span> <span style="color: blue;">as</span> <span style="color: teal;">[Product!2!Color]</span></li>
<li><span style="color: blue;">FROM</span> <span style="color: teal;">Production</span><span style="color: grey;">.</span><span style="color: teal;">ProductModel</span> <span style="color: blue;">as</span> <span style="color: teal;">[ProductModel]</span></li>
<li style="background: #f3f3f3;"><span style="color: grey;">JOIN</span> <span style="color: teal;">Production</span><span style="color: grey;">.</span><span style="color: teal;">Product</span> <span style="color: blue;">as</span> <span style="color: teal;">[Product]</span> <span style="color: blue;">on</span> <span style="color: teal;">[Product]</span><span style="color: grey;">.</span><span style="color: teal;">ProductModelID</span> <span style="color: grey;">=</span> <span style="color: teal;">[ProductModel]</span><span style="color: grey;">.</span><span style="color: teal;">ProductModelID</span></li>
<li><span style="color: blue;">UNION</span> <span style="color: grey;">ALL</span></li>
<li style="background: #f3f3f3;"><span style="color: blue;">SELECT</span> 2<span style="color: grey;">,</span> 1<span style="color: grey;">,</span></li>
<li> <span style="color: teal;">[ProductModel]</span><span style="color: grey;">.</span><span style="color: teal;">ProductModelID</span><span style="color: grey;">,</span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">NULL,</span></li>
<li> <span style="color: teal;">[Product]</span><span style="color: grey;">.</span><span style="color: teal;">ProductNumber</span><span style="color: grey;">,</span></li>
<li style="background: #f3f3f3;"> <span style="color: teal;">[Product]</span><span style="color: grey;">.</span><span style="color: teal;">Name</span><span style="color: grey;">,</span></li>
<li> <span style="color: teal;">[Product]</span><span style="color: grey;">.</span><span style="color: teal;">Color</span> </li>
<li style="background: #f3f3f3;"><span style="color: blue;">FROM</span> <span style="color: teal;">Production</span><span style="color: grey;">.</span><span style="color: teal;">ProductModel</span> <span style="color: blue;">as</span> <span style="color: teal;">[ProductModel]</span></li>
<li><span style="color: grey;">JOIN</span> <span style="color: teal;">Production</span><span style="color: grey;">.</span><span style="color: teal;">Product</span> <span style="color: blue;">as</span> <span style="color: teal;">[Product]</span> <span style="color: blue;">on</span> <span style="color: teal;">[Product]</span><span style="color: grey;">.</span><span style="color: teal;">ProductModelID</span> <span style="color: grey;">=</span> <span style="color: teal;">[ProductModel]</span><span style="color: grey;">.</span><span style="color: teal;">ProductModelID</span></li>
<li style="background: #f3f3f3;"><span style="color: blue;">ORDER</span> <span style="color: blue;">BY</span> <span style="color: teal;">[Model!1!ID]</span></li>
<li><span style="color: blue;">FOR</span> <span style="color: blue;">XML</span> <span style="color: blue;">EXPLICIT</span><span style="color: grey;">,</span> <span style="color: blue;">ROOT </span><span style="color: grey;">(</span><span style="color: red;">'Inventory'</span><span style="color: grey;">)</span></li>
<li style="background: #f3f3f3;"> </li>
<li><span style="color: grey;"><</span><span style="color: teal;">Inventory</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">Model</span> <span style="color: teal;">ID</span><span style="color: grey;">=</span><span style="color: teal;">"1"</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"Classic Vest"</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">Product</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"Classic Vest, S"</span> <span style="color: teal;">Color</span><span style="color: grey;">=</span><span style="color: teal;">"Blue"</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">Number</span><span style="color: grey;">></span><span style="color: teal;">VE</span><span style="color: grey;">-</span><span style="color: teal;">C304</span><span style="color: grey;">-</span><span style="color: teal;">S</span><span style="color: grey;"></</span><span style="color: teal;">Number</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"></</span><span style="color: teal;">Product</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">Product</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"Classic Vest, M"</span> <span style="color: teal;">Color</span><span style="color: grey;">=</span><span style="color: teal;">"Blue"</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">Number</span><span style="color: grey;">></span><span style="color: teal;">VE</span><span style="color: grey;">-</span><span style="color: teal;">C304</span><span style="color: grey;">-</span><span style="color: teal;">M</span><span style="color: grey;"></</span><span style="color: teal;">Number</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"></</span><span style="color: teal;">Product</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">Product</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"Classic Vest, L"</span> <span style="color: teal;">Color</span><span style="color: grey;">=</span><span style="color: teal;">"Blue"</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">Number</span><span style="color: grey;">></span><span style="color: teal;">VE</span><span style="color: grey;">-</span><span style="color: teal;">C304</span><span style="color: grey;">-</span><span style="color: teal;">L</span><span style="color: grey;"></</span><span style="color: teal;">Number</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"></</span><span style="color: teal;">Product</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">Product</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"AWC Logo Cap"</span> <span style="color: teal;">Color</span><span style="color: grey;">=</span><span style="color: teal;">"Multi"</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">Number</span><span style="color: grey;">></span><span style="color: teal;">CA</span><span style="color: grey;">-</span>1098<span style="color: grey;"></</span><span style="color: teal;">Number</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"></</span><span style="color: teal;">Product</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"></</span><span style="color: teal;">Model</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">Model</span> <span style="color: teal;">ID</span><span style="color: grey;">=</span><span style="color: teal;">"2"</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"Cycling Cap"</span> <span style="color: grey;">/></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">Model</span> <span style="color: teal;">ID</span><span style="color: grey;">=</span><span style="color: teal;">"3"</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"Full-Finger Gloves"</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">Product</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"Full-Finger Gloves, S"</span> <span style="color: teal;">Color</span><span style="color: grey;">=</span><span style="color: teal;">"Black"</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">Number</span><span style="color: grey;">></span><span style="color: teal;">GL</span><span style="color: grey;">-</span><span style="color: teal;">F110</span><span style="color: grey;">-</span><span style="color: teal;">S</span><span style="color: grey;"></</span><span style="color: teal;">Number</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"></</span><span style="color: teal;">Product</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">Product</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"Full-Finger Gloves, M"</span> <span style="color: teal;">Color</span><span style="color: grey;">=</span><span style="color: teal;">"Black"</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">Number</span><span style="color: grey;">></span><span style="color: teal;">GL</span><span style="color: grey;">-</span><span style="color: teal;">F110</span><span style="color: grey;">-</span><span style="color: teal;">M</span><span style="color: grey;"></</span><span style="color: teal;">Number</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"></</span><span style="color: teal;">Product</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">Product</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"Full-Finger Gloves, L"</span> <span style="color: teal;">Color</span><span style="color: grey;">=</span><span style="color: teal;">"Black"</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">Number</span><span style="color: grey;">></span><span style="color: teal;">GL</span><span style="color: grey;">-</span><span style="color: teal;">F110</span><span style="color: grey;">-</span><span style="color: teal;">L</span><span style="color: grey;"></</span><span style="color: teal;">Number</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"></</span><span style="color: teal;">Product</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">Product</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"Half-Finger Gloves, S"</span> <span style="color: teal;">Color</span><span style="color: grey;">=</span><span style="color: teal;">"Black"</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">Number</span><span style="color: grey;">></span><span style="color: teal;">GL</span><span style="color: grey;">-</span><span style="color: teal;">H102</span><span style="color: grey;">-</span><span style="color: teal;">S</span><span style="color: grey;"></</span><span style="color: teal;">Number</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"></</span><span style="color: teal;">Product</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">Product</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"Half-Finger Gloves, M"</span> <span style="color: teal;">Color</span><span style="color: grey;">=</span><span style="color: teal;">"Black"</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">Number</span><span style="color: grey;">></span><span style="color: teal;">GL</span><span style="color: grey;">-</span><span style="color: teal;">H102</span><span style="color: grey;">-</span><span style="color: teal;">M</span><span style="color: grey;"></</span><span style="color: teal;">Number</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"></</span><span style="color: teal;">Product</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">Product</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"Half-Finger Gloves, L"</span> <span style="color: teal;">Color</span><span style="color: grey;">=</span><span style="color: teal;">"Black"</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">Number</span><span style="color: grey;">></span><span style="color: teal;">GL</span><span style="color: grey;">-</span><span style="color: teal;">H102</span><span style="color: grey;">-</span><span style="color: teal;">L</span><span style="color: grey;"></</span><span style="color: teal;">Number</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"></</span><span style="color: teal;">Product</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"></</span><span style="color: teal;">Model</span><span style="color: grey;">></span></li>
<li><span style="color: grey;"></</span><span style="color: teal;">Inventory</span><span style="color: grey;">></span></li>
</ol>
</div>
</div>
<br />
<br />
<span class="Apple-style-span" style="font-size: large;"><b><a href="http://msdn.microsoft.com/en-us/library/ms189885.aspx">PATH</a></b></span><br />
<div style="text-align: justify;">
We can read in MSDN '<i>PATH mode is also a simpler way to introduce additional nesting for representing complex properties</i>' and whole is true. PATH mode is much more easier way than EXPLICITY mode to create complex XML. This mode based on additional technology called <a href="http://www.w3schools.com/xpath/">XPATH</a> which allow to query XML data but in this case reverse application was used. Its means that XML document hierarchy is contructed at runtime based on column name from the underlying SELECT statement.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The easiest way to introduce custom attributes to XML output is to add column aliases to each column in base SELECT statement (result as below). The problem with outputted XML is that we have a lot of <row /> node which is obviously not a professional, additionally we haven`t root node but as You can see by using @ before column alias we may create a attribute of current node ex. @Name. Next problem is that we don`t have any nested nodes because if we add some XPATX name like 'node/test' the result will be far from true.</div>
<div>
<div style="border-bottom-color: rgb(0, 0, 128); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(0, 0, 128); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(0, 0, 128); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(0, 0, 128); border-top-style: solid; border-top-width: 1px; font-family: 'Courier New', Courier, monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li><span style="color: blue;">SELECT </span> <span style="color: teal;">[ProductModel]</span><span style="color: grey;">.</span><span style="color: teal;">ProductModelID</span> <span style="color: blue;">as</span> <span style="color: red;">'@ID'</span><span style="color: grey;">,</span></li>
<li style="background: #f3f3f3;"> <span style="color: teal;">[ProductModel]</span><span style="color: grey;">.</span><span style="color: teal;">Name</span> <span style="color: blue;">as</span> <span style="color: red;">'@Name'</span></li>
<li><span style="color: blue;">FROM</span> <span style="color: teal;">Production</span><span style="color: grey;">.</span><span style="color: teal;">ProductModel</span> <span style="color: blue;">as</span> <span style="color: teal;">[ProductModel]</span></li>
<li style="background: #f3f3f3;"><span style="color: blue;">ORDER</span> <span style="color: blue;">BY</span> <span style="color: teal;">[ProductModel]</span><span style="color: grey;">.</span><span style="color: teal;">ProductModelID</span></li>
<li><span style="color: blue;">FOR</span> <span style="color: blue;">XML</span> <span style="color: blue;">PATH</span></li>
<li style="background: #f3f3f3;"> </li>
<li><span style="color: grey;"><</span><span style="color: blue;">row</span> <span style="color: teal;">ID</span><span style="color: grey;">=</span><span style="color: teal;">"1"</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"Classic Vest"</span> <span style="color: grey;">/></span></li>
<li style="background: #f3f3f3;"><span style="color: grey;"><</span><span style="color: blue;">row</span> <span style="color: teal;">ID</span><span style="color: grey;">=</span><span style="color: teal;">"2"</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"Cycling Cap"</span> <span style="color: grey;">/></span></li>
<li><span style="color: grey;"><</span><span style="color: blue;">row</span> <span style="color: teal;">ID</span><span style="color: grey;">=</span><span style="color: teal;">"3"</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"Full-Finger Gloves"</span> <span style="color: grey;">/></span></li>
<li style="background: #f3f3f3;"><span style="color: grey;"><</span><span style="color: blue;">row</span> <span style="color: teal;">ID</span><span style="color: grey;">=</span><span style="color: teal;">"4"</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"Half-Finger Gloves"</span> <span style="color: grey;">/></span></li>
<li><span style="color: grey;"><</span><span style="color: blue;">row</span> <span style="color: teal;">ID</span><span style="color: grey;">=</span><span style="color: teal;">"5"</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"HL Mountain Frame"</span> <span style="color: grey;">/></span></li>
<li style="background: #f3f3f3;"><span style="color: grey;"><</span><span style="color: blue;">row</span> <span style="color: teal;">ID</span><span style="color: grey;">=</span><span style="color: teal;">"6"</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"HL Road Frame"</span> <span style="color: grey;">/></span></li>
<li><span style="color: grey;"><</span><span style="color: blue;">row</span> <span style="color: teal;">ID</span><span style="color: grey;">=</span><span style="color: teal;">"7"</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"HL Touring Frame"</span> <span style="color: grey;">/></span></li>
</ol>
</div>
</div>
</div>
<div>
<br /></div>
<div style="text-align: justify;">
To fix problems listed above we have to make some changes in base SELECT query. Let`s assume that we want to have root node named 'Models'. As You can read earlier in this article this problem can be solve by adding <i>ROOT('Models')</i> at the end of <i>FOR XML PATH</i> statement. Furthermore we want to remove odd <row /> nodes from output XML replacing them with 'Model' nodes - this can be done easily by adding name after <i>FOR XML PATH</i> ex. <i>FOR XML PATH ('Model')</i>. Last this we want to do is to attach products list in each 'Model' node. This is not as intuitive as we can think and to solve this problem we must be familiar with <a href="http://msdn.microsoft.com/en-us/library/ms190025.aspx">TYPE </a> SQL keyword. By using it we can create SQL type content (hyperlinked in Management Studio) in sub-query so we are able to return base data time in the same row as XML. But in this case we need to use TYPE keyword to create sub-nodes collection in our output document. Because we cant to add list of products to each product model (example below) we need to use sub-query inside in which we want to make a list of products where each products contains two attributes (name and color) and list (sub-nodes) of product number. To achieve this we need to make a sub-query in our SELECT statement and inside it we have to make correlated query (in example. <i>[Product].ProductModelID = [ProductModel].ProductModelID</i>). Whole sub-query result need an alias which will be parent node for whole product list in output example. Our sub-query need to return XML element so to to this right we have to use TYPE keyword with FOR XML PATH mode.</div>
<div>
<br /><div>
<div>
<div style="border-bottom-color: rgb(0, 0, 128); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(0, 0, 128); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(0, 0, 128); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(0, 0, 128); border-top-style: solid; border-top-width: 1px; font-family: 'Courier New', Courier, monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li><span style="color: blue;">SELECT </span> <span style="color: teal;">[ProductModel]</span><span style="color: grey;">.</span><span style="color: teal;">ProductModelID</span> <span style="color: blue;">as</span> <span style="color: red;">'@ID'</span><span style="color: grey;">,</span></li>
<li style="background: #f3f3f3;"> <span style="color: teal;">[ProductModel]</span><span style="color: grey;">.</span><span style="color: teal;">Name</span> <span style="color: blue;">as</span> <span style="color: red;">'@Name'</span><span style="color: grey;">,</span></li>
<li> <span style="color: blue;"> </span><span style="color: grey;">(</span><span style="color: blue;">SELECT</span> </li>
<li style="background: #f3f3f3;"> <span style="color: teal;">[Product]</span><span style="color: grey;">.</span><span style="color: teal;">Name</span> <span style="color: blue;">as</span> <span style="color: red;">'@Name'</span><span style="color: grey;">,</span></li>
<li> <span style="color: teal;">[Product]</span><span style="color: grey;">.</span><span style="color: teal;">Color</span> <span style="color: blue;">as</span> <span style="color: red;">'@Color'</span><span style="color: grey;">,</span></li>
<li style="background: #f3f3f3;"> <span style="color: teal;">[Product]</span><span style="color: grey;">.</span><span style="color: teal;">ProductNumber</span> <span style="color: blue;">as</span> <span style="color: red;">'Number'</span></li>
<li> <span style="color: blue;">FROM</span> <span style="color: teal;">Production</span><span style="color: grey;">.</span><span style="color: teal;">Product</span> <span style="color: teal;">[Product]</span> </li>
<li style="background: #f3f3f3;"> <span style="color: blue;">WHERE</span> <span style="color: teal;">[Product]</span><span style="color: grey;">.</span><span style="color: teal;">ProductModelID</span> <span style="color: grey;">=</span> <span style="color: teal;">[ProductModel]</span><span style="color: grey;">.</span><span style="color: teal;">ProductModelID</span></li>
<li> <span style="color: blue;">FOR</span> <span style="color: blue;">XML</span> <span style="color: blue;">PATH </span><span style="color: grey;">(</span><span style="color: red;">'Product'</span><span style="color: grey;">),</span> <span style="color: blue;">TYPE</span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;">)</span> <span style="color: blue;">as</span> <span style="color: red;">'Products'</span></li>
<li><span style="color: blue;">FROM</span> <span style="color: teal;">Production</span><span style="color: grey;">.</span><span style="color: teal;">ProductModel</span> <span style="color: blue;">as</span> <span style="color: teal;">[ProductModel]</span></li>
<li style="background: #f3f3f3;"> <span style="color: blue;">ORDER</span> <span style="color: blue;">BY</span><span style="color: teal;">[ProductModel]</span><span style="color: grey;">.</span><span style="color: teal;">ProductModelID</span></li>
<li><span style="color: blue;">FOR</span> <span style="color: blue;">XML</span> <span style="color: blue;">PATH</span><span style="color: grey;">(</span><span style="color: red;">'Model'</span><span style="color: grey;">),</span><span style="color: blue;">ROOT</span><span style="color: grey;">(</span><span style="color: red;">'Models'</span><span style="color: grey;">)</span></li>
<li style="background: #f3f3f3;"> </li>
<li><span style="color: grey;"><</span><span style="color: teal;">Models</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">Model</span> <span style="color: teal;">ID</span><span style="color: grey;">=</span><span style="color: teal;">"1"</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"Classic Vest"</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">Products</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">Product</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"Classic Vest, S"</span> <span style="color: teal;">Color</span><span style="color: grey;">=</span><span style="color: teal;">"Blue"</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">Number</span><span style="color: grey;">></span><span style="color: teal;">VE</span><span style="color: grey;">-</span><span style="color: teal;">C304</span><span style="color: grey;">-</span><span style="color: teal;">S</span><span style="color: grey;"></</span><span style="color: teal;">Number</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"></</span><span style="color: teal;">Product</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">Product</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"Classic Vest, M"</span> <span style="color: teal;">Color</span><span style="color: grey;">=</span><span style="color: teal;">"Blue"</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">Number</span><span style="color: grey;">></span><span style="color: teal;">VE</span><span style="color: grey;">-</span><span style="color: teal;">C304</span><span style="color: grey;">-</span><span style="color: teal;">M</span><span style="color: grey;"></</span><span style="color: teal;">Number</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"></</span><span style="color: teal;">Product</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">Product</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"Classic Vest, L"</span> <span style="color: teal;">Color</span><span style="color: grey;">=</span><span style="color: teal;">"Blue"</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">Number</span><span style="color: grey;">></span><span style="color: teal;">VE</span><span style="color: grey;">-</span><span style="color: teal;">C304</span><span style="color: grey;">-</span><span style="color: teal;">L</span><span style="color: grey;"></</span><span style="color: teal;">Number</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"></</span><span style="color: teal;">Product</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"></</span><span style="color: teal;">Products</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"></</span><span style="color: teal;">Model</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">Model</span> <span style="color: teal;">ID</span><span style="color: grey;">=</span><span style="color: teal;">"2"</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"Cycling Cap"</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">Products</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"><</span><span style="color: teal;">Product</span> <span style="color: teal;">Name</span><span style="color: grey;">=</span><span style="color: teal;">"AWC Logo Cap"</span> <span style="color: teal;">Color</span><span style="color: grey;">=</span><span style="color: teal;">"Multi"</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"><</span><span style="color: teal;">Number</span><span style="color: grey;">></span><span style="color: teal;">CA</span><span style="color: grey;">-</span>1098<span style="color: grey;"></</span><span style="color: teal;">Number</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"></</span><span style="color: teal;">Product</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"> <span style="color: grey;"></</span><span style="color: teal;">Products</span><span style="color: grey;">></span></li>
<li> <span style="color: grey;"></</span><span style="color: teal;">Model</span><span style="color: grey;">></span></li>
<li style="background: #f3f3f3;"><span style="color: grey;"></</span><span style="color: teal;">Models</span><span style="color: grey;">></span></li>
</ol>
</div>
</div>
</div>
<div>
<br /></div>
After making appropriate adjustments our query is ready to deploy on server to returns pretty looks XML document.</div>
</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
Thank You...</div>Damian Zaparthttp://www.blogger.com/profile/17026397366973677672noreply@blogger.comtag:blogger.com,1999:blog-8522517990291142303.post-4921321044801601792011-10-22T08:27:00.000+01:002011-10-22T08:44:59.633+01:00Processing XML i SQL SERVER 2008Many times our application uses data from external suppliers. These data, mostly
recived by the Internet, is written in XML format and has different from our data
mode structure. But it`s still very important for us so we want to process them
by extracting data from. Of course we may procesing XML documents in CLR or
simple .NET project and than pass them to database but we should this about performance
of each our solution. For example if we recieved 100MB XML document from supplier
and we processed them we still need to send those data to our database which means
that we have to pass data by the network- it`s very costly...<br />
<br />
Now assume that the same operation, connected with proccessing XMLdocuemnt, can
be done in SQL SERVER side. Looks great don`t You? So let`s begin.<br />
<br />
First of all we should learn something more about three things:<br />
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/ms187367.aspx" target="_blank">
master.dbo.sp_xml_preparedocument</a>: start preparing passed text as XML document
with checking document integrity. The first (OUTPUT type) parameter '<span class="Apple-style-span" style="font-family: monospace; font-size: 13px; white-space: pre;">idoc</span>'
returns handle to XML cached in memory.</li>
<li><a href="http://msdn.microsoft.com/en-us/library/ms186918.aspx" target="_blank">
OPENXML</a> (keyword): used to generate table from XML parameters passed as a handle
to a file in memory. <b>Allow to processing XML document fragment</b>.</li>
<li><a href="http://msdn.microsoft.com/en-us/library/ms190353.aspx" target="_blank">
master.dbo.sp_xml_removedocument</a>: removes all information conected with passed '<span class="Apple-style-span" style="font-family: monospace; font-size: 13px; white-space: pre;">idoc</span>'
handler.</li>
</ul>
<div>
Now we are able to use elements enumerated above to create simple importing stored
procedure. Let`s assumed that we are going to import the following XML document
fragment (not entire XML document!!):
<br />
<br /></div>
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px; white-space: nowrap;">
<li><span style="color: blue;">DECLARE</span> <span style="color: teal;">@t</span> <span style="color: blue;">as</span> <span style="color: grey;">=</span><span style="color: red;">'<Car
Brand="Audi"></span></li>
<li style="background: #f3f3f3;"> <span style="color: red;"><Model Name="A1"></span></li>
<li> <span style="color: red;"><Type TypeName="Sendan"></span></li>
<li style="background: #f3f3f3;"> <span style="color: red;"><EngineType
Vol="1.6" Fuel="Benzine" Version="Standard" BasePrince="80000" /></span></li>
<li> <span style="color: red;"><EngineType Vol="1.8"
Fuel="Benzine" Version="Standard" BasePrince="85000" /></span></li>
<li style="background: #f3f3f3;"> <span style="color: red;"><EngineType
Vol="1.8" Fuel="Benzine" Version="Full" BasePrince="95000" /></span></li>
<li> <span style="color: red;"><EngineType Vol="1.9"
Fuel="Diseal" Version="Standard" BasePrince="95000" /></span></li>
<li style="background: #f3f3f3;"> <span style="color: red;"><EngineType
Vol="1.9" Fuel="Diseal" Version="Full" BasePrince="105000" /></span></li>
<li> <span style="color: red;"></Type></span></li>
<li style="background: #f3f3f3;"> <span style="color: red;"><Type
TypeName="Coupe"></span></li>
<li> <span style="color: red;"><EngineType Vol="1.6"
Fuel="Benzine" Version="Standard" BasePrince="81000" /></span></li>
<li style="background: #f3f3f3;"> <span style="color: red;"><EngineType
Vol="1.8" Fuel="Benzine" Version="Standard" BasePrince="86000" /></span></li>
<li> <span style="color: red;"><EngineType Vol="1.8"
Fuel="Benzine" Version="Full" BasePrince="96000" /></span></li>
<li style="background: #f3f3f3;"> <span style="color: red;"><EngineType
Vol="1.9" Fuel="Diseal" Version="Standard" BasePrince="96000" /></span></li>
<li> <span style="color: red;"><EngineType Vol="1.9"
Fuel="Diseal" Version="Full" BasePrince="106000" /></span></li>
<li style="background: #f3f3f3;"> <span style="color: red;"></Type></span></li>
<li> <span style="color: red;"></Model></span></li>
<li style="background: #f3f3f3;"> <span style="color: red;"><Model Name="A4"></span></li>
<li> <span style="color: red;"><Type TypeName="Sendan"></span></li>
<li style="background: #f3f3f3;"> <span style="color: red;"><EngineType
Vol="1.6" Fuel="Benzine" Version="Standard" BasePrince="110000" /></span></li>
<li> <span style="color: red;"><EngineType Vol="1.8"
Fuel="Benzine" Version="Standard" BasePrince="115000" /></span></li>
<li style="background: #f3f3f3;"> <span style="color: red;"><EngineType
Vol="1.8" Fuel="Benzine" Version="Full" BasePrince="115000" /></span></li>
<li> <span style="color: red;"><EngineType Vol="1.9"
Fuel="Diseal" Version="Standard" BasePrince="115000" /></span></li>
<li style="background: #f3f3f3;"> <span style="color: red;"><EngineType
Vol="1.9" Fuel="Diseal" Version="Full" BasePrince="125000" /></span></li>
<li> <span style="color: red;"></Type></span></li>
<li style="background: #f3f3f3;"> <span style="color: red;"><Type
TypeName="AllRoad"></span></li>
<li> <span style="color: red;"><EngineType Vol="1.6"
Fuel="Benzine" Version="Standard" BasePrince="110000" /></span></li>
<li style="background: #f3f3f3;"> <span style="color: red;"><EngineType
Vol="1.8" Fuel="Benzine" Version="Standard" BasePrince="115000" /></span></li>
<li> <span style="color: red;"><EngineType Vol="1.8"
Fuel="Benzine" Version="Full" BasePrince="115000" /></span></li>
<li style="background: #f3f3f3;"> <span style="color: red;"><EngineType
Vol="1.9" Fuel="Diseal" Version="Standard" BasePrince="115000" /></span></li>
<li> <span style="color: red;"><EngineType Vol="1.9"
Fuel="Diseal" Version="Full" BasePrince="125000" /></span></li>
<li style="background: #f3f3f3;"> <span style="color: red;"></Type></span></li>
<li> <span style="color: red;"></Model></span></li>
<li style="background: #f3f3f3;"><span style="color: red;"></Car>'</span><span style="color: grey;">;</span></li>
</ol>
</div>
</div>
<br />
Now its time for out table. For this example there is only one table (noncompilant
with 2NF and 3NF!).<br />
<br />
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px; white-space: nowrap;">
<li><span style="color: blue;">CREATE</span> <span style="color: blue;">TABLE</span>
<span style="color: teal;">dbo</span><span style="color: grey;">.</span><span style="color: teal;">Cars</span></li>
<li style="background: #f3f3f3;"><span style="color: grey;">(</span></li>
<li><span style="color: teal;">CarID</span> <span style="color: blue;">int</span>
<span style="color: blue;">IDENTITY</span><span style="color: grey;">(</span>1<span style="color: grey;">,</span>1<span style="color: grey;">)</span> <span style="color: blue;">
PRIMARY</span> <span style="color: blue;">KEY</span><span style="color: grey;">,</span></li>
<li style="background: #f3f3f3;"><span style="color: teal;">CarBrand</span> <span style="color: blue;">nvarchar</span><span style="color: grey;">(</span>50<span style="color: grey;">)</span> <span style="color: grey;">not</span> <span style="color: grey;">
null,</span></li>
<li><span style="color: teal;">ModelName</span> <span style="color: blue;">nvarchar</span><span style="color: grey;">(</span>50<span style="color: grey;">)</span> <span style="color: grey;">
not</span> <span style="color: grey;">null,</span></li>
<li style="background: #f3f3f3;"><span style="color: teal;">TypName</span> <span style="color: blue;">nvarchar</span><span style="color: grey;">(</span>50<span style="color: grey;">)</span> <span style="color: grey;">not</span> <span style="color: grey;">
null,</span></li>
<li><span style="color: teal;">Engine</span> <span style="color: blue;">float</span>
<span style="color: grey;">not</span> <span style="color: grey;">null,</span></li>
<li style="background: #f3f3f3;"><span style="color: teal;">FuelType</span> <span style="color: blue;">nvarchar</span><span style="color: grey;">(</span>10<span style="color: grey;">)</span> <span style="color: grey;">not</span> <span style="color: grey;">
null,</span></li>
<li><span style="color: teal;">CarVersion</span> <span style="color: blue;">nvarchar</span><span style="color: grey;">(</span>50<span style="color: grey;">)</span> <span style="color: grey;">
not</span> <span style="color: grey;">null,</span></li>
<li style="background: #f3f3f3;"><span style="color: teal;">BasePrince</span> <span style="color: blue;">int</span> <span style="color: grey;">not</span> <span style="color: grey;">
null</span></li>
<li><span style="color: grey;">)</span></li>
<li style="background: #f3f3f3;"><span style="color: blue;">GO</span><span style="color: grey;">;</span></li>
</ol>
</div>
</div>
<br />
<div style="border-bottom-color: rgb(0, 0, 128); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(0, 0, 128); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(0, 0, 128); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(0, 0, 128); border-top-style: solid; border-top-width: 1px; color: black; font-family: 'Courier New', Courier, monospace; font-size: 10pt;">
<div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">
Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;">
<ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px; white-space: nowrap;">
<li><span style="color: blue;">CREATE</span> <span style="color: blue;">PROCEDURE</span>
<span style="color: teal;">dbo</span><span style="color: grey;">.</span><span style="color: teal;">ImportCars</span></li>
<li style="background: #f3f3f3;"> <span style="color: teal;">@data</span>
<span style="color: blue;">xml</span></li>
<li><span style="color: blue;">AS</span></li>
<li style="background: #f3f3f3;"><span style="color: blue;">BEGIN</span></li>
<li> <span style="color: blue;">DECLARE</span> <span style="color: teal;">@handle</span> <span style="color: blue;">int</span><span style="color: grey;">;</span>
<span style="color: green;">--handler declaration</span></li>
<li style="background: #f3f3f3;"> </li>
<li> <span style="color: green;">--Preparing document</span></li>
<li style="background: #f3f3f3;"> <span style="color: blue;">EXEC</span>
<span style="color: blue;">master</span><span style="color: grey;">.</span><span style="color: teal;">dbo</span><span style="color: grey;">.</span><span style="color: maroon;">sp_xml_preparedocument</span><span style="color: blue;"> </span><span style="color: teal;">@handle</span> <span style="color: blue;">
OUTPUT</span><span style="color: grey;">,</span> <span style="color: teal;">@data</span><span style="color: grey;">;</span></li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: green;">--Reading
XML and inserting selected values</span></li>
<li> <span style="color: blue;">INSERT</span> <span style="color: blue;">INTO</span> <span style="color: teal;">dbo</span><span style="color: grey;">.</span><span style="color: teal;">Cars</span><span style="color: grey;">(</span><span style="color: teal;">CarBrand</span><span style="color: grey;">,</span><span style="color: teal;">ModelName</span><span style="color: grey;">,</span><span style="color: teal;">TypName</span><span style="color: grey;">,</span></li>
<li style="background: #f3f3f3;"> <span style="color: teal;">Engine</span><span style="color: grey;">,</span> <span style="color: teal;">
FuelType</span><span style="color: grey;">,</span> <span style="color: teal;">CarVersion</span>
<span style="color: grey;">,</span><span style="color: teal;">BasePrince</span><span style="color: grey;">)</span></li>
<li> <span style="color: blue;">SELECT</span> <span style="color: grey;">*</span> <span style="color: blue;">FROM</span> <span style="color: blue;">
OPENXML</span><span style="color: grey;">(</span><span style="color: teal;">@handle</span><span style="color: grey;">,</span> <span style="color: red;">'Car/Model/Type/EngineType'</span><span style="color: grey;">)</span></li>
<li style="background: #f3f3f3;"> <span style="color: blue;">WITH </span><span style="color: grey;">(</span><span style="color: teal;">CarBrand</span> <span style="color: blue;">varchar</span><span style="color: grey;">(</span>50<span style="color: grey;">)</span>
<span style="color: red;">'../../../@Brand'</span><span style="color: grey;">,</span>
<span style="color: green;">--three nodes up</span></li>
<li> <span style="color: teal;">Model </span><span style="color: blue;">varchar</span><span style="color: grey;">(</span>50<span style="color: grey;">)</span>
<span style="color: red;">'../../@Name'</span><span style="color: grey;">,</span>
<span style="color: green;">--two nodes up</span></li>
<li style="background: #f3f3f3;"> <span style="color: teal;">TypeName</span> <span style="color: blue;">varchar</span><span style="color: grey;">(</span>50<span style="color: grey;">)</span> <span style="color: red;">
'../@TypeName'</span><span style="color: grey;">,</span> <span style="color: green;">
--one node up</span></li>
<li> <span style="color: teal;">Engine</span> <span style="color: blue;">float</span> <span style="color: red;">'@Vol'</span><span style="color: grey;">,</span> <span style="color: green;">
--current node attribute</span></li>
<li style="background: #f3f3f3;"> <span style="color: teal;">Fuel</span> <span style="color: blue;">nvarchar</span><span style="color: grey;">(</span>10<span style="color: grey;">)</span><span style="color: red;">'@Fuel'</span><span style="color: grey;">,</span></li>
<li> <span style="color: teal;">CarVersion</span> <span style="color: blue;">nvarchar</span><span style="color: grey;">(</span>50<span style="color: grey;">)</span><span style="color: red;">'@Version'</span><span style="color: grey;">,</span></li>
<li style="background: #f3f3f3;"> <span style="color: teal;">Price</span> <span style="color: blue;">int</span> <span style="color: red;">'@BasePrince'</span><span style="color: grey;">)</span></li>
<li> </li>
<li style="background: #f3f3f3;"> <span style="color: green;">--remove
XML from memory</span></li>
<li> <span style="color: blue;">EXEC</span> <span style="color: blue;">
master</span><span style="color: grey;">.</span><span style="color: teal;">dbo</span><span style="color: grey;">.</span><span style="color: maroon;">sp_xml_removedocument</span><span style="color: blue;"> </span><span style="color: teal;">@handle</span><span style="color: grey;">;</span></li>
<li style="background: #f3f3f3;"><span style="color: blue;">END</span></li>
</ol>
</div>
</div>
<span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"><br /></span><br />
<span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;">
Now lets try our procedure:<br />
</span>
<br />
<span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"><br /></span><br />
<div style="font-family: Consolas, Courier, monospace;">
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">
<span class="Apple-style-span" style="font-size: xx-small;"> </span>EXEC dbo.<span class="Apple-style-span" style="white-space: pre;">ImportCars @t</span></span></div>
<div style="font-family: Consolas, Courier, monospace;">
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">
<span class="Apple-style-span" style="white-space: pre;"> SELECT * FROM dbo.Cars</span></span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="white-space: pre;"><br /></span></span></div>
<span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;">
Thank You.</span> <span class="Apple-style-span" style="font-family: Consolas, Courier, monospace; font-size: xx-small;"></span>Damian Zaparthttp://www.blogger.com/profile/17026397366973677672noreply@blogger.comtag:blogger.com,1999:blog-8522517990291142303.post-25317807032998328132011-10-20T12:23:00.000+01:002013-01-13T00:22:30.877+00:00Log database structure changesIn many application the database structure can be changed by the user ex. CRM or Reporting. In such situation we may want to know such changes was maded. In SQL SERVER 2008 we have a possibility to react when DML (Data Manipulation Language) AND DDL (Data Definition Language) execution occured in out database. So try to log it.<br />
<br />
Firstly we want to Create a single table named 'DatabaseChangesLog':<br />
<br />
<span style="font-family: "Courier New", Courier, monospace;">use model;</span><br />
<span style="font-family: "Courier New", Courier, monospace;">GO</span><br />
<br />
<span style="font-family: "Courier New", Courier, monospace;">CREATE SCHEMA LOGS</span><br />
<span style="font-family: "Courier New", Courier, monospace;">CREATE TABLE DatabaseChangeLogs</span><br />
<span style="font-family: "Courier New", Courier, monospace;">(</span><br />
<span style="font-family: "Courier New", Courier, monospace;"> EventId int Identity Primary Key,</span><br />
<span style="font-family: Courier New;"> EventDate datetime2 Constraint DF_DefaultLogDate DEFAULT(sysdatetime()),</span><br />
<span style="font-family: "Courier New", Courier, monospace;"> EventType nvarchar(100) NOT NULL,</span><br />
<span style="font-family: "Courier New", Courier, monospace;"> UserName nvarchar(1050) NOT NULL,</span><br />
<span style="font-family: "Courier New", Courier, monospace;"> Command nvarchar(max) NOT NULL</span><br />
<span style="font-family: Courier New;"> </span><span style="font-family: "Courier New", Courier, monospace;">)</span><br />
<span style="font-family: "Courier New", Courier, monospace;">GO</span><br />
<br />
Note that we creata this table in model databse. This means that each newly created database will has this table after creation. For existing databases You need to run this script manullay.<br />
<br />
Now when we have <span a="undefined" c="4" class="short_text" id="result_box" lang="en"><span class="hps" closure_uid_rh8yiw="126">appropriate table we can insert record to. We are able to detect each of DML changes using database trigger which is a new feauture in SQL Server 2008. Such trigger may react for more than <span style="font-family: "Courier New", Courier, monospace;">INSERT</span>, <span style="font-family: "Courier New", Courier, monospace;">UPDATE</span> and <span style="font-family: "Courier New", Courier, monospace;">DELETE</span> statments. Whole list of 'events' can be obtained by the executing following query: <span style="font-family: "Courier New", Courier, monospace;">SELECT * FROM sys.trigger_event_types;</span> .</span></span><br />
<br />
<span a="undefined" c="4" class="short_text" lang="en"><span class="hps" closure_uid_rh8yiw="126"><span style="font-family: "Courier New", Courier, monospace;">CREATE TRIGGER StructureLogTrigger<br />ON DATABASE <br />FOR </span><span style="font-family: "Courier New", Courier, monospace;"><strong>DDL_DATABASE_LEVEL_EVENTS </strong>AS</span></span></span><br />
<span a="undefined" c="4" class="short_text" lang="en"><span class="hps" closure_uid_rh8yiw="126"><span style="font-family: "Courier New", Courier, monospace;"> DECLARE @data XML;<br /> SET @data = EVENTDATA();<br /> INSERT LOGS.DatabaseChangeLogs (EventType, UserName , Command )</span></span></span><br />
<span a="undefined" c="4" class="short_text" lang="en"><span class="hps" closure_uid_rh8yiw="126"><span style="font-family: "Courier New", Courier, monospace;">VALUES <br /> (@data.value('(/EVENT_INSTANCE/EventType)[1]', 'nvarchar(100)'),<br /> CONVERT(nvarchar(100), CURRENT_USER),<br /> @data.value('(/EVENT_INSTANCE/TSQLCommand)[1]', 'nvarchar(2000)') ) ;<br />GO</span></span></span><br />
<br />
Now each changes will be logged directly to out table. <br />
Made some changes and take a look.<br />
<br />
<br />
Thanks<br />
<br />
Links:<br />
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/bb510452.aspx">Event types</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/ms189799.aspx">Triggers</a></li>
</ul>
Damian Zaparthttp://www.blogger.com/profile/17026397366973677672noreply@blogger.com