Welcome to MSDN Blogs Sign in | Join | Help

Microsoft Dynamics Mobile Team blog


News and goodies direct to you from the product team!
How to code your own barcode enabled tasklets (Motorola and Intermec devices)

This is an installment of Barcode Scanning With Microsoft Dynamics Mobile series.

This article is targeted at developers who want to start using the barcode scanner capabilities of Microsoft Dynamics Mobile 1.5 framework. It supports Motorola (formerly Symbol) and Intermec devices. After you have read this article and followed its tutorial part you will be able to implement your own tasklets with barcode scanning capabilities. It might seem a long way on first glance but once done you will realize that the heart of the functionality is doable in just a few steps.

Barcode Scanner Sample Barcode Scanner Demo Tasklet

The following tutorial describes all steps necessary to create a simple Rolepad based application which enables barcode scanning on Motorola (Symbol) and Intermec devices. The process is the same for both device classes – there are only two differences: The first one is proprietary .NET CF scanning assemblies which you must download and reference within your project and the second one is the corresponding section in the App.config file. Tutorial is written for Symbol, differences are highlighted for Intermec.

  1. Prerequisites: Microsoft Visual Studio 2008 SP1 (Professional edition or above), Microsoft Dynamics Mobile – Device Components with Device SDK feature installed
  2. We are going to create one VS solution with two projects based on Microsoft Dynamics Mobile 1.5 platform. The main purpose of the Rolepad project called BarcodeScannerSample15 is an easy deployment of all necessary binaries configuration files. The barcode scanning logic is being coded in the separated tasklet project called BarcodeScanner.
  3. Open Visual Studio 2008 (Professional edition or above).
  4. Create a Rolepad project called BarcodeScannerSample15: File > New > Project… > Project types > Visual C# > Dynamics Mobile > Rolepad project for Windows Mobile 6 (or Windows Mobile 5 if you wish).
  5. Add a new tasklet project called BarcodeScanner to the BarcodeScannerSample15 solution: Right-click on BarcodeScannerSample15 solution > Add > New Project… > Project types > Visual C# > Dynamics Mobile > Tasklet project for Windows Mobile 6 (or 5).
  6. BarcodeScanner assembly should be deployed automatically when deploying BarcodeScannerSample15 project: Add reference of the BarcodeScanner project to the BarcodeScannerSample15 project.
  7. Add following references to the BarcodeScannerSample15 project:
      Microsoft.Dynamics.Mobile.Components
      Microsoft.Dynamics.Mobile.Components.Services.BarcodeScanning.Symbol
      (Microsoft.Dynamics.Mobile.Components.Services.BarcodeScanning.SymbolIntermec)
      Microsoft.Dynamics.Mobile.Components.Tasklets.Menu
  8. The scanning itself is a manufacturer-specific operation, so manufacturer-specific assemblies will be needed. You have to download and extract the following assemblies: Symbol and Symbol.Barcode for Motorola (Symbol) devices and Intermec.DataCollection.CF2 for Intermec. Read the article Where to get barcode drivers to figure out where and how to get these.
  9. Open Windows Explorer and locate BarcodeScannerSample15 project folder, create BinaryReferences subfolder and copy extracted assemblies under this folder. Reference these binaries from the BarcodeScannerSample15 project.
  10. The core of barcode reader functionality provided by Microsoft Dynamics Framework is located in Microsoft.Dynamics.Mobile.Runtime assembly. Add following reference to the BarcodeScanner (tasklet) project:
      Microsoft.Dynamics.Mobile.Framework.Runtime
  11. Open BarcodeScannerTasklet.cs and add following using statements:
      using Microsoft.Dynamics.Mobile.Framework.Entities;
      using Microsoft.Dynamics.Mobile.Components.Services.BarcodeScanning;
      using Microsoft.Dynamics.Mobile.Components.Services;
  12. We will need a BarcodeReader object to perform the actual scanning. This object will be created by BarcodeScanningService defined in the App.config file. The service assures that a correct version of BarcodeReader object will be newed-up.
  13. Add BarcodeReader private field called barcodeReader.
      BarcodeReader barcodeReader;
  14. Add BarcodeScanningService public property called BarcodeScanningService and decorate it with [RolePadService] attribute.
      [RolePadService]
      public BarcodeScanningService BarcodeScanningService { get; set; }
  15. Edit OnStarted method. You must ask BarcodeScanningService to create particular BarcodeReader object and implement two event handlers with self-explaining names. This code will be called only once within the tasklet lifetime.
      protected override void OnStarted()
      {
          base.OnActivated();
       
          barcodeReader = BarcodeScanningService.GetReader(this);
       
          barcodeReader.Scanned += new EventHandler<ScannedDataEventArgs>(barcodeReader_Scanned);
          barcodeReader.Error += new EventHandler<ErrorEventArgs>(barcodeReader_Error);
      }
  16. Override OnActivate method. The scanner must be opened (enabled). This code can be called repeatedly when entering already started tasklet.
      protected override void OnActivated()
      {
          base.OnActivated();
       
          barcodeReader.Open();
      }
  17. Override OnDeactivated method. The scanner will be closed (disabled). Counterpart of the OnActivate method – can be called repeatedly.
      protected override void OnDeactivated ()
      {
          base. OnDeactivated ();
       
          barcodeReader.Close();
      }
  18. Override OnClosing method. Closing the system resources and bit of cleaning.
      protected override void OnClosing(ExitResult exitResult)
      {
          base.OnClosing(exitResult);
       
          barcodeReader.Error -= barcodeReader_Error;
          barcodeReader.Scanned -= barcodeReader_Scanned;
       
          barcodeReader.Dispose();
      }
  19. Add barcodeReader_Error event handler.
      void barcodeReader_Error(object sender, ErrorEventArgs e)
      {
          if (e != null && e.Exception != null)
              Container.Alert("Exception ocured while using barcode scanner:\n" + e.Exception.Message);
      }
  20. Add barcodeReader_Scanned event handler. In case the scanning was successful tasklet view class is going to present the scanned data. Some barcode readers return multiple lines of the scanned information. Typically we need to know only the first one – that is why we pass 0 index of e.Data array to the view.
      void barcodeReader_Scanned(object sender, ScannedDataEventArgs e)
      {
          if (e != null && e.Data != null && e.Data.Length > 0)
              view.ShowScannedBarcode(e.Data[0]);
      }
  21. You are done with the tasklet itself but we have to extend its view.
  22. Double-click BarcodeScannerView.cs and add one TextBox control called txtScannedBarcodes.
  23. Make txtScannedBarcodes control ReadOnly, Multiline and change its size to your convenience.
  24. Open IBarcodeScannerView.cs and add extend the interface by:
      void ShowScannedBarcode(string barcode);
  25. Right-click BarcodeScannerView.cs and select View Code.
  26. Implement IBarcodeScannerView by the following code:
      public void ShowScannedBarcode(string barcode)
      {
          this.txtScannedBarcodes.Text += barcode + Environment.NewLine;
      }
  27. You should be able to build BarcodeScanner tasklet project by now so let us finish the BarcodeScannerSample15 project.
  28. Modify app.config by adding of the following code at the beginning of the <services> node. The simple configuration informs Framework that it should create BarcodeScanningService of an appropriate type. Please notice that you must comment out/in the correct section for Intermec devices:
      <!-- Required for Barcode scanning on Symbol devices-->
      <add type="Microsoft.Dynamics.Mobile.Components.Services.BarcodeScanningService, Microsoft.Dynamics.Mobile.Framework.Runtime">
          <configuration xmlns="http://schemas.microsoft.com/Dynamics/Mobile/2008/11/Services/BarcodeScanning/Configuration">
              <scannerType>Microsoft.Dynamics.Mobile.Components.Services.BarcodeScanning.Symbol.ScannerDevice, Microsoft.Dynamics.Mobile.Components.Services.BarcodeScanning.Symbol</scannerType>
          </configuration>
      </add>
       
      <!-- Required for Barcode scanning on Intermec devices-->
      <!--<add type="Microsoft.Dynamics.Mobile.Components.Services.BarcodeScanningService, Microsoft.Dynamics.Mobile.Framework.Runtime">
              <configuration xmlns="http://schemas.microsoft.com/Dynamics/Mobile/2008/11/Services/BarcodeScanning/Configuration">
                  <scannerType>Microsoft.Dynamics.Mobile.Components.Services.BarcodeScanning.Intermec.ScannerDevice, Microsoft.Dynamics.Mobile.Components.Services.BarcodeScanning.Intermec</scannerType>
              </configuration>
      </add>-->
  29. Modify UserRole.xml – replace its whole content by the following code. It is a very simple orchestration with two tasklets: Menu tasklet provided by the Framework as an invitation screen and our newly created BarcodeScanner tasklet.
      <?xml version="1.0" encoding="utf-8" ?>
      <userRole minimize="false" xmlns="http://schemas.microsoft.com/Dynamics/Mobile/2008/11/Flow">
          <orchestrations>
              <orchestration name="startup">
                  <tasklets>
                      <!-- Main Menu (Menu) -->
                      <tasklet name="MenuTasklet" icon="Graphics\Dynamics_small.png" text=" Barcode Scanner Sample" context="Tasklet header;26" type="Microsoft.Dynamics.Mobile.Components.Tasklets.MenuTasklet, Microsoft.Dynamics.Mobile.Components.Tasklets.Menu">
                          <actions>
                              <group name="BackAndCancel" type="Flat" priority="98">
                                  <exitOrchestration name="Close" text="Close" />
                              </group>
                              <group name="MenuItems" priority="50" type="Flat">
                                  <open text="Barcode" icon="Graphics\Barcode_large.png" priority="49" tasklet="BarcodeScanner" />
                              </group>
                          </actions>
                      </tasklet>
                      <!-- /Main menu (Menu) -->        
       
                      <!-- This is a demo tasklet which shows how to implement barcode scanning functionality. -->
                      <tasklet name="BarcodeScanner" icon="Graphics\Barcode_small.png"  type="BarcodeScanner.BarcodeScannerTasklet, BarcodeScanner" >
                          <actions>
                              <exitTasklet text="Close" />
                          </actions>
                      </tasklet>
                  </tasklets>
              </orchestration>
          </orchestrations>
      </userRole>
  30. You should be able to build the whole solution at this moment.
  31. Double check that BarcodeScannerSample15 is your startup project. If it is not the case then right-click on BarcodeScannerSample15 project node and select “Set as StartUp Project”.
  32. Right-click Properties subfolder of BarcodeScannerSample15 project and select Open.
  33. Go to Devices and select your target device.
  34. Connect the device and press F5.

Do not forget to check MSDN documentation: BarcodeScanningService Class

By the way: The complete source code can be downloaded – see the bottom of this article. However I am sure you are glad you went through the whole example by yourself - it is the best way how to learn the stuff.

Please notice that the downloadable code is more complex and much better commented than the example you created based on the tutorial above. The difference is mainly given by more extensive error handling in the downloadable code. The tutorial code should be used for tutoring/learning only, the downloadable example on the other hand rather as a skeleton for building real applications based on 1.5 version of the Framework.

Download source code here: BarcodeScannerSample15.zip

This code will run first after you copy barcode drivers into the .\BarcodeScannerSample15\BinaryReferences folder.

How to enable barcode scanning on existing Microsoft Dynamics Mobile tasklets

This is an installment of Barcode Scanning With Microsoft Dynamics Mobile series.

… and concurrently it is the shortest blog article I have ever written :-)

Just follow the MSDN link: How to: Set Up Barcode Scanning for Mobile Sales. Use this approach for SimpleList or similarly for ItemList tasklet.

Where To Get Barcode Drivers

This is an installment of Barcode Scanning With Microsoft Dynamics Mobile series.

Barcode drivers are the most essential prerequisites for barcode scanning functionality on a particular device. Out of the box, Microsoft Dynamics Mobile supports two barcode enabled device manufacturers:  Motorola (formerly Symbol) and Intermec. To achieve any barcode related functionality you need to acquire appropriate barcode drivers. These are usually wrapped in some .NET Compact Framework assembly which is shipped as a part of a particular SDK of the given manufacturer. Third parties (in this case Microsoft) are not allowed to redistribute manufacturers’ drivers so you have to get them by your own. To make your life easier I prepared the following mini-tutorials describing where to download appropriate SDK and how to extract barcode driver out of them.

Please notice! The description below is very precise and all links are currently working (January 2009). However it can change as time goes by. Feel free to add your comment to the blog article, we will update the description.

Motorola (formerly Symbol): You need two assemblies called Symbol and Symbol.Barcode

  • Go to Motorola EMDK for .NET v2.0 (EMDK stands for Enterprise Mobility Developer Kit formerly known as SMDK - Symbol Mobility Developer Kit) and download EMDK-M-020005-Up2.zip.
  • Unzip and locate the following CAB file: symbol.all.arm.cab (typically in .\SDK\Smart Devices\wce500\armv4i folder).
  • Install the CAB file on any Windows Mobile device or emulator, and locate Symbol.dll and Symbol.Barcode.dll on that device under \Windows
  • Copy Symbol.dll and Symbol.Barcode.dll to your PC for future use.

Intermec: You need one assembly called Intermec.DataCollection.CF2 a

  • Notice that you must be a registered user to be able to perform any download from the Intermec web site. If you are not, go to the Intermec downloads login page, click on the “create a new account” link, provide all required information and click on the “Register” button.
  • Having your Intermec account you can download the Intermec Development Toolkit. You must enter your Intermec account credentials and go through a short wizard to reach the download link.
  • Install the toolkit (00002344_IDLDCRK_Setup.exe).
  • Locate Intermec.DataCollection.CF2.dll assembly under the following path: %PROGRAMFILES%\Intermec\Developer Library\Dot NET Assemblies\CF 2.0
  • Copy Intermec.DataCollection.CF2.dll to your PC for future use.
Barcode Scanning With Microsoft Dynamics Mobile

My plan is to post a short series of articles related to barcode scanning experience with Microsoft Dynamics Mobile. Today’s post should act as an overview of posted and will-be-posted articles touching the barcode functionality.

Here is the plan:

Bullets above will be transformed to http links after the corresponding article has been issued.

Unit Testing DocumentHandlers With Parameters

In my previous post, I described how to unit test custom DocumentHandlers. When your DocumentHandler has one or more DocumentHandlerParameters, you have to manually assign values to these, since, during unit testing, the DocumentHandler instance runs outside the warm and fuzzy Mobile Server environment.

This is as simple as setting the property to the desired value before invoking the Submit or GetDocumentDescription methods.

[TestMethod]
public void TestUsingMyIntegerParameter()
{
    // Fixture setup
    string anonymousNumber = 7.ToString();
    MyDocumentHandler sut = new MyDocumentHandler();
    sut.MyInteger = anonymousNumber;
    // Exercise system
    // ...
    // Verify outcome
    // ...
    // Teardown
}

Notice how, in the above test, the MyInteger property is assigned to an Anonymous Variable before the SUT is exercised.

It's very simple, so the main purpose of this post was just to remind you that you have to remember setting all relevant properties appropriately as part of setting up your Fixture.

Unit Testing DocumentHandlers

As I promised in a previous post, I'd like to discuss how to unit test a custom DocumentHandler. There's really nothing to it: Just create a new instance of your DocumentHandler and start invoking its members.

Here's a test of the Submit method:

[TestMethod]
public void SubmitWillReturnCorrectDescription()
{
    // Fixture setup
    string anonymousXml = "<anonymous>XML</anonymous>";
    Guid anonymousMessageId = Guid.NewGuid();
    string anonymousDeviceId = "Anonymous device ID";
    IPrincipal anonymousPrincipal =
        new GenericPrincipal(
            new GenericIdentity("Someone"), new string[0]);
 
    string expectedDescription =
        string.Format("Message {0} was successfully submitted",
        anonymousMessageId);
 
    MyDocumentHandler sut = new MyDocumentHandler();
    // Exercise system
    DocumentResponse result =
        sut.Submit(anonymousXml, anonymousMessageId,
        anonymousDeviceId, anonymousPrincipal);
    // Verify outcome
    Assert.AreEqual<string>(expectedDescription,
        result.Description, "Description");
    // Teardown
}

Since the Submit method takes four parameters, you must create these four objects prior to invoking the method. In this example, I'm naming the variables using the Anonymous Variable Naming coding idiom.

In many cases, the XML string containing the document to submit is probably the most interesting parameter, and you will likely need to write many separate tests to verify that your custom DocumentHandler correctly deals with different instances of your particular XML document format.

In this context, it's worth noting that you can obviously debug into your code when running a test, so this is a very effective troubleshooting technique. Due to the way we load and host DocumentHandlers, it's not possible to attach a debugger to a custom DocumentHandler while it's executing in Mobile Server, so debugging into a unit test is a good alternative. If your custom DocumentHandler throws an exception while executing in Mobile Server, the event log will contain a copy of the message, and you can then use this copy to reproduce the problem in a unit test.

In the test shown above, notice that I create a new GenericPrincipal instance to use as the mobileUser parameter. Be aware that any IPrincipal instance is acceptable, so I just created a GenericPrincipal because it was the easiest thing to do. When executing your custom DocumentHandler, Mobile Server doesn't use GenericPrincipal, but rather a different implementation of IPrincipal, and it makes no guarantees that it will always use the same implementation type. In other words, your custom DocumentHandler should follow the Liskov Substitution Principle.

As you can see, it's really straightforward to unit test custom DocumentHandlers. The Submit method has by far the most complex signature, so testing the FriendlyName and GetDocumentDescription members is even simpler.

Update: A follow-up post dealing with unit testing and DocumentHandlerParameters is now available.

DocumentHandlerParameter Best Practices

When you create a custom DocumentHandler, it is very likely that you may need to supply it with some configuration data. Common examples include the address of your back-end server, credentials to the back-end system, etc.

DocumentHandlers can be configured by adding public read/write string properties and decorating them with the DocumentHandlerParameter attribute. This is all described in the documentation, but in this post, I'd like to expand a bit on the subject to describe some best practices for dealing with such parameters.

If all you need is a string, you can get by with an implementation as simple as this:

[DocumentHandlerParameter("Description template")]
public string DescriptionTemplate { get; set; }

However, if you really need something else, you will have to parse the text yourself, since only strings are supported. Imagine that you really need to expose an integer property. Basically, you have two options:

  • You can parse it as the value is being assigned
  • You can parse it when you need it

Parsing the value right away is the preferable alternative, since this gives Mobile Server a chance to verify the configuration as soon as the operator saves the document type (right now, Mobile Server doesn't do that, but it might do that in a future version, in which case you'll get validation for free). It also makes for cleaner code.

Here's one possible implementation of an integer property:

[DocumentHandlerParameter("My integer")]
public string MyInteger
{
    get { return this.myInt.ToString(); }
    set 
    {
        int i;
        if (int.TryParse(value, out i))
        {
            this.myInt = i;
            return;
        }
        throw new ArgumentException(
            "Value was not an integer", "value");
    }
}

where myInt is a private member variable. Notice how the setter attempts to parse the string to an integer, and throws a descriptive exception if this is not possible.

Whenever the value of this property is required, the rest of the code can simply reference this.myInt, which is now guaranteed to be correct. Int32 is a value type, so referencing this.myInt will always be correct, since the default is 0.

This is not the case for reference type properties like the DescriptionTemplate property above. Keep in mind that reference types may be null, so that it becomes necessary to check for this before using the property:

public override DocumentResponse Submit(string xmlDocument,
    Guid messageId, string deviceId, IPrincipal mobileUser)
{
    string template = 
        string.IsNullOrEmpty(this.DescriptionTemplate) ?
        "Message {0} was successfully submitted" :
        this.DescriptionTemplate;
 
    DocumentResponse dr = new DocumentResponse();
    dr.Description = string.Format(template, messageId);
    return dr;
}

In this implementation of the Submit method, I test the DescriptionTemplate property's value before using it, defaulting to a hard-coded value if it's not defined. It is important to realize that Mobile Server makes no guarantee regarding the values of DocumentHandlerProperties, since it is entirely up to the operator whether he or she cares to fill in the values or not, so either have some good default values or throw an exception with a descriptive error message.

As the above example illustrates, you can reference DocumentHandlerProperties from within the Submit method. This is the main scenario, but Mobile Server will also fill in the values of these properties when invoking the GetDocumentDescription method.

As a contrast to the Submit and GetDocumentDescription methods, the FriendlyName property of DocumentHandler is only being used in the UI when the operator selects a DocumentHandler to configure; that is, before the properties are being configured. For that reason, when the code inside the FriendlyName property executes, the property values will always have their default values.

In short:

  • Validate parameter values in their setters and fail fast.
  • Don't assume values have been set.
  • Consume values from Submit and GetDocumentDescription only. You cannot consume the values from within the FriendlyName property's code.
DocumentHandler - Behind The Scenes

Mobile Server gives you the option of developing custom code that integrates to your back-end system. One way you can do this is by implementing one or more .NET classes that derive from the abstract DocumentHandler class. This is already described in the documentation along with the other options for back-end integration, but in this post, I'd like to provide some background information on this API. In future posts, I'll discuss some best practices for developing custom DocumentHandlers.

Here's the DocumentHandler API to establish the context:

public abstract class DocumentHandler
{
    protected DocumentHandler();
 
    public abstract string FriendlyName { get; }
 
    public abstract string GetDocumentDescription(
        string xmlDocument);
    public abstract DocumentResponse Submit(
        string xmlDocument, Guid messageId,
        string deviceId, IPrincipal mobileUser);
}

When we designed DocumentHandler, we had several design goals in mind:

  • It should be as simple as possible to implement a custom DocumentHandler
  • It should provide as much flexibility as possible
  • It should be testable
  • It should adhere to the .NET Framework Design Guideline that states that you should prefer abstract classes over interfaces (consequently, this is why DocumentHandler is not an interface)
  • It should be CLS compliant

While I personally could wish for even more flexibility, I think we succeeded very well on all the other points. In the Dynamics Mobile Team, we use TDD, so it was particularly important to us that the DocumentHandler API is testable - and it is.

The DocumentHandler constructor is empty, so we don't require you to pass some weird, internal or sealed object as a constructor parameter; on the contrary, in fact we require that your custom DocumentHandler has a default constructor. That makes it super-easy to create a new instance as part of a test:

MyDocumentHandler sut = new MyDocumentHandler();

All the members of DocumentHandler works on well-known BCL types (string, Guid, and IPrincipal) with the single exception of the Submit method, which returns a DocumentResponse instance, which is a type that we have defined in the same library.

DocumentResponse is a public, non-sealed class with a default constructor, and it works almost exclusively with BCL types such as string, DateTime, bool, etc. Again, there's a single exception in the use of the DocumentResponseStatus enum, but also here we are dealing with a public type that is easily created.

The bottom line is that the entire DocumentHandler API contains only three custom types, and all of those types are very susceptible to unit testing.

In a future post, I will discuss the matter of unit testing custom DocumentHandlers in greater detail.

Microsoft Dynamics Mobile case study at Roskilde Festival : Watch the video!!

Please enjoy this video showcasing how the Microsoft Dynamics Mobile product can be used in a very different, but nevertheless important, situations. When you watch it, take into consideration the difficulties a partner/customer goes through when implementing a mobile solution that has to work on a huge camping ground with only cellular coverage that only work occasionally, in rain and wind, battery driven and with capabilities to integrate directly into a Microsoft Dynamics backend. This solution was build in 1½ month - with no dry-run on the technology possible. That's only possible if you have a solid platform to develop on!

Enjoy!

New version of Microsoft Dynamics Mobile now available on partner source

The Microsoft Dynamics Mobile Team is really proud and pleased to announce that a new version of Microsoft Dynamics Mobile were released to PartnerSource last friday!

This new version of Microsoft Dynamics Mobile is Better Than Ever by significantly raising the bar in a number of areas:

  • Tightly integrated and aligned with both the releases of Dynamics AX 2009 SP1 and Dynamics NAV 2009
  • Upgraded support for the latest Microsoft technologies (WM 6.1, Visual Studio 2008, SQL 2008, SQL CE 3.5 SP1, .NET CF 3.5, Windows Server 2008)
  • Significantly improved the quality and performance through rigorous end-2-end testing and code-optimization
  • Clearer and more appealing UI with the added support of VGA resolution devices
  • Improved implementation experience in one installer for Mobile Development Tools and Mobile Sales

Today we have more than 500 partners signed up for Microsoft Dynamics Mobile and a catalog of 20+ ISV solutions. Our Mobile Sales application is available in 46 languages and we now support 5 versions of Microsoft Dynamics AX and Microsoft Dynamics NAV.

The bits can be found here, https://mbs.microsoft.com/partnersource/downloads/releases/DynamicsMobileVersion15.htm

Microsoft Dynamics Mobile at Convergence 2008 EMEA in Copenhagen

If you are at Convergence in Copenhagen this week, please come join us in a round table, watch one of our sessions - or meet us at our booth number 37 and 38 in the Expo area for a 1:1 discussion. At the booth we will present our latest release and you will have the opportunity to try out being ‘mobilized' yourself. We do hope to see you there !

Tuesday

Roundtable: Microsoft Dynamics Mobile - Business Opportunity and Business Model
16:00-17:30, Room 33, Hall B

During this roundtable we will discuss the new opportunities that mobility brings to our partners. We will discuss all aspects of what is needed for partners to succeed in delivering great mobile solutions for Microsoft Dynamics AX and NAV.

Wednesday

Roundtable: Microsoft Dynamics Mobile - Product feedback focus group
11:00-12:30, Meeting Room 16. 1st Floor

The purpose of this session is to get feedback from you on all product related issues

Thursday

MDM01 - How Do I Get Started On Mobility for Microsoft Dynamics NAV?
09:00-10:00, Aud 11
Do you want to implement a mobile business application for Microsoft Dynamics NAV but don't know how? During this session, you'll be able to learn from experienced Microsoft partners who have successfully developed and implemented a wide range of mobile solutions with their customers. Topics covered in the session will include: Mobile best practices, introduction to mobile technologies & mobile infrastructure needs, recommended skills and a hands on introduction to mobility.

Thursday

MDM02 - Go Mobile with Microsoft Dynamics AX
10:30-11:30, Aud 11

In this session, you'll learn how to boost the productivity and efficiency of your mobile employees by enabling them to perform their tasks while "on-the-go" - and get the results directly into your Microsoft Dynamics AX solution. You'll learn the benefits of deploying a mobile business application in your organization and the factors that should influence your decision.

Thursday

MDM03 - How Do I Get Started On Mobility for Microsoft Dynamics AX?
12:00-13:00, Aud 11
Do you want to implement a mobile business application for Microsoft Dynamics AX but don't know how? During this session, you'll be able to learn from experienced Microsoft partners who have successfully developed and implemented a wide range of mobile solutions with their customers. Topics covered in the session will include: Mobile best practices, introduction to mobile technologies & mobile infrastructure needs, recommended skills and a hands on introduction to mobility

Thursday

NAV12 - Go Mobile with Microsoft Dynamics NAV¨
14:00-15:00, C1.4
Learn how to boost the productivity and efficiency of your mobile employees by enabling them to perform their tasks while "on-the-go" - and get the results directly into your Microsoft Dynamics NAV solution. Attend this session to learn the benefits of deploying a mobile business application in your organization and the factors that may influence your decision.

Dynamics Mobile takes out the trash at Europe’s largest music festival

From July 3rd to 6th, the quiet fairgrounds outside the provincial town of Roskilde, about a 30 minute drive from Copenhagen, were transformed into a cacophony of music, people, tent camps, and general abandon. Over 67,000 people attended this year’s Roskilde Festival, the largest music festival in Europe, held since 1971.

They party hard – and generate a lot of trash in an area, which each year has to be fitted with an infrastructure “from scratch” to support the comforts of such a large group of people. So every year at festival time, the non-profit Roskilde Festival organization grows from its 25 paid staff to an army of almost 20.000 people as volunteers join to man the booths, collect trash, and do most tasks involved with executing a festival of this size.

One major challenge is keeping the area clear of trash, both for aesthetic and health reasons, but also to avoid fire hazards. This year, the waste collection crew will be using Microsoft Dynamics Mobile devices to stay on top of the trash piles. Kristian Ridley from the MDCC Mobile team has spearheaded the effort, inspired by his many years as a Roskilde Festival volunteer worker.

“I saw the opportunity when presented to a solution from one of our partners, Tegos. Tegos has developed a vertical Dynamics NAV solution for waste management. Roskilde Festival uses Dynamics NAV for its daily ERP system, and so the link was obvious”, said Kristian Ridley.

The Dynamics Mobile solution enabled crew members to better coordinate the dispatch of garbage trucks to hard-hit areas. If a crew member sees a big trash pile in the camp grounds, he or she can send a mobile photo of the site along with GPS coordinates into the system, which allows the driver to better plan the collection routes based on need.

“This new method will also bring relief to the large crew of fire men who are dispatched to the festival and who in the past have spend a lot of time pointing out fire hazards which need to taken care of. So of course, we are really happy that Dynamics Mobile technology can be put to such a worthy use”, said Kristian Ridley.

The Microsoft Dynamics Mobile team sponsored 15 devices at this year’s festival. The Roskilde Festival is a non-profit event with all proceedings from the main event donated to charity and to the local sports clubs in the Roskilde area which represent a large percent of the volunteer workers in the festival.

Read more here: http://www.roskilde-festival.dk/2008/frontpage/system/news/singlenews/the-technology-takes-care-of-the-garbage/

Additional place to get help using Microsoft Dynamics Mobile bits

As a non official role in our team I’m searching the internet for people who needs help using our bits, and has on several occasions helped. I would like to point you to a site where you can get some quality answers without waiting for the team to write you back or me to find your question on the internet; www.dynamicsmobile.net.

The owner of the site, Laurent Lopez, already helped a couple of people and I know he is eager to help even more.

Hope you found this information interesting.
/Tim

Using SSIS with Microsoft Dynamics Mobile

Let me start with a small announcement

I am happy to announce that we have upgraded our SSIS (SQL Server Integration Services) solution for Mobile Sales from the 2005 to the 2008 version of Microsoft SQL Server Integration Services. So from now on we will internally work with the 2008 version which will give us some new features.

Side note: Please notice that I am talking here about upgrade which has not been released yet. In case you have your own SSIS solution you may wait for our next release - however I encourage you to perform your own upgrade. Upgrading of SSIS is a straightforward and not time consuming process - just follow this link.

Posting plan

My plan is to give you a small introduction why and how we use SSIS (today’s posting) and to publish few SSIS tips and tricks (next postings). Of course I will also take into consideration all your comments / questions / requests / recommendations.

General introduction

If you are completely new to SSIS please read this short introduction or go for details to the official site.

SSIS role within the Microsoft Dynamics Mobile architecture

One of the questions solved by Microsoft Dynamics Mobile architecture is which business related data should be displayed on the mobile device and how to get them. Our current solution uses three different database types (Resource, Staging and Reference) and two different technologies of transforming data between these databases. SSIS as the first mentioned technology takes care about the data transfer from Resource (also called Backend or Business) Database to the temporary database called Staging Database. The next logical step – passing and filtering user related data from the Staging to the Reference (also called Device) Database located on the mobile device – is based on a different technology called SQL Merge Replication and its description is not part of this article.

I am going to describe only very particular piece of the Microsoft Dynamics Mobile architecture - see the highlighted parts of the picture below.

SSIS role within the Microsoft Dynamics Mobile architecture

When we are talking about the data transfer from Resource to the Staging Database proceeded by the SSIS package we can describe it as an Extract, Transform and Load principle. During one SSIS iteration the data are not only being extracted from the Resource Database, but also converted to more consistent data types or transformed to more meaningful units to fit better the business needs displayed later on the mobile device. Finally the extracted and transformed data are being loaded to the Staging Database.

Typically SSIS package is installed as an SQL Server job scheduled to run every few minutes, so you can understand the Staging Database as an always-up-to-date simplified copy of the Resource Database.

Currently our SSIS solution contains three SSIS packages: Mobile Sales-AX4-Package, Mobile Sales-NAV4-Package and Mobile Sales-NAV5-Package supporting Microsoft Dynamics AX 4.0 SP1 and SP2, Microsoft Dynamics NAV 4.0 SP3 and Microsoft Dynamics NAV 5.0 SP1 backend solutions.

You can see that sometimes one package can cover two versions of one backend solution (as for AX 4.0 SP1 and SP2); sometimes two different packages are needed (as for NAV 4.0 and 5.0). This of course depends on how many and how complex changes have been introduced in the newer backend solution.

Sometimes different backend solutions could share the same structure of the Staging Database (e.g. AX and NAV), which basically means that the same set of features could be built on the mobile client. Other time special version of the Staging Database is required – mainly because of set of features supported by the particular backend solution.

General introduction to the SSIS development experience

SQL Server Business Intelligence Development Studio (BIDS) is the tool you want to use when creating new or modifying existing SSIS packages. This IDE is based on Visual Studio and comes together with the SQL Server 2005 or 2008 respectively.

Introduction to the Mobile Dynamics SSIS development experience

The different versions of the packages differ significantly in e.g. the way how they handle switching between different companies; however it is pretty easy to assemble the generic description how the packages do their works.

Each package consists of several so called Data Flow Tasks - sequence of these tasks is being defined in the Control Flow view. Please have a look at the simplified version of the Control Flow diagram below:

Simplified version of the BIDS Control Flow view

Typically there is a one-to-one relationship between Staging Database tables and Data Flow tasks. So for example Customer flow task corresponds to the Customer table in the Staging Database and takes care about data transformation related to this particular table. If you double-click one of the tasks the environment will switch to the Data Flow view.

Here is the generalized version of one Data Flow task demonstrating the general pattern how these are built:

Generalized version of the BIDS Data Flow view

Extraction – This is in fact only a wrapper for the SQL select statements – one for the Backend and the other one for the Staging Database.

Data Conversion – Just extracted data could be converted to different data types - e.g. to different numeric types, to Unicode strings, to strings with a specific length etc.

Sorting – Data must be sorted before Merge Join. This step could be avoided by using ORDER BY clause within the extraction SQL statement and setting IsSorted property to true. Much better performance could be gained by such a shift. However - be careful - the sorting step may be avoided only if you are absolutely sure that the reference and staging databases are using the same sorting methods.

Merge Join – Probably the most complicated part which deserves a separate article. Just notice it must be Full Outer Join for now.

Conditional Split – Based on the previous Full Outer Join we can specify three conditions which decide whether the data row coming from the Backend Database should be inserted to the Staging Database (New rows); or already existing data row should be modified (Modified rows); or data row exists in the Staging Database but not (anymore) in the Backend Database and in this case it should be deleted from the Staging Database.

Loading – Performs the operations decided in the previous step using the correct data mappings.

This must be enough for today :)

As mentioned at the beginning I will return to this topic giving more detailed description of selected parts and publishing some small and useful tips & tricks.

How to send a requestdocument from a service

Yesterday I was sitting with a potential partner here at MDCC (Microsoft Development Center Copenhagen) to get them introduced to Microsoft Dynamics Mobile. All in all I think we had a good and productive day where we covered most of the major topics and gave the partner a good kick start on their development of a mobile application.

Looking back I can however see that there were a couple of things that we might explain better. I’ll try to write some posts about this as time progress.

The first thing I’d like to address is "How to send a requestdocument from a service"

Until now we, at Dynamics Mobile, have only had scenarios where we collect data from multiple tasklets and put this into a request document. Working with NaviParner I could see that there are several scenarios where you might wish to send data from a service.

Creating a request document in code 

A request document is wrapped in a RequestDocumentDefinition which takes name as parameter.

RequestDocumentDefinition definition =

   new RequestDocumentDefinition("requestDocumentFromCode" /* name */);

definition.Inherit = false; // Inherrit other request documents

definition.Stamps = 10; // Stamps to put on the document

definition.Text = "My request document";   // Userfriendly text show i.e. in request document status

Secondly we need to create the actual request to send.

RequestDocument document = new RequestDocument(definition);

document.AddRequest(new RequestFromCode("my data as a string"));

requestDocumentService.Submit(document);

First line creates the request document using the request document definition. In the 2nd line we add data to the request document using a custom object called RequestFromCode which takes a string in the constructor. And finally we submit the request document to the RequestDocumentService.

The RequestFromCode object is a simple data object that implements IRequestContributor.

public class RequestFromCode : IRequestContributor

{

   private readonly string data;

 

   public RequestFromCode(string data)

   {

      this.data = data;

   }

 

   public void CreateRequest(XmlWriter writer)

   {

      writer.WriteStartElement("requestDocumentFromCode");

      writer.WriteAttributeString("data", data);

      writer.WriteEndElement();

   }

 

   public string Name

   {

      get { return "RequestFromCode"; }

   }

}

The request document needed to be submitted to the requestDocumentService. In order access the service the following peace of code can be inserted in the tasklet or service where the request document from code is required

private IRequestDocumentService requestDocumentService;

 

[RolePadService]

public IRequestDocumentService RequestDocumentService

{

   get { return requestDocumentService; }

   set { requestDocumentService = value; }

}

Hope you found this post interesting.

More Posts Next page »
Page view tracker