in

Dé specialist in .NET trainingen en consultancy

Roland Guijt

  • Linq to XML strongly typed: meet Linq to XSD

    Linq to XML is a part of Linq I never did like very much. Everything hangs together with loosely typed strings. For example:

      

    var query = from xElem in doc.Descendants("Patient")

    select new Patient { EMail = xElem.Attribute("EMail").Value,

    FirstName = xElem.Element("FirstName").Value,

    LastName = xElem.Element("LastName").Value, };

      

    Meet Linq to XSD. Here you use a XML schema to make your queries strongly typed.

    Linq to XSD is still in beta, you can download it at codeplex.

    There is not yet a clean and mean installer for it. To install, follow the steps posted here.

    Just change one thing in the installation procedure, in step 9, change $(SolutionDir) into the folder where you installed the binaries.

    In my case:

    <LinqToXsdBinDir Condition="'$(LinqToXsdBinDir)' == ''">c:\LINQTOXSDBIN\</LinqToXsdBinDir>

      

    imageNow, just create an XML file and make a schema for it by using the Visual Studio “Create xml schema” button and

    tweak it a bit. If you, like me do not know the syntax by heart, look here.

    Once you have your schema, you can use an existing one too of course, place it inside the project mentioned in

    the installation guide.

    Be sure to include a “targetNamespace” in your schema:

    <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.oosterkamp.nl/conversionconfiguration">

      

    Select the xsd file in the project en go to the properties pane. Set the build action to “LinqtoXsdSchema”.

    Now, build your project.

      

    There is a new namespace available now. It has the name of the uri specified as targetNamespace,

    but without the http:// prefix and the slashes are dots.

    In my case the namespace is www.oosterkamp.nl.conversionconfiguration .

    Ok, maybe this is not the nices feature of Linq to XSD.

      

    Inside the namespace is a class. It’s name is the name of your root node. It has a static method called Load, that get’s you to load a xml file.

    The file has to validate with the schema.

    using www.oosterkamp.nl.conversionconfiguration;

    ..

    ConversionConfiguration xmlData = ConversionConfiguration.Load("ConversionConfiguration.xml");

      

    Now the Linq party can really begin, because everything is strongly typed now. And if you’re used to Linq to SQL or Linq to Entities,

    this works exactly the same, even updating and inserting data!

      

    var repositories = from repository in xmlData.Repositories.Repository

                       select repository.name;

      

     

    Here’s my full xsd:

    <?xml version="1.0" encoding="utf-8"?>

    <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.oosterkamp.nl/conversionconfiguration">

      <xs:element name="ConversionConfiguration">

        <xs:complexType>

          <xs:sequence>

            <xs:element name="Repositories">

              <xs:complexType>

                <xs:sequence>

                  <xs:element maxOccurs="unbounded" name="Repository">

                    <xs:complexType>

                      <xs:attribute name="name" type="xs:string" use="required" />

                      <xs:attribute name="invariantProviderName" type="xs:string" use="required" />

                      <xs:attribute name="connectionString" type="xs:string" use="required" />

                    </xs:complexType>

                  </xs:element>

                </xs:sequence>

              </xs:complexType>

            </xs:element>

            <xs:element name="Conversions">

              <xs:complexType>

                <xs:sequence>

                  <xs:element maxOccurs="unbounded" name="Conversion">

                    <xs:complexType>

                      <xs:sequence>

                        <xs:element name="LastTimeStampProcessed" type="xs:dateTime" />

                      </xs:sequence>

                      <xs:attribute name="repositoryAName" type="xs:string" use="required" />

                      <xs:attribute name="respositoryBName" type="xs:string" use="required" />

                      <xs:attribute name="tableNameFromRepositoryA" type="xs:string" use="required" />

                      <xs:attribute name="tableNameFromRepositoryB" type="xs:string" use="required" />

                      <xs:attribute name="fieldNameFromRepositoryA" type="xs:string" use="required" />

                      <xs:attribute name="fieldNameFromRepositoryB" type="xs:string" use="required" />

                      <xs:attribute name="direction" use="required">

                        <xs:simpleType>

                          <xs:restriction base ="xs:string">

                            <xs:enumeration value ="fromAtoB"/>

                            <xs:enumeration value ="bidirectional"/>

                          </xs:restriction>

                        </xs:simpleType>

                      </xs:attribute>

                    </xs:complexType>

                  </xs:element>

                </xs:sequence>

              </xs:complexType>

            </xs:element>

          </xs:sequence>

        </xs:complexType>

      </xs:element>

    </xs:schema>

      

    Here’s my full xml file:

      

    <?xml version="1.0" encoding="utf-8" ?>

    <ConversionConfiguration>

      <Repositories>

        <Repository name="Access" invariantProviderName="dfdf" connectionString="sdfsdf"></Repository>

        <Repository name="SQL" invariantProviderName="dfdf" connectionString="sdfsdf"></Repository>

      </Repositories>

      <Conversions>

        <Conversion repositoryAName="Access" respositoryBName="SQL" tableNameFromRepositoryA="Customers" tableNameFromRepositoryB="Customer" fieldNameFromRepositoryA="Address"

                    fieldNameFromRepositoryB="Adres" direction="fromAtoB">

          <LastTimeStampProcessed>"2010/01/01"</LastTimeStampProcessed>

        </Conversion>

        <Conversion repositoryAName="Access" respositoryBName="SQL" tableNameFromRepositoryA="Orders" tableNameFromRepositoryB="order" fieldNameFromRepositoryA="naampje"

                fieldNameFromRepositoryB="naam" direction="bidirectional">

          <LastTimeStampProcessed>"2010/01/01"</LastTimeStampProcessed>     

        </Conversion>             

      </Conversions>

    </ConversionConfiguration>

     
  • Team Foundation Server (TFS) 2010 installation experience

    Having installed TFS 2008, the installation of TFS 2010 is a breeze!

    The problem with the installation of TFS 2008 was, that the security system was very complicated. So complicated that I ended up installing TFS as well as the databases of TFS unwillingly on the same machine. And even that took me days to get it right.

    Now, TFS 2010 has installation wizards. If you want everything (TFS, DBs, Sharepoint integration and Reporting Services integration) on the same machine, choose the standard wizard. Just let TFS know which user account it should use and you’re on your way.

    If, like me, you want your DBs on a DB server, choose the advanced wizard. Make sure the user you are logged in with has admin rights on the SQL server 2008 (yes, 2008 is required for TFS 2010) machine. You’ll probably need a domain account for that. Although this wizard is for “advanced” users it was a breeze in comparison with TFS 2008 installation.

  • Updating an entity with related entities in MVC2 and Entity Framework

    I’ve been working on a way for our website to easily create and update trainings by our employees. The website is using MVC2 with the entity framework.

    Each training entity consists of scalar data and a related entity (foreign key relationship in the db) called MaterialObject, which is the material needed for the training.

    My ViewData class looks like this:

     

        public class TrainingEditViewData

        {

            public IEnumerable<SelectListItem> MaterialList { get; set; }

            public Training Training { get; set; }

        }

    The MaterialList collection is the feed for a dropdown list I’m using in my view to select the material. Now my controller as a method to fill the model and to view the view:

        public ActionResult EditTraining(int id)

        {

            TrainingEditViewData data = new TrainingEditViewData();

            data.Training = Adapters.Training.GetByID(id);

            data.MaterialList = GetMaterialSelectList();

            return View(data);

        }

    When the form is posted, this method is called:

        [HttpPost]

        //This attribute is needed to prevent an exception about html data originating from the form

        [ValidateInput(false)]

        public ActionResult EditTraining(TrainingEditViewData viewData)

        {

            Training training = Adapters.Training.GetByID(viewData.Training.ID);

            Adapters.Context.ApplyCurrentValues<Training>(training.EntityKey.EntitySetName, viewData.Training);

            training.MaterialObject = Adapters.Material.GetByID(viewData.Training.MaterialObject.ID);

            Adapters.Training.Save();

            return this.TrainingList();

        }

    In MVC, the viewdata object is reconstructed from the data entered in the form. As this is a new object, it is not available in the context. So you could add it to the context. In this case, I don’t want that, the training does already exist.

    So I just use the reconstructed data to retrieve the entity in the context, in this case by using our repository, which just does a linq query for the id specified. The next line is new in EF 4. It takes an object not available in the context and maps the scalar data to the existing object in the context. But it’s just the scalar data, I also need my related entity to be updated, in this case MaterialObject. So I just retrieve that from the context too before I save the whole training.

    The view must reference all data that is to be reconstructed in the viewdata. Even if you don’t have a UI for a certain part of the data, you can easily include a hidden field for it. For example:

    <%: Html.HiddenFor(model => model.Training.ID) %> 

  • Security in WCF: TransportWithMessageCredential

    This week, I needed to create a client for a webservice created in Java. The webservice has implemented username/password security (in the WS security header) AND a certificate.

    So, in my ignorance, I configured the following binding:

    <basicHttpBinding>
      <binding configurationName="SWMExtendedBasicHttpBinding">
        <security mode="TransportWithMessageCredential">
          <transport clientCredentialType = “Certificate”>
          <message clientCredentialType ="UserName" />
        <security>
      </binding>
    </basicHttpBinding>

    And I configured a certificate in a behavior (for the eventual endpoint).

    Turns out that Transport security with WCF just means the secure transport for the binding itself, it this case https, with just the SSL certificate installed on the web server. If you configure Transport security, WCF won’t accept a non-encrypted channel. That’s it.

    So my line <transport clientCredentialType = “Certificate”> is superfluous. My assumption was that the configured certificate in the behavior was taken to do the transport security.

    The conclusion was that I needed certifcate AND username/password security on the message level. The standard BasicHttpBinding can’t handle that.

    So I created my own custom binding in code with all the properties of the basicHttpBinding:

    BasicHttpBinding bbinding = new BasicHttpBinding(BasicHttpSecurityMode.TransportWithMessageCredential);
    BindingElementCollection bec = bbinding.CreateBindingElements();
    TransportSecurityBindingElement tsp = bec.Find<TransportSecurityBindingElement>();
    HttpsTransportBindingElement httpsBinding = bec.Find<HttpsTransportBindingElement>();
    TextMessageEncodingBindingElement encoding = bec.Find<TextMessageEncodingBindingElement>();
    httpsBinding.RequireClientCertificate = true;

    CustomBinding binding = new CustomBinding(tsp, encoding, httpsBinding);

    Notice the RequireClientCertificate property.

    Next: create endpoint, get the certificate from the store and provide credentials to the proxy object, generated from the WSDL:

    EndpointAddress endpoint = new EndpointAddress("https://someurl.com/service");

    X509Store store = new X509Store(StoreLocation.CurrentUser);
    store.Open(OpenFlags.ReadOnly);

    X509Certificate2Collection certCollection = store.Certificates.Find(X509FindType.FindBySubjectName, "CertName", false);

    Client proxy = new Client(binding, endpoint);

    proxy.ClientCredentials.UserName.UserName = "UserName";
    proxy.ClientCredentials.UserName.Password = "Password";
    if (certCollection.Count > 0)
        proxy.ClientCredentials.ClientCertificate.Certificate = certCollection[0];

    This will generate an exception when the certificate is not assigned, because of the RequireClientCertificate setting above.

  • WPF above the polar circle

    300px-World_map_with_polar_circles.svg Microsoft, heads up. They even know WPF above the polar circle now.

    For a while now, we have a customer in Norway. So my colleagues and I are travelling around the country. For me, it’s my first time in the country and in Scandinavia. So far I’m baffled by the scenery. I’m in Bodø now. I’ve never been so far up and for Oosterkamp It’s the first course above the polar circle.

    The funny thing with scenery is that the people in Norway can’t understand that I am staring at a snow covered mountaintop. After a while, they even coming toward you, asking if everything is OK :-)

    The town I’m in now is cold and dark this time of year. Just as the midnight sun is up in summer, the opposite is happening in winter. It’s going to be a bit worse, but it’s “light” for about 4 hours now.

    The icy streets are also exciting if you’re not used to it. While the Norwegians walk like normal, I couldn’t manage to cross the street at first.

    All and all it’s better to stay in my comfy hotel room at nights, catching up on mail, youtube, blogging, editing some websites and preparing some demos for the course. Tomorrow evening is my flight back to Oslo and the next morning back to good old, flat, Holland.

    A video with a view from the building I gave training in is here.

  • Hosting a WCF service in IIS 7

    I just spent a day figuring out how to do this. Here are the steps I took:

    1. Install Windows 2008 with web role.
    2. Install Windows updates
    3. In the .NET Framework 3.0 features screen. (Config panel –> Programs and Features –> Turn Windows Components on or off) make sure both HTTP Activation and non-HTTP activation is enabled. By default this is off!
    4. Run this to register WCF with IIS: "%windir%\Microsoft.NET\Framework\v3.0\Windows Communication
      Foundation\ServiceModelReg.exe" -r –y
    5. Add a new application pool in IIS
    6. Be sure the application pool runs with a fixed user. e.g. network services.
    7. Create a directory somewhere with a bin directory inside. Put web.config and a valid svc file in the root of this directory and the service’s dll in the bin directory.
    8. Make sure the user you assigned to the application pool has all rights in this dir, including the bin subdir.
    9. Under IIS, create a new website, with runs with the made application pool and maps to the root of the made dir.
    10. In the configuration of the website, be sure the allowed protocols AND the enabled protocols match the protocols of your endpoints. Use a comma separated list if you have more than one protocol.

    Voilla.. now hit the service with something.

  • IBM DB2 .NET Provider not listed in Visual Studio 2008 dialogs

    If you downloaded the IBM DB2 .NET Provider and installed it, the provider won't show up in the dialog boxes of e.g. Server Explorer.

    To fix this, see this page:

    http://tinyurl.com/meugx7

  • OPC Server: error 8000401a

    I'm working on a WCF service that communicates with OPC Server, A COM application that coordinates PLCs on the work floor. Schneider supplies a COM library for that.

    As a host, we use a console application to test, because it's easier to debug. In production we use a Windows service application. The fenomenon that occured was that only with the use on the Windows service, the WCF service wouldn't start and produced the following error:

    Schneider Opc Server Unable to connect to the OPC server. Retrieving the COM class factory for remote component with CLSID {E7675090-9FF9-11D1-AC46-0060978ADD48} from machine 172.18.0.203 failed due to the following error: 8000401a

    8000401a is a COM security error, as it turns out after some searching.

    OPC server has a seperate layer of security. The solution to this problem was to configure it to accept calls from services. The trick was to keep all these layers of security seperated :-) :

    • Windows security for the service (under which account does it run?)
    • COM security (run the dcomcnfg tool)
    • WCF security (transport and message security, configurable in the *.config file)
    • OPC server security
  • DotNetNuke developer? Use these modules.

    A note in advance: I'm in no way commercially involved with the product I'm mentioning here.

    If you're working with DotNetNuke, some key functionality is missing. The possibility to create custom forms, a custom registration page, a good newsletter system and a skin that you can modify on the site itself are things that I've been yearning for.

    Recently, I bought the module value package from Data Springs. It contains 23 modules. In the package is a module called "dynamic forms". This very flexible module allows you to create custom forms with a great deal of fieldtypes. When you have designed your form (all from the web interface) you can add events that fire when the user submits. E.g. send yourself and the subscriber a mail, add the user to a role etc. It's also possible to create question events, that give you the possibility to relate a question to another question. E.g. show certain fields only when a checkbox is on.

    Dynamic registration is very similar, but it's intended use is for the registration page your users see when they register on your site. Where DNN is not flexible at all, this module solves this.

    Opt in email is a very good mailing list manager to opt in/out your subscriber, design newsletters and create campaigns, where you can send subscriber a mail some time after they subscribed and then some time after that mail is sent etc. It also supports scheduling, tracking (see which users looked at your newsletter) and it can detect bounces.

    If you want a flexible skin, where you can choose from a wide variety of designs as well as tailor the colors of all elements on the fly, look at Flex2 from DrNuke. It features a nifty module that changes every color you have on the skin instantly on screen. So guessing colors is over, just fiddle until it looks good.

    With these products, I can create most of a standard site just by configuring. That leaves custom development to do some really interesting stuff.

  • Free Telerik WPF controls

    Telerik, a leading vendor of .NET UI components and tools, has a special offer for all active MSDN subscribers !! A free Developer License for RadControls for WPF ($799 value), with community support only. This license gives you access to all of the Telerik WPF controls for use in unlimited personal or commercial projects. Take advantage of the offer and enjoy a powerful WPF grid, scheduler, animated 3D charts and gauges, and everything you need to build rich and visually stunning WPF line-of-business applications. The offer is valid through July 31st, 2009. To claim your free license, log-in to your MSDN Subscriber account and look for the “Exclusive Deal from Telerik” on the MSDN “Special Offers” tab.
    Posted jun 10 2009, 06:21 by Roland with no comments
    Filed under: ,
  • Upgrading to .NET 3.5 with DotNetNuke

    If you're using DotNetNuke 4.0+ and are developing modules using .NET 3.5 (using Linq for instance), there are significant changes needed in the web.config to get your module running. You can use Visual Studio to do that automagically for you, however, that only works on a developers machine, not a staging or production server.

    Solution: use a module that does the trick for you: LinqPrep.

    DotNetNuke 5+ doesn't need this fix, because it has a setting for it. However, at the time of this writing, this version is not yet production capable.

  • The new ASP.NET 3.5 ListView

    I've been working on a DotNetNuke module the last couple of weeks. More details on that soon. In this project I used the new ASP.NET 3.5 ListView control.

    If you are using the DataList control or Repeater control right now, I can recommended ListView wholeheartedly. The DataList works fine for selecting data from any DataSource, but it doesn't support updating/inserting/deleting data. That's just code you have to do yourself by handling events. That was very troublesome for me, working with a LinqDataSource.

    The ListView can be seen as the DataList 2.0, or the DataList as it should be. It supports updates, deletes and inserts and has a great template system. This template system works somewhat different than what I was used to. Here goes.

    image

    The smarttag of the ListView shows a couple of more templates than the DataList. But, a few templates that are important are missing. They are the LayoutTemplate and the GroupTemplate. These are created when you click on "Configure ListView". Here, you can choose a layout (Grid, Tiled, List, Flow, Single Row) that determines the contents of the missing templates.

     

    But... of course, I want to tweak these. Understanding these two templates is also vital to create markup that actually works in the other templates. My experience is that the template designer of ListView works, sometimes. If there is one itty bitty thingy wrong with your markup, the designer will blank completely.. just like that, no error or anything. So I created the templates by editing the markup directly in the "source" view.

                    <LayoutTemplate>

                        <table ID="groupPlaceholderContainer" runat="server" border="0">

                            <tr ID="groupPlaceholder" runat="server">

                            </tr>

                        </table>

                    </LayoutTemplate>

     

    The LayoutTemplate is the basis for the rest of the templates. In this example it renders a table with a row that has the groupPlaceholder. This renders the GroupTemplate, which is optional. Don't forget to set the right ID of the groupPlaceHolder in the property of the ListView! Also, the entire tr that acts as a placeholder is NOT rendered! It is completely replaced by, in this case, the GroupTemplate. The grouptemplate is rendered as many times per row as the integer value in the GroupItemCount property in the ListView.

     

    The GroupTemplate might look as follows:

     

            <GroupTemplate>

              <tr ID="itemPlaceholderContainer" runat="server">

                <td ID="itemPlaceholder" runat="server">

                </td>

              </tr>

            </GroupTemplate>

     

    Again, itemPlaceholder is the ID set in a property of ListView and the entire td is not rendered.

    So, all you have to do now is create an itemtemplate, which in this example, has td tags for the tr tags in the GroupTemplate.

     

    Also, don't forget the other templates of the screenshot. They are all optional and use the same Layout and GroupTemplate. Besides that, they work like the templates in every other templated control.

     

     

     

  • Hardware talk: New server

    Our old server, a Xeon single core system is still doing it's duty at the moment. On this server we're running VMWare Server, a hypervisor (piece of software used to run virtual machines) that runs 4 virtual machines for various purposes.

    Now, VMWare has an exciting new product called ESXi. A free (!) hypervisor that runs as an OS. While GSX needs an OS to run on (Windows 2003 at the moment), ESXi is a very lightweight, linux based OS on it's own.

    ESXi could run on our old server, so my first plan was to replace the HDs (which run for 4 years now) for 1 TB versions.

    But, I had another problem. The "old" Xeon doesn't support hardware virtualisation. As a result, 64 bit virtual machines are not possible. And we need that to run Exchange.

    After some consideration, we decided to buy a new server. The costs of a good server are considerable, but can be cut dramatically if you build the system yourself. So, I did that.

    Intel has several "barebone" servers and we have a good experience with them, because our old server is build with one too. We decided on buying a SR1500 with a Quad Core Xeon, 16 GB of RAM and 2 x 1 TB hot swapable HD, which will be configured in Raid 0 configuration.

    When I received the stuff and started to build it, I was pleasantly surpised. Building such a system is easier than putting an Ikea table together these days. With our old server, I remember struggling with cables, but with the new one, all cabling is in place. With an Ikea like sheet, you just put all components in. Also, the screwing is reduced to a minimum.

    So: here it is, still needing software installation. Soon, our website will run faster than ever!

    P1000348 P1000349

  • Delphi: RAD Studio 2009 (NL)

    Het Delphi produkt beleeft al een tijdje een onrustige periode. De originele uitgever van Delphi, Borland, heeft Delphi een aantal jaar geleden in de etalage gezet en richt zich verder op Application Lifecycle Management (ALM) oplossingen. Een tijd lang was er geen koper en Borland heeft zolang een zuster bedrijf opgezet: Codegear. Inmiddels is Codegear verkocht aan Embarcadero en zij hebben een veelbelovend produkt uitgebracht: RAD Studio 2009.

    Wat zit er in de doos?

    - Delphi 2009. De nieuwe versie van de good old Delphi. Ontwikkelen dus voor het Win32 platform maar nu met Unicode en nieuwe Delphi syntax. Daarnaast een update van de VCL met onder meer een Office 2007 ribbon. Er is ook gewerkt aan een update van DataSnap, waarbij de focus ligt op een niet-COM omgeving (yeah!) en ultra-thin client development.

    - C++ Builder 2009: Niet mijn kopje thee, maar dezelfde soort update als Delphi heeft ondergaan.

    - Delphi Prism 2009: De nieuwe versie van Delphi voor .NET, waarbij ook Mono (.NET voor Linux en MAC) niet wordt vergeten. De compiler die gebruikt wordt komt niet uit de Codegear stal, maar is gemaakt door RemObjects, een oude bekende in Delphi land, en heet Oxygene. Er is support voor het nieuwste 3.5 framework met daarin WinForms, ASP.NET, WPF (yeah!) en er is ook LINQ support. De IDE is gebaseerd op Visual Studio.

    Al met al is RAD Studio 2009 een indrukwekkend produkt geworden, waarbij de ondersteuning voor .NET 3.5 met WPF mij het meest in het oog springt. De overname door Embarcadero maakt de toekomst erg rooskleurig. Als Delphi ontwikkelaar van oudsher maakt dit me gelukkig. Wij zijn (opnieuw) enthousiast over Delphi en zien uit naar een goede samenwerking met Embarcadero en hun vertegenwoordigers bij Barnsten.

  • Bits and Bytes with marshalling

    Today I worked on a project I do with PLCs. Many of the datatypes in the PLC world are not the same as .NET types. The float is 16 bits for example.

    The customer had some unsafe code implemented where unsafe operators were used to manipulate the bits to get the desired conversion. As a result we occassionally got the access violation exception, indicating unallocated, unsafe, memory is written.

    There is a much easier and safe way to do this type of conversions using the BitConverter class. The class has overloaded methods to convert all standard .NET types to a byte array. And also, it has methods to convert byte arrays to .NET types.

    In practice, when you do any kind of marshalling, just 'capture' the non .NET type in a .NET equavalent and use the BitConverter class.

    In addition, many explicit conversion operators are overloaded in .NET types. For example, you can cast an Int16 into a Int32 without any trouble.

More Posts Next page »