Monday, December 12, 2011

Resolving Compile Errors and Generating CIL is not Optional

All too often I visit clients or move in a code release to a production environment, only to find there are compile errors in the environment. This is totally unacceptable, and not just in a production environment. The existence of a compile error in a production environment is bad in itself, but it clearly shows there is an underlying problem going on in the development process.

Why is there a compile error in production, how did it get there? There are only 2 possibilities:
1) someone was WRITING/CHANGING code in production
2) there is a problem in the procedure of moving code into production

If someone was writing code in production, they should get a warning and a note in their employee file. Writing code in a production environment is one of the worst offenses a developer can make. I've known plenty of projects where developers did not have access to production at all. I absolutely love that idea because it forces proper procedures all around. I've seen consultants and developers complain about not having access to production to troubleshoot issues. If issues are severe enough they need a developer's eye and possibly debugging, it's time to take a backup of production and restore in an environment where investigation can be done (you should never have debugging on AOS enabled in production!). Contrary to some people's beliefs, making an environment copy is an easy (and relatively quick) thing to do, and it is the right thing to do. Debugging in production or manipulating data in production using the table browser or SQL without having tested this (and its impact) in a copy of production first is just as bad of an offense...

The second possible scenario is a problem with code release procedures. I've talked about this topic before in the AX 2012 code deployment article, and this is a good illustration. Deployments to production should be done in a binary, compiled form. That implies that
1) the code was compiled and checked somewhere else and moved into prod in a compiled form, so no compile errors should exist in prod after the move
2) the code that was moved into prod is the exact same as where it came from and was tested

Compile errors in prod can result from missing objects in XPOs or having to do an XPO merge while importing and making a mistake. All the more reasons to not move XPOs. To quote my deployment article: "Moving XPOs is barbaric" (it's becoming my slogan).

In either case, after moving in XPOs you should do a full compile anyway. At Streamline Systems we move layers or models, not XPOs. But even then we do a full compile after the binary code is moved in. It is an extra check that your code is ok, but more importantly it verifies that your layer works with the existing layers in the environment. What if a code change you made works by itself, but there is a customization in another layer that is now broken because of your change? You will not know until you do a full compile. And hopefully you already noticed that in a user acceptance testing environment (that has the same other layers as production) before you moved it into production. I guess layers being out-of-sync between production and a user acceptance testing environment could be considered a third reason for a production environment to have compile errors, but it comes down to a code release procedure issue as well.


Compiling brings me to my next topic. The way the X++ language works as a scripting language has gotten us spoiled over the years. The fact that X++ is a scripting language is exactly the reason why we are even talking about these issues. You can modify one object, compile it, and you're good to go. If you just broke another object by doing this code change, you won't know until run-time, or until you do a full compile of everything and find out. Think about traditional compiled development. For your code change to be incorporated, you have to recompile your whole library. If you make one code error or break something in another code file, your whole library will fail to compile and you can't run anything anymore at all until that is fixed. Besides this being good practice, it totally makes sense.
So now in AX 2012, we have the CIL generation. This generates .NET assemblies for all the X++ code. And guess what? If you have 1 compile error anywhere, the CIL generation will fail to complete. However, the .NET assemblies are used in batch jobs, services, and potentially other code being run explicitly in the CLR. (Check my previous article on X++ and CLR for details.)
As soon as the CIL generator encounters ANY compile error, it will stop going any further (just like a regular compile in C# for example). So you may have two pieces of code that are totally independent of each other. But one of the two has a compile error and CIL generation will abort for BOTH.


So here are two major conclusions I leave you with:
1) If you have ANY X++ compile errors in your system, you may end up with NO CIL code at all, even if the compile error is in a different area of code
2) Without a full CIL generation you have a CRIPPLED AX environment. Your CIL code will either be the previously compiled binaries (without your latest code change), or it won't be there at all. Batch jobs and services may not work at all, or have unexpected behavior based on the last good compile that happened.

So, resolving compile errors and having a completed full CIL generation in AX 2012 is NOT OPTIONAL. If you have compile errors in any of your environments, you should go back to your desk and start resolving them until they're fixed, right now. Failing to do so will break AX 2012, for real.

Wednesday, December 7, 2011

10-minute App Series Conclusion

The 10-minute app series has been concluded. If you've missed one, here are the links:

• "10 minute WPF app": a WPF app that consumes AX 2012 queries (without customization to AX).
• "10 minute Windows Azure app": send item data to an Azure site.
• "10 minute Windows Phone 7 app": get list of items on windows phone 7 app through trusted intermediary (without customization to AX)

I acknowledge to create these 10-minute apps I probably violated tons of best practices and I know I took a lot of shortcuts and skipped over things, just to make it work in 10 minutes. They are all proof-of-concepts and hopefully by taking these shortcuts you won't be inclined to just take the code and some things to create a customer solution. You should do it the right way, and take more than 10 minutes :-)

The whole point of these 10 minute apps is to enforce Microsoft's AX 2012 marketing buzz about "Powerfully Simple". The continued deep merging of AX with the rest of the Microsoft stack enables a lot of possibilities. And although a lot of the marketing is focused around AX 2012 being powerfully simple for the user, hopefully this 10-minute app series shows how the power of the integration with other Microsoft technologies makes things simpler for us developers too!

Let this be an inspiration. There are wonderful things you can do with these three examples if you start mixing and matching. Perhaps a service bus between Azure and AX, making mobile apps for mobile platforms using Azure (including Windows Phone). Or, as Sashi did, apply the base code and concepts to create an Android app.

If you created any other projects based on these apps, post it in the comments or let me know on twitter, and I will gladly reference them on my blog.

Monday, December 5, 2011

AX Mobile App for Android

The Windows Phone 7 app article has drawn quite some attention and interest. And (as I had somewhat hoped), someone has taken the series and created an Android front-end.
Technically that is all that would have to change: the front-end. If the intermediary is working, the WCF in between is up and running, all should work just fine. This author decided to make the WCF service RESTful, which took some extra effort.

Can't wait to see the final result!

Visit Shashi's blog to follow along with his article.

Wednesday, November 30, 2011

10-Minute App - Windows Phone 7 App

This is the third and final article in a 3-post about the Windows Phone 7 app for AX 2012. Before we continue on I think it's import to re-iterate that this is a proof-of-concept and you should not take this code as a basis to make a real world app. The goal is to show the potential and relative ease of making AX 2012 work with the rest of the Microsoft technology stack.
That being said, if you missed the first two articles:

- Part 1 - Setting up IIS
- Part 2 - Creating the intermediate WCF service for Windows Phone 7

In this final article, we'll build the actual Windows Phone 7. You need to have the setup and code in place of the first two articles. Before we get started, make sure you have the WCF service that we created in Part 2 running (press F5 in Visual Studio), and make sure you have the Windows Phone 7 SDK installed.

So, with the WCF service running, open a SECOND instance of Visual Studio 2010, this one does not need to run as administrator. Create a new project of type "Silverlight for Windows Phone and select the "Windows Phone Databound Application" template. I'm calling this project "DAXMusings_WP7".


You will get a dialog asking what version of the OS you want to use. The current version as of this writing is 7.1, which is Mango. I know it's confusing, I thought Mango was 7.5, but 7.1 is what it is. If you are a time traveler from the future reading this old blog post from November 2011, feel free to use a newer version. We're not using any specific OS features, so as long as .NET still supports WCF when you're reading this, I'm suspecting this code will still work :-)


First thing we need to do is add the service reference to our WCF service. This goes back to article 1 and 2. You NEED to enter the FULL qualified domain name for your server (the server name needs to match the certificate created in part 1), and you need to know the path to your service. If you've followed my lead on naming of the classes and folders etc, then (except for the server name) your URL should be:

https://yourmachinename.domainname/WP7/Service1.svc?WSDL

obviously replacing the "yourmachinename.domainname" with your server's FQDN. To add the reference, right-click the "References" node and select "Add Service Reference". On the dialog, enter the URL to your service's WSDL and click GO. In the namespace, I called the reference "AXItems".


The default layout defined in the XAML file contains a grid with two rows: one for the application and page title, one for the actual content grid. We'll add a third row to go in between, where we can enter a user name and have a button to retrieve the data. In the XAML file, add a third "RowDefinition" in between the two existing ones, with Height set to "Auto", so it looks like this:
Click here for a full code screenshot
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>


Next, under the StackPanel node containing the application title and page title (you can change the TEXT attribute on those TextBlock nodes to change the title that will show in your app... for example, change it to "DAXMusings Rules") and before the Grid called ContentPanel, we will add the following XAML. Since we're adding a Row in between, we need to make sure the Grid.Row property of contentpanel below is changed to 2! (see the full screenshot)
Click here for a full code screenshot
        <StackPanel x:Name="LogonPanel" Grid.Row="1">
            <TextBox x:Name="Logon" Text="claimguy@myapp.com" /%gt;
            <Button x:Name="GetItems" Click="GetItems_Click">
                <TextBlock Text="Get Items" />
            </Button>
        </StackPanel>

The keen eye noticed that the logon TextBox I added contains a username already (claimguy@myapp.com - the user we setup in the trusted intermediary article). Obviously this is not something you want to do in your production app. However, the Windows Phone Emulator (or at least the current version of it) does not support your machine's keyboard, so you actually have to use the on-screen keyboard for testing. So putting it in here saves you some typing. This is also a good moment to remind you this article series depends on the trusted intermediary setup, so you need to go through that for this to work.

If the hard-coded user was caught by your left keen eye, then your right keen eye may have noticed there is an event handler for the "Click" event on the button. If you are typing this in manually, the Visual Studio editor will prompt you to add that event handler method. If you just copy/paste the code from above, you can right-click the GetItems_Click text and select "Navigate to Event Handler" and this will create the method for you.


Before we can actually do something, we'll have to add the code that actually makes the call. There is already some basic code added for that in the template, but we want to change that of course. In your solution explorer, open the "ViewModels" folder and double click the "MainViewModel.cs" file.


The grid on the main page uses the Observable Collection that is defined in this file. In the template, they define a new data structure. We want to actually just use the data structure returned from the WCF service. So we'll need to make some changes to use the AXItems.AxdEntity_InventTable as the class contained in the collection:


You will notice that there is a method in this file called "LoadData", which due to this change will now contain a bunch of error lines. Just remove the error lines or comment them out:


Next, we'll add a method at the end of this MainViewModel class, which will be used as the event handler when the results are received from our WCF app. First we'll make sure there were no errors, if there were we will show that in a popup, and return out of the method. Next, we check to see there were items in the result set, if not we say so and return out of the method. Lastly, we loop over the items that were in fact returned, and add them to our observable collection. The isdataloaded=true is not really necessary, it's a variable maintained by this template but it doesn't really do much anyway.
Click here for a full screenshot
void client_GetItemCompleted(object sender, AXItems.GetItemCompletedEventArgs e)
{
    if (e.Error != null)
    {
        Exception ex = e.Error;
        MessageBox.Show(ex.Message);
        return;
    }
    if (e.Result == null)
    {
        MessageBox.Show("No items found");
        return;
    }

    foreach (AXItems.AxdEntity_InventTable item in e.Result)
    {
        this.Items.Add(item);
    }
    this.IsDataLoaded = true;
}

Finally, we'll add the actual code that makes the call. As mentioned a few times in this article series, the authentication is not what it should be and you should do proper WCF authentication.
Click here for a full screenshot
public void GetItems(string username)
{
    this.Items.Clear();

    try
    {
        AXItems.Service1Client client = new AXItems.Service1Client();
        // Set the client credentials property here for proper authentication
        client.GetItemCompleted += new EventHandler(client_GetItemCompleted);
        client.GetItemAsync(username, "10000", "10005");
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

Another thing here is the hard coded item numbers range. We're basically getting items 10000 through 10005. Feel free to add these as parameters on the XAML file as well. However, you need some type of limitation or you will run into the maximum message size of your WCF service. These can be changed easily in the web.config settings of the WCF service if you wish to do so. However, since we're doing a quick prototype here we're using mostly standard settings and a standard service too. Remember this service actually returns ALL item data, not just a few fields.
Ok, so now that we have the WCF call in place, we just need to call this method from our button click event handler. You should still have MainPage.xaml.cs open, so click on that tab.


in the GetItems_Click method, we now call our new method GetItems, which was put in the main view model. We need to pass the username entered on the screen. The textbox we added we gave the x:Name="Logon" name, so we can just call that and retrieve its property "Text" to pass to our method as the username:
private void GetItems_Click(object sender, RoutedEventArgs e)
{
    App.ViewModel.GetItems(Logon.Text);
}

Almost there! The last thing we need to change is back in the MainPage's XAML file:


Now that we have changed the observable collection ("Items" - which is what you see in the XAML the grid's ItemsSource property is bound to), we need to make sure the two TextBlocks in the data bound grid actually bind to properties that exist on the AXItems.AxdEntity_InventTable class. This is the class AIF returns from the service, and the properties on it basically reflect the fields on the InventTable. In fact, it also contains some sub-tables of InventTable, so feel free to experiment with the binding. For now, we'll just bind the two text blocks to item id and name alias ("search name"):
Click here for a full screenshot
<TextBlock Text="{Binding itemIdField}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
<TextBlock Text="{Binding nameAliasField}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/>


With all this in place, we're ready to run the App!! Now, one thing to remember from Part 1 was the self-signed certificate issue with Windows Phone 7. Remember that to resolve this issue we added a ZIP file called certificate.zip onto the IIS website in the root folder.
Press F5 to run and deploy the app to the phone emulator. Make sure the emulator is selected and it doesn't try to deploy using Zune software (in case you actually have a windows phone or a zune player perhaps).


Ok, so when the emulator opens, it will load all the assemblies and then open your app, which should look like this:


Feel free to click the "Get Items" button, but you will get the "endpoint not listening" error (see Part 2 for explanation). So use your mouse to click on the Windows button. Once in the main menu, open internet explorer.


In internet explorer (after click away the privacy notice from Microsoft), click the URL bar at the bottom and type in the URL of the certificate.zip file. Now, I will save you some typing (clicking - since the windows keyboard doesn't seem to be supported) here. For development purposes, the windows phone emulator re-routes "localhost" to your computer running visual studio, rather than localhost being the windows phone device itself. So, to get to the certificate, if you followed the naming of my articles, the URL should be https://localhost/WP7/certificate.zip (don't forget the "S" at the end of https). Click the white button with the arrow on it. You will get a warning from IE and just click continue.


When I do this the first time, I get an error "can't download the file". If someone can explain why this is, feel free to leave a comment. In any case, if you click the URL bar at the bottom again, it will pop up with the URL still in it, and if you hit the white arrow again, it will actually work... (not sure what this is all about)


This will open the ZIP file on screen, and will show you the certificate.CER file contained within. Click the CER file, and you will be prompted with the details. Click the "Install" button at the bottom. This will confirm it's installed, just click OK.


Once this is done, click and HOLD the back button at the bottom. This will bring up the task switcher. Click on your APP (you can swipe the screen to get to it) and this will switch back to your app.


Back in your app, you can now click the "Get Items" button, and after a few seconds it should display your item numbers 10000 through 10005 (assuming you have those, remember we hardcoded the range). If your app doesn't react to clicks on the username field or the item button, make sure you have set the Grid.Row property of the Grid/ContentPanel to "2". Else you have two overlapping controls and it gets stuck basically (guess how I know this).


A word of advice. If you close the emulator screen, you will LOSE the certificate installation and have to repeat the process every time. So rather than closing it, go to Visual Studio and STOP debugging to close the app. Next time you wish to run your app, just hit F5 again, and the emulator will just pop back up. But if you close it, you'll have to reinstall the certificate.


So (63 screenshots and some sleep deprivation later) that concludes our Windows Phone 7 app. Your mileage may vary on the development being 10 minutes, but at least the intent was there. And the windows phone app itself was probably about 10 minutes, no? :-) The setup and potential pitfalls is what makes this tough.

Hope you enjoyed this one, I know I did (once it was working!). Please drop me a line on my blog and let me know if you have this running, if you have feedback of any kind.

Monday, November 28, 2011

10-Minute App - WCF service for Windows Phone 7

This is Part 2 in the Windows Phone 7 app. Due to length of the articles, the "10 minutes" is split up in three articles. Part 1 talks about setting up IIS to support the intermediary WCF service.


After an explanation on the trusted intermediary in AIF, and the IIS setup needed to be able to run our WCF service for use with Windows Phone 7 (WP7), we're ready to code! We will create two Visual Studio projects, one is the WCF service that consumes the original AIF service and exposes it back out again (translating the authentication in the process). The second project is the actual WP7 app consuming our WCF service to display the AX data.

Part of the trusted intermediary article was setting up the AIF service enhanced port for item data and allowing a trusted intermediary for that web service. We will re-use that in this article, so if you haven't done so already, please go through the article for the setup.
Also a must is the setup necessary for IIS. You need to go through this setup first, before we can get into the code below.

First, the WCF application. To work with the IIS setup, you will need to start Visual Studio 2010 in administrator mode. To do this, right-click Visual Studio 2010 in your start menu, and select "Run as administrator". Once in Visual Studio 2010, create a new WCF project of type "WCF Service Application". I called my project "DAXMusings_WCF".

First thing is changing the setup to use our IIS setup instead of the built-in development server of Visual Studio. On the Project menu, select "DAXMusings_WCF Properties..." (if you named your project differently, you should see that here). In the properties window, select the Web tab.

Select the "Use Local IIS Web server", and enter the URL for the website we created, including a new sub-folder (I changed the default, which is the project name, to something short: WP7). Don't forget to use the FQDN (fully qualified domain name) that IIS used for the certificate! Also make sure you enter httpS to indicate it's an SSL site. If you setup the website on another port, make sure to add the port (for example if you used port 80443: https://myserver:80443/WP7).

Once entered, click the "Create Virtual Directory". This will create a new virtual sub-folder in the site, pointing to the output folder of your Visual Studio project. Unfortunately, IIS assigns the default application pool to it, so we'll need to go back to IIS and change the application pool. Under administrative tools, open "Internet Information Services (IIS) Manager". Under sites, browse to the site we created (if you followed to the letter, this will be called "DAXMusings"), and click on the new virtual directory called "WP7". On the right-hand side panel, select "Advanced Settings".

In the application pool setting, click the ellipsis and select your application pool and click OK. That's it.

Back in Visual Studio, we'll add a reference to the AX 2012 AIF service we've setup in the trusted intermediary article article. Check back there what to setup and how to find the WSDL URL to use.
To add the service reference, right-click on References in your project and click "Add Service Reference".

On the dialog, type in or paste in the address for the item service WSDL and click the "Go" button. In the namespace field, type "ItemService". Click OK to add the service.

Now, there is a catch which took me a long time to figure out. By default, the proxies are generated for the item service from AX. My idea was to just re-use those objects for this WCF service. They are already a data contract, plus the service from AX will return the object, so you can just pass it along. Well, until the WP7 app tries to consume it. You will get the following error:
Inner Exception: Type 'System.ComponentModel.PropertyChangedEventHandler' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute.
Apparently this is a SilverLight issues, but it took me a while to figure out how to circumvent it. Turns out it's all in the proxies generated by the service reference we just added. By default, the reference tries to be helpful and adds events for property changes, so the proxy objects return from the service can be used for data binding and other cool stuff. But that is exactly what we cannot pass along to a silverlight service without making it part of the data contract. Since the data contract is auto-generated, we're stuck. I finally found a helpful blog post explaining how to turn off the automatic addition of the events. To do this, right-click your project and select "Open Folder in Windows Explorer". In the folder, you will find the "Service References" folder, inside of it, the ItemService folder.

In this folder, we need to edit a file called "Reference.svcmap". You can edit this file in notepad or even in Visual Studio, it's an XML file. In the XML file, the second field is called "EnableDataBinding" and is set to true. Setting this to false will avoid the service proxies having the notification properties.

Save the file and close it. Back in Visual Studio, right-click the service reference "ItemService" and select "Update Service Reference". This will regenerate the proxies and effectively remove the events.

Ok, so now to the code. We need to change the service interface (IService1), and then the implementation itself as well. Open the IService1.cs file by double clicking on it in the project.

To cut things short, all we want to do is add a method to the interface (feel free to clean up the rest, we won't use it). We'll return an array of InventTable records coming from the AIF service, so add the following line under the "TODO: add your service operations here" comment:
Click here for full code screenshot
[OperationContract]
ItemService.AxdEntity_InventTable[] GetItem(string username, string itemIdFrom, string itemIdTo);

As you can see, we're cheating on the authentication here by just passing in the username as a parameter to the operation. No password here either. Please look into proper authentication mechanisms for WCF (I know I am). As I said in the previous article, a good place to start is this article on MSDN.
As far as the operation, we'll use the "Find" method of the AX service which can use a range of filters, so we'll do a from and to value for the find range.
Next in the Service1.svc file, we want to implement this new operation inside the Service1 class, as follows:
Click here for full code screenshot
public ItemService.AxdEntity_InventTable[] GetItem(string username, string itemIdFrom, string itemIdTo)
{
 ItemService.AxdItem item = null;

 ItemService.ItemServiceClient client = new ItemService.ItemServiceClient();
 ItemService.CallContext context = new ItemService.CallContext();

 context.Company = "CEU";
 context.MessageId = Guid.NewGuid().ToString();
 context.LogonAsUser = String.Format("DAXMusingsAuth\\{0}", username);

 try
 {
  ItemService.QueryCriteria criteria = new ItemService.QueryCriteria();
  criteria.CriteriaElement = new ItemService.CriteriaElement[1];
  criteria.CriteriaElement[0] = new ItemService.CriteriaElement();
  criteria.CriteriaElement[0].DataSourceName = "InventTable";
  criteria.CriteriaElement[0].FieldName = "ItemId";
  criteria.CriteriaElement[0].Operator = ItemService.Operator.Range;
  criteria.CriteriaElement[0].Value1 = itemIdFrom;
  criteria.CriteriaElement[0].Value2 = itemIdTo;
  item = client.find(context, criteria);
 }
 catch (Exception ex)
 {
  Console.WriteLine(ex.Message);
  throw ex;
 }

 return item.InventTable;
}

As you can see this uses the context for the intermediary user (read the article if you haven't already!). We re-throw any errors coming back from AIF, otherwise we return the InventTable datasource coming from AIF... Ok, last thing to do is actually tell WCF we want to use https and basic authentication. To do that we need to change the Web.config file (double-click on the Web.config in your project). First, we need to add a section for basic http binding. Inside the "bindings" node, after the </netTcpBinding> node, add the following:
<basicHttpBinding>
        <binding name="webBinding">
          <security mode="Transport" />
        </binding>
      </basicHttpBinding>

Next, under behaviors/servicebehaviors we'll add the following node after the </behavior> :
<behavior name="ServiceBehaviors">
          <serviceDiscovery/>
          <serviceMetadata httpsGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>

Next, we add a services node with a service setup, linking to the basic http binding, the service behavior, and the data contract. If you used any other names for the service reference namespace make sure to change the service class name and the data contract interface name (shown in bold) below:
<services>
      <service name="DAXMusings_WCF.Service1" behaviorConfiguration="ServiceBehaviors">
        <endpoint name="Endpoint"
                  address=""
                  binding="basicHttpBinding"
                  contract="DAXMusings_WCF.IService1"
                  bindingConfiguration="webBinding"/>
        <endpoint kind="udpDiscoveryEndpoint" />
      </service>
    </services>

Lastly, at the top of the web.config, we need to remove the targetFramework attribute in the compilation node, so it looks like this:

I know this was a lot, so feel free to look at the actual web.config file as I'm using it. It's up for download here.
We're done with the WCF service. You can hit F5 to run the service. Nothing much to see, you can browse to your https site under /WP7/Service1.svc?WSDL to see if it's working. We'll need this URL later for the WP7 app itself.

On to the WP7 app!

10-Minute App - IIS Setup for Windows Phone 7

The final 10-minute app, this time for Windows Phone 7! I will be using a trusted intermediary, so if you haven't read that article yet, head on over here. You'll also need the Windows Phone 7 SDK installed. As with the Windows Azure app, there were some hurdles in this setup, mainly all the setup around IIS. Therefor the article is split up in two, first is this setup article, next will be the actual code.
If you missed the previous 10-minute articles, visit my blog for the Windows Presentation Foundation and the Windows Azure articles.

As I explained in the Trusted Intermediary article, mobile applications usually do not have access or support for active directory authentication. Which is exactly why we need an intermediary. For this article, we will need to create two visual studio projects:
1) A WCF service that consumes the actual AIF service using a trusted intermediary account, and exposes the AX AIF service out again with authentication of the consumer
2) A Windows Phone 7 (WP7) app that will consume our WCF service and display the results of the AIF service on the phone

The intermediary WCF service will need to authenticate the user. Unfortunately I'm still trying to figure out WCF authentication myself, and it would probably go beyond the "10 minutes" I'm aiming for anyway. A good start if you want to take this further would be MSDN. This blog article will give you all the basics, you just need to implement the authentication side properly.
That being said, for basic authentication to work, Windows Phone 7 requires you to use SSL. It will effectively ignore any credentials you try to pass if you try to use a basic http site. This is a security decision and makes sense, you don't want to be sending usernames and passwords in plain text around the internet. Unfortunately the Visual Studio built-in development web server ("Cassini") does not support SSL. So we'll have to change our Visual Studio solution to use IIS instead. No big deal, but a dent in my 10 minutes to go over this setup with you :-)

So first things first, which is setting up IIS. Our WCF service will run as whatever identity is used in the application pool for our website in IIS. Since our WCF service will call AX as a trusted intermediary, that means the application pool needs to run as the trusted intermediary user. Under administrative tools, open the Internet Information Services (IIS) Manager. Right-click on Application Pools and select "Add Application Pool".


Name the application pool (I chose DAXMusings) and make sure to set the .NET Framework version to 4.0 and the pipeline mode to classic.


Next, right-click on your new application pool and select Advanced Settings.


Under Process Model, click the ellipsis button on the Identity property. Select the "Custom account" and click the Set button. Set the username and password for your trusted intermediary in AX (make sure to prefix the username with the domain name and a backslash). Remember in a production environment things are different and security is top priority, and definitely don't use your personal account for the application pool.


Click OK until you get back to the IIS Manager. Next we'll need to create a certificate for our SSL site. Unless you want to shell out the big bucks for an actual certificate for your development server or laptop or whatever, we will just create a self-signed certificate.
Click on the root level (the name of your server), and in the Features View, double click on the "Server Certificates" icon.


In the Server Certificate pane, click the "Create Self-Signed Certificate..." link in the right-hand side menu. In the dialog that pops up, enter a "friendly name" for your certificate. I just entered the name of my laptop (everything runs locally on my laptop). You should see the certificate show up with an expiration date. Note that under "Issued To", IIS will have listed the FQDN (fully qualified domain name) of your server. You will need to use this later in the code, so make sure you know what the FULL name of your server is.


Double-click on your new certificate, or click the "View…" link on the right-hand side. On the certificate view dialog, click on the details tab. In the list, try to find the "Public key" row. When you click on it, the bottom part will show the key, and you can click the "Copy to file..." button.


On the first wizard page, just click next. Select the default option to NOT export the private key. Click next. Select the default option "DER encoded binary", click next. Select a location to save the .CER file, and click next. On the last page, just click the Finish button to save the file. This will save the public key to a file.


The reason we need this is a Windows Phone 7 "issue". For security purposes, Windows Phone 7 apps can only accept certificates signed by a trusted authority. We will need to install the certificate on your windows phone device emulator for the phone to accept the certificate at all. Without it, you will get the very detailed and inspiring error message:
System.ServiceModel.EndpointNotFoundException : There was no endpoint listening at that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
There is an open-source tool to install certificates on a WP7 device, but I found the easiest way to be providing the certificate file as a download on your website, so you can just download and install it on the WP7's internet explorer. As an FYI, I finally found what this error meant thanks to this blog post.

Next in our IIS setup, right-click on Sites and select "Add Web Site". On the dialog, give the site a name (internal name so not an important choice), and under the "Select" button select the application pool we created previously. Under Physical Path, select the ellipsis lookup button and create a new folder. The default path for IIS sites is on C:\InetPub, so I just created a new folder "DAXMusings" underneath. If you already have a website on the default port (443), you will need to change the port. Just make sure you remember that port number, we'll need it in code later. Under "SSL Certificate", select the certificate (friendly name) we created in the previous step. Click OK.


Finally in this setup, we need to put the CER file in a zip file to be able to install it on the WP7 device. Locate the .CER file we created from the server certificate, and right-click it, select "Send To", and select "Compressed (zipped) folder". If you have any other means of creating a zip file, feel free to use that instead. Move the new ZIP file (which I called "certificate.zip") to the new folder you created called "DAXMusings".


I think we're finally ready to get coding!