January 2008 Entries

Overview

I reckon that I have probably seen the same LINQ demo as just about everyone else in the world.  You know, the one where you get a list of all of the processes running on the server and print them out to the console as follows:

var processes = from activeProcesses in Process.GetProcesses() 
                select new { Name = activeProcesses.ProcessName, ProcessId = activeProcesses.Id };

foreach (var row in processes) Console.WriteLine(row.ToString());

Console.ReadLine();

Well, I tired to use the same principle to iterate through a custom collection for an idea I was trying out and I got a heavily descriptive error of:

"Error 19 Could not find an implementation of the query pattern for source type"

So what does that mean?

Solution

It can actually mean a couple of things depending on the full error message.  The two main causes that I have noticed are:

  1. Your source is not enumerable!!
  2. LINQ doesn't have a clue what your source is.

The first issue is fairly easily addressed, make sure you use enumerable types.  It turns out that in the example I was trying to make work, I'd used the wrong object as the source which was why I got the error in the first place. 

Once I had changed to the correct object, I still had the error.  The difference was that the error message now also included the following

"Consider explicitly specifying the type of the range variable"

Interesting I thought, why on earth would that be?  The code I had originally was as follows:

var pollingDirectories = from directory in serviceConfigSection.PollingDirectoires 
                select new { DirectoryPath = directory.Path, FileType = directory.FileType };

foreach (var row in pollingDirectories ) Console.WriteLine(row.ToString());

Console.ReadLine();

What I need to to was to tell LINQ the type of source explicitly so that it would know what to do with it.  So I needed to make my code look as follows:

var pollingDirectories = from DirectoryElement directory in serviceConfigSection.PollingDirectoires 
                select new { DirectoryPath = directory.Path, FileType = directory.FileType };

foreach (var row in pollingDirectories ) Console.WriteLine(row.ToString());

Console.ReadLine();

After that - everything seems to work just fine. 

I guess in some cases, LINQ just needs to be given a little more information about what it is doing. 

References

Versions

Metadata

  • Categories: .Net Framework 3.5, Visual Studio 2008, Orcas, LINQ
  • Additional Keywords: Orcas, LINQ, Error 19, Enumerable, IEnumerable

Bookmark with :
Digg It! DZone StumbleUpon Technorati Reddit Del.icio.us Newsvine Furl Blinklist

Overview

For a while now, I have been working on a project that uses a helper class to send any error emails out that may occur during document processing.  In order for the helper class to know the recipient and sender for the emails, I have been relying on a custom configuration file which is retrieved from the registry.  Now, I inherited this project, and whilst the configuration file was originally used for a great deal of settings, it is now only used for these email addresses.

Now - I'm actually running two versions of the same BizTalk Server solution in different applications on the same server.  As such, my method of locating the correct configuration file is not suitable.  So I start thinking:

Perhaps I should try using the SMTP Adapter to send my emails, I wonder how that works?

Solution

The first thing that we need to do is to configure the SMTP adapter.  Rather then delve too deep here, I'm just going to set 'lazy' values that will work for me, you'll probably need to get decent values of you IT services team.

  1. In the BizTalk Server Administrator, navigate to BizTalk Server 2006 Administration > BizTalk Server Group > Platform Settings.
  2. Double-click SMTP and then Right-click on BizTalkServerApplication (this may differ depending on your host name) and select Properties.
  3. In the General tab, click Properties.
  4. Fill in the details you need.  For this example, I have just used the following:
  5. SMTP Server Name localhost
    From (e-mail address) nottelling@you.com
    Server Authentication Do not authenticate

That should be enough to allow you BizTalk Server to send emails to the world (or at least to the mail queue).

We're going to need something to kick off the process, so I'll just have a receive port name 'SMTP Test Receive Port' with a receive location (I usually just use a file receive location for this type of thing, but just use whatever is easier for you)

Now I need to create a port that will create the emails to send.  To try this in its simplest form, I created a one-way send port that used the SMTP adapter for the primary transport.  So, lets do it:

  1. In BizTalk Server Administrator, navigate to BizTalk Server 2006 Administration > BizTalk Server Group > Test BizTalk Server Application > Send Ports.
  2. Right-click in the right pane and select New > Static One-Way Send Port....
  3. Give the port a nice name and then select the transport type as SMTP. Then click Configure.....
  4. In the SMTP Transport Properties dialogue General tab, set up a To address (and CC if you would like) and a subject for the email.  In this example, I'm not using any notification.
  5. In the SMTP Transport Properties dialogue Compose tab, set email body to Text and type something appropriate.
  6. In the SMTP Transport Properties dialogue Attachments tab, set Remaining BizTalk Server message parts to Attach all parts.
  7. Click OK.
  8. In the send port properties, add a filter on BTS.ReceivePortName is that of the Receive Port we created earlier ('SMTP Test Receive Port').
  9. Click OK.

Enable the receive location(s) and enlist and start the send port.  If we supply the receive location with a file/message then we should get an email sent through to the email address that we set up.  If the email doe snot arrive and BizTalk Server is not reporting any errors, you may need to talk to you IT Services team.

Now, that is the simple way to send an email, but at a guess, most people don't want all emails to have the same subject, body and recipients. 

How do we go about modifying these things from an orchestration?

It's actually quite simple, there are a number of properties available on the port inside orchestrations that may be set at run-time.  It's not thoroughly easy to find information about these properties if you just use Google, so you can find a link to the list of the SMTP adapter properties at the bottom of this article.

Using an expression shape (this will need to be inside a message construction),  you can just set the properties as follows:

Message_1(SMTP.Subject) = "I was set in the orchestration";
Message_1(SMTP.EmailBodyText) = "Hello, Mum!";

It is pretty much that simple. 

There are some properties you can't set (such as recipient), as these are specifically set in the send port, but you can add a CC.

Versions

References

Metadata


Bookmark with :
Digg It! DZone StumbleUpon Technorati Reddit Del.icio.us Newsvine Furl Blinklist

There seems to be a trend at work to use Microsoft Live Writer to create posts at the moment, so I though I would be a good little sheep and install it myself to have a  look. So off I went to the page to go and download Live Writer for myself.

There I ran in to a problem, I could not seem to get the installer to work.  You don't simply download and then install, you effectively install through Windows Update.

The install application sat there for a few minutes attempting to see what 'Live' applications I already had installed on my machine.  Then it told me that it had failed and that was the end of it, although I could try later if I wanted too.

Naturally, I wanted to know why it did not install.  My initial though was, it must be our firewall.  But other people in the office had installed it OK, so that could not be the case.

The next logical thing to do was to check the event log, which delivered some delightful insight in to the problem:

The description for Event ID ( 5000 ) in Source ( WindowsLiveSetup ) cannot be found. The local computer may not have the necessary registry information or message DLL files to display messages from a remote computer. You may be able to use the /AUXSOURCE= flag to retrieve this description; see Help and Support for details. The following information is part of the event: wlsetupdiagnostic, windows live sign-in assistant, 4.200.520.1, onsetupjobsourceresolutionend_ 0x80072efd, 12.0.1471.1025, NIL, NIL, NIL, NIL, NIL, NIL.

As usual with a lot of error messages, the only real course of action was to pick the error code 0X80072EFD and google it.  The most useful article I found seemt o be this one:

You may receive an "Error 0x80072EE2," "Error 0x80072EE7," "Error 0x80072EFD," "Error 0x80072F76," or "Error 0x80072F78" error message when you try to use the Windows Update Web site or the Microsoft Update Web site

"Super", I think to myself and merrily go about my way checking all of the things it tells me to check.  Problem is, once I've checked everything, it still will not install.

My next course of action was to look at the Windows Update service itself.  Perhaps something is wrong with that?  Looking in %WINDIR% will reveal a file called WindowsUpdate.log.  In here we can see all of the information about the update service and what it thinks it is doing.  Now nine was full of things like:

Bypass List used : <(null)> Auth Schemes used : <>
2008-01-12    09:23:24:046    1564    360    Misc    WARNING: WinHttp: SendRequestUsingProxy failed for <
http://beta.update.microsoft.com/wsus30b2/microsoftupdate/redir/wsus30b2muredir.cab>. error 0x80072efd
2008-01-12    09:23:24:046    1564    360    Misc    WARNING: WinHttp: SendRequestToServerForFileInformation MakeRequest failed. error 0x80072efd
2008-01-12    09:23:24:046    1564    360    Misc    WARNING: WinHttp: SendRequestToServerForFileInformation failed with 0x80072efd
2008-01-12    09:23:24:046    1564    360    Misc    WARNING: WinHttp: ShouldFileBeDownloaded failed with 0x80072efd
2008-01-12    09:23:57:234    1564    360    Misc    WARNING: Send failed with hr = 80072efd.
2008-01-12    09:23:57:234    1564    360    Misc    WARNING: SendRequest failed with hr = 80072efd. Proxy List used: <(null)>
2008-01-12    09:24:18:250    1564    360    PT    WARNING: PTError: 0x80072efd
2008-01-12    09:24:18:250    1564    360    PT    WARNING: PTError: 0x80072efd
2008-01-12    09:24:18:250    1564    360    PT    WARNING: Initialization failed for Protocol Talker Context: 0x80072efd
2008-01-12    09:24:18:250    1564    360    Agent      * WARNING: Failed to synchronize, error = 0x80072EFD
2008-01-12    09:24:18:328    1564    360    Agent      * WARNING: Exit code = 0x80072EFD
2008-01-12    09:24:18:328    1564    360    Agent    *********
2008-01-12    09:24:18:328    1564    360    Agent    **  END  **  Agent: Finding updates [CallerId = WLSetupSvc]
2008-01-12    09:24:18:328    1564    360    Agent    *************
2008-01-12    09:24:18:328    1564    360    Agent    WARNING: WU client failed Searching for update with error 0x80072efd

Fun, eh? No.

I could not see why I could not get these CAB files.  The thing I didn't like was that it said 'http://beta.update.microsoft.com'.  Somehow that sounded quite dirty to me and made me think that perhaps my version of Windows Update was a little screwed up.  As that was potentially a problem, I though I would go to the windows update site.

Going to the windows update site highlighted my problem; my windows update was hideously out of date and needed to be updated.  The reason for that was that I did not have automatic updates turned on, and so no updates had been applied since I had installed Windows.  This problem was made even worse when my Internet security settings were to high, so they had to be turned down to Medium-Low in order to install Windows Update.  Once that was all done (some forty or so patches later), Live Writer installed and I can now use it.

The moral of the story is to make sure you keep Windows up to date.  The error reporting could perhaps have been a little clearer, but essentially it was my fault for not keeping my OS up to date.  If anyone else has this problem, I hope this article helps.


Bookmark with :
Digg It! DZone StumbleUpon Technorati Reddit Del.icio.us Newsvine Furl Blinklist

As I've had a number of people mention to me that they don't quite know how to use a class that implements the IFormatProvider interface.  In most case that come to my attention, we are specifically interested in date formats and number formats.

Below is the code for a simple console application in .Net 2.0 that will use the NumberFormatInfo class to format the display of a numeric value.  I've set up two instances of the NumberFormatInfo class, one for French formatting and one for British English formatting.  The CultureInfo class from the Globalization namespace has been used to load up the culture specific information that I need for this example.

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;

namespace IFormatProvider
{
    class Program
    {
        static void Main(string[] args)
        {
            double testValue = 10.234;

            NumberFormatInfo britishFormatter = CultureInfo.CreateSpecificCulture("en-GB").NumberFormat;
            NumberFormatInfo frenchFormatter = CultureInfo.CreateSpecificCulture("fr-FR").NumberFormat;

            Console.WriteLine("In fr-FR, our value is {0}", testValue.ToString(frenchFormatter));
            Console.WriteLine("In en-GB, our value is {0}", testValue.ToString(britishFormatter));
            Console.ReadLine();
        }
    }
}

When you run the above code in Visual Studio, you will see the following output:

In fr-FR, our value is 10,234
In en-GB, our value is 10.234

This then got me thinking.  As I have now told the application what I want to do, I assume tha by default the ToString method on must have some kind of default based on the application thread.  I also know that the application thread has two sets of culture information; the UI culture and the system culture.  That led to the question; which is the default?

So I went ahead and wrote the following to see which culture information is the default.

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Threading;

namespace IFormatProvider
{
    class Program
    {
        static void Main(string[] args)
        {
            double testValue = 10.234;

            Console.WriteLine(
                "Default Culture information: UI [{0}] - SYSTEM [{1}]",
                Thread.CurrentThread.CurrentUICulture.Name,
                Thread.CurrentThread.CurrentCulture.Name
                );
            Console.WriteLine(
                "Our Value: {0}",
                testValue.ToString()
                );

            Console.WriteLine("> Change CurrentUICulture to French...");
            Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture("fr-FR");
            Console.WriteLine(
                "> Our Value: {0}",
                testValue.ToString()
                );

            Console.WriteLine("Change CurrentCulture to French...");
            Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("fr-FR");
            Console.WriteLine(
                "> Our Value: {0}",
                testValue.ToString()
                );

            Console.ReadLine();
        }
    }
}

Interestingly, the output is as follows:

Our Value: 10.234
> Change CurrentUICulture to French...
> Our Value: 10.234
> Change CurrentCulture to French...
> Our Value: 10,234

So, for the sake of interest; it looks like CurrentCulture is used as the default.

References



Bookmark with :
Digg It! DZone StumbleUpon Technorati Reddit Del.icio.us Newsvine Furl Blinklist

I've just installed Visual Studio 2008 so that I can start evaluating it for potential (read as 'as soon as we're allowed') deployment across the development teams here.  The very first thing that I notice was understandable but still rather disapointing.

As you may have read, Visual Studio 2008 will allow you to work with different .Net Framework versions (namely 2.0, 3.0 and 3.5). 

This is great, sort of. 

What I noticed was that the Solution and Project files are not compatible between Visual Studio versions.  Whenever you open a Visual Studio 2005 Project/Solution, Visual Studio 2008 will ask you to convert it to the new format.  You actually code itself does not change.

This isn't really a massive problem, but it does kind of mean that if you want to do the upgrade then all of your team members will need to be using the same version of Visual Studio to be able to work on the same projects. 


Bookmark with :
Digg It! DZone StumbleUpon Technorati Reddit Del.icio.us Newsvine Furl Blinklist
Recently, I've seen a couple of people having issues installing and indeed creating Windows Services.  I decided it would be a good idea to write an article about how to create a basic Windows Service and install it.

There is nothign fancy, the service really does nto do anything at all, but you can build it and install it; that is what I want to demonstrate.

So, if you've had trouble with installing a service you've created then read my article about creating and instaling Windows Services in C#.

Bookmark with :
Digg It! DZone StumbleUpon Technorati Reddit Del.icio.us Newsvine Furl Blinklist

I have always found that documenting BizTalk Server projects can be somewhat difficult and time consuming.  At that back of my mind, I’ve always wanted a tool that I could simply point at the installation and it would clear documentation for me.

While looking through Darren Jefford’s blog I happened across this article about 64 Bit BizTalk Documenter support.  Naturally, I opened the article, and installed the thing immediately.  It’s a great, basic little app that will create a help file for your BizTalk Server configuration.  It obviously does not elaborate on what a map does; it does give you the ins and outs of the overall plumbing of the project.  It’s certainly worth giving a try.

While documenting that fact that orchestration X subscribes to messages from port Y and that the orchestration uses assemblies A, B and C may be fairly straight forward, it’s a great step to reducing the amount of work that needs to be done in overall documentation.

As per Darren’s blog; the download for the documenter and some more information can be found here:

I did find that the first time I tried to run it, I got monaed at for not having the Help Compiler.  So here is a link to that too:

Enjoy

 


Bookmark with :
Digg It! DZone StumbleUpon Technorati Reddit Del.icio.us Newsvine Furl Blinklist
Recently, I was trying to go back and complete my blog about using web services in BizTalk without using orchestrations.  As is quite normal for me, my notes were generally bereft of any real detail and I could not for the life of me figure out how I managed to get Visual Studio to generate an XSD (and thus a schema to use in BizTalk).  It was simply written and 'Visual Studio will create the schema for me'; all very good and well but it was not creating one for me now.

In my attempts to try recreating the scenario whereby I could create the XSD from a web reference, I created a simple web service and added a web reference to an empty BizTalk project in Visual Studio.  I then started off looking through my notes to try and get an XSD out of the web reference.  Early on, a lot of my scribbled notes were about using xsd.exe, wsdl.exe and csc.exe.  These proved to be unfruitful in terms of actually generating a XSD file.

After a fair amount of head scratching I noticed something a little different with the web service that I had originally used and the simple test harness that I was using to try to replicate the creation of the XSD.  In my test harness, I was attempting to call a web service with a web method that accepted a string and an integer as it parameters.  In contrast, in my previous attempt, I had only one parameter that was a non-primitive type.  I noticed that the created XSD that I already had was a definition of the non-primitive type, rather than a definition of the entire SOAP method.  With that in mind, I updated my test harness web service and added a class to create a non-primitive for the parameter.  That was the ticket and when I refreshed the web reference, Visual Studio created an XSD file describing the non-primitive.

I then decided to take things a little further and added another non-primitive type to my web service that was employed by a new web method.  My hope was that this would create an additional XSD file for the new non-primitive.  Alas it didn’t quite work as planned and it created another root node in the existing schema.  I think there I will need to do some more investigation, but for the time being it allows me to continue investigating the use of web services without having to use orchestrations.

A few notes that may come in handy:
  • This method only works for non-primitive types.
  • The XSD files only get generate in BizTalk projects to my knowledge.
  • The generated XSD only generates schemas for non-primitive types that are used within the services public methods that are both public and serializable.
Relevant Technologies
References:

Bookmark with :
Digg It! DZone StumbleUpon Technorati Reddit Del.icio.us Newsvine Furl Blinklist