domenica 2 dicembre 2012

Visual Studio 2012 Update 1

It's now possible download Update 1 for VS 2012. Most of the new functionality appears in Ultimate and Premium and primarily spans these four areas: 

  • Windows development 
  • SharePoint development 
  • Agile teams 
  • Continuous quality
More info here:
http://www.microsoft.com/visualstudio/ita/visual-studio-update#story-update-1
 

mercoledì 1 agosto 2012

WCF Data Service and Knockoutjs

One of the strengths of modern websites is the use of client side technologies.In fact there are several libraries that can help us develop our work and are among the most popular jQuery.
Using these libraries we can more easily interact with the DOM (Document Object Model) than using the traditional JavaScript functions.
Furthermore, the ajax functions are much simpler to implement.

With jQuery, you can do many things, but not all ... or you can do them but some become very complex, such as dynamically create an html select tag.
Here a very basic example with jQuery:

//a simple continents array
someContinents = { "1": "EUROPE", "2": "AMERICA", "3": "ASIA", "4": "AFRICA" };

$.each(someContinents, function (k, v) {
        $('select#selContinents').append($("").attr("value", k).text(v));
});


With a foreach jQuery function ($.each) we can iterate all elements (continents). Every iteration append an "option" html tag (with key and value) to html select tag. This is a very very simple example. Your data can come from several sources (webservice, array...). 
Now introduce another way to populate a combo box, using less JavaScript code and a very powerful library: Knockout. It does not replace jQuery, but we can say that it can be an integration.
But we go one step at a time…
First, we create a sample table on a MS SQL database called “T_STATE” with two columns: id and description. Then populate it with some data like these:







Data table












This will be out data source. Now create a new ASP.NET application (or a MVC, one or the other is indifferent).
Add a new  ADO.NET Entity Data Model and add the previous database table to its designer. That’s result:

Entity


I saved my Entity Container Name as “DbTestEntities”. Normally, I prefer to create a new libray project and create a new ADO.NET Entity Model inside it, so I can reuse it in other applications. Remember our saved name because it will serve for the next step: WCF data service.
Now we see how to interact with data stored on a database and client-side components. I decided to use the DataService because they are easy to implement, and through the OData protocol can be queried directly from the URL when calling the service. Of course you can also use other traditional REST webservices, but in this example we’ll use a WCF Data Service.
On Visual Studio 2010 project, add a new WCF Data Service. A new *.svc file will be created on our project. I saved it as “WcfDS.svc” Open this file and modify class code with parameters previous created in our entity model designer:

public class WcfDS : DataService<DbTestEntities>
    {

        public static void InitializeService(DataServiceConfiguration config)
        {

            config.SetEntitySetAccessRule("T_STATE", EntitySetRights.AllRead);
            config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
        }
    }

It’s important that DataService base class is of the type described on the entity container name. Remember, my previous name was “DbTestEntities”, so base class will be DataService.
The other step is to set entity set access rule:
config.SetEntitySetAccessRule("T_STATE", EntitySetRights.AllRead);

First parameter will be the exact entity name (in my example it’s T_STATE) and right “AllRead”. These settings permit a read only permission in the table.
Press F5 to debug our project, navigate to our WCF Data Service Page (ex http://localhost:1340/WcfDS.svc/) and you can see something like this (it depend on used browser):


<service xml:base="http://localhost:1340/WcfDS.svc/"><workspace><atom:title>Default</atom:title><collection href="T_STATE"><atom:title>T_STATE</atom:title></collection></workspace></service>

Right! Now try to read T_STATE entity data through browser url http://localhost:1340/WcfDS.svc/T_STATE and result source data will be something like this:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<feed xml:base="http://localhost:1340/WcfDS.svc/" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
  <title type="text">T_STATE</title>
  <id>http://localhost:1340/WcfDS.svc/T_STATE</id>
  <updated>2012-07-31T20:29:12Z</updated>
  <link rel="self" title="T_STATE" href="T_STATE" />
  <entry>
    <id>http://localhost:1340/WcfDS.svc/T_STATE(1)</id>
    <title type="text"></title>
    <updated>2012-07-31T20:29:12Z</updated>
    <author>
      <name />
    </author>
    <link rel="edit" title="T_STATE" href="T_STATE(1)" />
    <category term="DbTestModelNs.T_STATE" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
    <content type="application/xml">
      <m:properties>
        <d:id m:type="Edm.Int32">1</d:id>
        <d:State>ITALY</d:State>
      </m:properties>
    </content>
  </entry>
  <entry>
    <id>http://localhost:1340/WcfDS.svc/T_STATE(2)</id>
    <title type="text"></title>
    <updated>2012-07-31T20:29:12Z</updated>
    <author>
      <name />
    </author>
    <link rel="edit" title="T_STATE" href="T_STATE(2)" />
    <category term="DbTestModelNs.T_STATE" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
    <content type="application/xml">
      <m:properties>
        <d:id m:type="Edm.Int32">2</d:id>
        <d:State>USA</d:State>
      </m:properties>
    </content>
  </entry>
  <entry>
    <id>http://localhost:1340/WcfDS.svc/T_STATE(3)</id>
    <title type="text"></title>
    <updated>2012-07-31T20:29:12Z</updated>
    <author>
      <name />
    </author>
    <link rel="edit" title="T_STATE" href="T_STATE(3)" />
    <category term="DbTestModelNs.T_STATE" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
    <content type="application/xml">
      <m:properties>
        <d:id m:type="Edm.Int32">3</d:id>
        <d:State>GERMANY</d:State>
      </m:properties>
    </content>
  </entry>
  <entry>
    <id>http://localhost:1340/WcfDS.svc/T_STATE(4)</id>
    <title type="text"></title>
    <updated>2012-07-31T20:29:12Z</updated>
    <author>
      <name />
    </author>
    <link rel="edit" title="T_STATE" href="T_STATE(4)" />
    <category term="DbTestModelNs.T_STATE" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
    <content type="application/xml">
      <m:properties>
        <d:id m:type="Edm.Int32">4</d:id>
        <d:State>GREECE</d:State>
      </m:properties>
    </content>
  </entry>
  <entry>
    <id>http://localhost:1340/WcfDS.svc/T_STATE(5)</id>
    <title type="text"></title>
    <updated>2012-07-31T20:29:12Z</updated>
    <author>
      <name />
    </author>
    <link rel="edit" title="T_STATE" href="T_STATE(5)" />
    <category term="DbTestModelNs.T_STATE" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
    <content type="application/xml">
      <m:properties>
        <d:id m:type="Edm.Int32">5</d:id>
        <d:State>FRANCE</d:State>
      </m:properties>
    </content>
  </entry>
</feed> 

You can get detailed information on this site OData protocol: http://www.odata.org/
If this is ok, we can proceed with the most interesting argument: how to read and use these data in a drop down list created by
To do this, we need to download jQuery library and Knockout. We can found them here:


Then, as other library we need to reference these libraries in the html head tag. Suppose our path is in the script website directory, code will be following (in the example I use MVC 3 and Url helper):

<script src="@Url.Content("~/Scripts/jquery-1.7.2.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/knockout-2.1.0.js")" type="text/javascript"></script>

We note that before we create a reference to the jQuery library, then Knockout. In this way we can ensure that any jQuery functions can be called and recognized with Knockuot. Now we can create JavaScript code to retrieve data and populate our drop down list (html select tag).

First we need to declare a class that represents our data. In this case, we need two fields: id and state name:

function StateDef(data) {
this.id = ko.observable(data.id);
this.State = ko.observable(data.State);
}

Data parameter represent single data read from webservice. Now create a new ViewModel JavaScript function and bind it into Knockout library:

function StatesViewModel() {

}

ko.applyBindings(new StatesViewModel());


Here StatesViewModel code:

function StatesViewModel() {
        var self = this;
        self.states = ko.observableArray([]);
        self.selectedState = ko.observable();

        $.getJSON("../../WcfDS.svc/T_STATE", function (res) {
            var mappedStates = $.map(res.d, function (item) { return new StateDef(item) });
            self.states(mappedStates);
        })
        .error(function (err) { alert(err.responseText); });

} //end ViewModel

We create a new states variable and initialize it with an obserbableArray. The, with jQuery getJSON function we read all States data through WCF Data Service.
Note two things inside $.getJSON function: we use a $.map function to retrieve datas and “translate” them in the object we want, in this case transform them in our State definition (with StateDef function). Second thing is res.d variable. It represents data collection read from data  service, so “item” is a single state object.
All of our mapped data will become our array of data to pass to select html control.
That’s complete JavaScript code:

<script type="text/javascript">

    function StateDef(data) {
        this.id = ko.observable(data.id);
        this.State = ko.observable(data.State);
    }

    // Overall viewmodel for this screen, along with initial state
    function StatesViewModel() {
        var self = this;
        self.states = ko.observableArray([]);
        self.selectedState = ko.observable();

        $.getJSON("../../WcfDS.svc/T_STATE", function (res) {
            var mappedStates = $.map(res.d, function (item) { return new StateDef(item) });
            self.states(mappedStates);
        })
        .error(function (err) { alert(err.responseText); });

    } //end ViewModel

    ko.applyBindings(new StatesViewModel());   

</script>

Last part consists of create our html select tag and bind it with Knockout data:

<select data-bind="options: states, value: selectedState, optionsText: 'State'"></select>

With “option” tag we connect previous states array. “value” is our selected item and “optionsText” represent our State description.
In follow example I explain another kind to create a html select tag connected to Knockout data:

<select data-bind="foreach: states">
        <option data-bind="text: State, value: id"></option>
</select>

In this example, I used a foreach iteration on states array. Then I create a single html option tag and bind it with id and State data.
If we want to show select tag only if there are elements, we can add another parameter to data-bind select:

<select data-bind="foreach: states, visible: states().length > 0">
        <option data-bind="text: State, value: id"></option>
</select>

“Visible” in this case will be true only if exists at least one item in states array.
If you want to extend the use of Knockout and see all the potential, potetre go on the official website: http://knockoutjs.com/

martedì 7 febbraio 2012

Ignore inline DTD in XML file with LINQ to XML

If we want to read an XML file with LINQ to XML that have DTD inline instructions, normally we use this statement

    XDocument doc = XDocument.Load("myXmlFile.xml");

but... we'll receive an exception.

The Load method of the XDocument has several overloads, including one in particular that takes as a parameter an XmlReader object.
Let's see how to use it:

  XmlReaderSettings settings = new XmlReaderSettings();
  settings.DtdProcessing = DtdProcessing.Ignore;
  XmlReader reader = XmlReader.Create("myFile.xml", settings);
  XDocument doc = XDocument.Load(reader,   LoadOptions.PreserveWhitespace);

First, create a XmlReaderSettings object and set its DtdProcessing property to "Ignore". It causes the DOCTYPE element to be ignored.
Then, create a new XmlReader object using the file path name and XmlReader previously created settings.
Now we can open without previous exception out xml file, passing XmlReader object as argument of XDocument Load method.

lunedì 16 gennaio 2012

EntityDataSource and isolation level.

Suppose we have a asp.net page and display some data from a database table in a GridView. The latter is connected to EntityDataSource.
If we are running a long elaboration on that table (as an update or other processing), the page containing the data to show cannot hang and display our data until processing is finished.
That's not ever that we want....

Probably this behavior is not what we want. How can we solve it?

Using EntityDataSource ContextCreated event we can "attach" a transaction to the ObjectContext used by datasource.

protected void MyEntityDataSource_ContextCreated(object sender, EntityDataSourceContextCreatedEventArgs e) {
        e.Context.Connection.Open();
        e.Context.Connection.BeginTransaction(IsolationLevel.ReadUncommitted);
}

First we have to manually open the database connection. Then, start a database transaction specifying the isolation level we want to use. In this case, we need "ReadUncommitted" so we can read all data from database, including those not yet committed (dirty).