Using WCF Services with Smart Client Application

WindowsMobileLogo The current project I am assigned to at work is Smart Client application running own Windows CE that communicates with WCF Services that it uses to communicate with SAP via BizTalk Services.  We choose to use WCF because of the power that we felt it would bring to the solution.  What we didn’t realize was the limited support in Visual Studio for consuming WCF Services for a Smart Client application.

In a WinForms application you have two choices to add an Application Reference to your project you can use the SvcUtil.exe or you can right click on the References node of the solution and select Add Application Reference.  In the Smart Client world you don’t have either option, you can try to use the SvcUtil.exe but it will not create a proxy that can compile against NetCF libraries because NetCF does not include all the classes referenced from that source code.

Fortunately we found the Power Toys for .NET Compact Framework 3.5 which contains NetCFSvcUtil.exe that could be used to generate NetCF complaint service proxies.  Once install the power toys you will find the NetCFSvcUtil.exe in the C:\Program Files (x86)\Microsoft.NET\SDK\CompactFramework\v3.5\bin directory.

We setup a batch file to generate the service files for us.  So, all we had to do was make sure we check out the files and then run the command file to update the proxies and check the files back in and we are good.

You should be aware that NetCF does not support all WCF Bindings, it supports: BasicHttpBinding, CustomBinding, WindowsMobileMailBinding, and ExchangeWebServiceMailBinding.  Andrew Arnott has a post about The WCF subset supported by NetCF and other good information.

A good friend and member of our team Devlin Liles, has put together a great post, Batch File and Command File running in Visual Studio, to show how you can execute a command file from the Visual Studio IDE and use the output window for any text.  I highly recommend you check it out.

NetCFSvcUtil.exe http://localhost/MyService.svc

This will generate the CFClientBase.cs and the MyService.cs files we need to access the WCF Service.  If you want to control the namespace that the proxies get created in you can use the /namespace argument to specify this.

NetCFSvcUtil.exe namespace:*,MyNameSpace.Proxies http://localhost/MyService.svc

Likewise you can also control where the files are generated by using the /directory argument.

NetCFSvcUtil.exe namespace:*,MyNameSpace.Proxies http://localhost/MyService.svc /directory:../MyApp/Proxies

There are a lot of other options you can use to control how the proxies are generated you can execute NetCFSvcUtil.exe /? to see all of them and what they do.

This gets you up and running with WCF Services in a Smart Client application, without the robust configuration that is offered with WinForms or WebForm projects.  In my next post I will walk you through how we configured our WCF Service endpoints and set some custom binding information to control how our clients behaved when consuming the services.

How I Got Started Programming

This is something I have wanted to do for a long time, and just decided that this it the time.  I saw this first on Michael Paladino’s blog.  I always wished I would get called out, but since I didn’t I am calling myself out.  I am also calling out a few others to share their story, and I hope you will pass it on to your closes enemies, eh I mean friends. ;-)

How old were you when you started programming?

In my senior year of High School I was overjoyed to be able to take a 1/2 semester programming class.  The computer class had 11 TRS-80 computers where 1 was the main host.  That meant that we all had to share the floppy drive on the host computer for saving data to disk.  It was a basic programming class, of which I still have some of my code.

How did you get started in programming?

When I got to college I of course was seeking a computer degree.  There I took all of the standard programming classes for my field which included a lot of Pascal programming, but I think I learned the most writing IRCII bots to share files and keep the channel ops in line. 

What was  your first language?

I would have to say that first language I developed in was Pascal or IRC Script.

What was the first real program that you wrote?

During college I was working a our local Wal-Mart and got the chance to go work in their Information System Division.  After working there for about a year I was moved to a programming team and started using Visual Basic (starting with version 3) to create reporting tool was used to monitor the health of the companies system by analyzing help desk ticket information.

What languages have you used since you started programming?

I have spent time in several languages since then, C/C++, Perl, Visual Basic v3-6, ASP Classic, C#, VB .NET, and a short year working with Java.

What was your first professional programming gig?

As I mentioned earlier, creating reports with Visual Basic at Wal-Mart was my first paid programming gig.  I learned a ton from my mentor John Lafoon, who I owe a great debt for setting me on my programming path.

If you knew what you know now, would you have started programming?

Heck yeah!!! I consider myself lucky that I get to do all day what I would be doing if I was independently wealthy had free time on my hands.  A friend of mine, I believe it was Raymond Lewallen, stated like this, “I am a professional problem solver who has chosen software as the tool of choice”.  I love learning and improving my development craftsmanship and spend as much time at home as I do at working improving my skills.  Really that just means I have a lot things to improve.  I like to say “I am failing my way to success” :-)    

If there was one thing you learned along the way that you would tell new developers, what would that be?

Be a practitioner of your craft, practice your craft and keep your axe sharp.  Set out to learn the fundamentals of your craft don’t just skim the surface to gain enough knowledge to get the job done.  Be a proactive programming, too much of the time programmers are reactive. I need to perform task X lets get the book and hit the reference section and find the example to get me past this hurdle.  This path has little learning, learn enough about your craft so that when the problem arises you already have enough information to formulate the correct action to solve the problem.  In short study and practice your craft.

What’s the most fun you’ve ever had…programming?

For the past two years I have attended the We Are Microsoft Charity Challenge, a give camp event, in the Dallas area.  Where developers come together for a weekend to produce web project for charities.  It is awesome to see dev teams put together produce the awesome project they do in such a short period of time.
Tag, you’re it!

I’ve enjoyed hearing other people’s stories, so I think I ought to keep this going.  I’m going to call out:

Blog Settings: Turning Off Comments

I have been thinking about this for a long time and finally decided to make the jump.  I am turning off comments on my blog.  I don’t have very many readers and those of you that do read my blog know me and would contact me via email or phone.  The comments I usually get are from link bots trying to drive traffic to their sites and never add anything to the discussion.

I have tried turning comment moderation and on and adding the Akismet extension for blogengine.  With that I still get an email that requires some action on my part, mostly because of the moderation rather than Akismet I am sure.

Maybe if my blog gets more popular and the need for comments arises I will consider turning them on again but until them I am going leave them off and dedicate the time I was using to deal with the few comments I was getting to more value added activities, like writing more post ;-).

Community: SharePoint Saturday Ozarks

SharePointSatOzarks

SharePoint Saturday Ozark is a one day educational, informative, and lively day filled with sessions from respected SharePoint Professionals and MVP’s. The event was held on July 18th at the South Campus of the North Arkansas College in Harrison, AR, a beautiful vibrant city located in the heart of the Ozark Mountains. The event was organized by Mark Rackley, The SharePoint Hillbilly and member of the Ozark .Net User Group. Over 75 attendees turned out for over 25 sessions covering all aspects of SharePoint from custom development, administration, and branding. There were even a few sessions for .NET Developers.

The event was fantastic, not only where the sessions awesome in every track, it was a great to see how the SharePoint community is coming together and growing. There were lots of great conversations regarding SharePoint and community going on outside the sessions and continued at the SharePint. A SharePint is an after party event where attendees and let their hair down and relax. The SharePint for this event was held at Hotel Seville which was built in 1929.

To find out more about SharePoint Saturday or to get started organizing one in your area be sure to check out the SharePoint Saturday website at http://sharepointsaturday.org. The SharePoint website also list dates and locations for other SharePoint Saturday events. Mark has also posted a great article titled Organizing a SharePoint Event: What you need to Know to help get you started, it is a great overview of the process of putting on a regional event.

I would like to thank Mark Rackley and the SharePoint Saturday event staff for putting on an awesome event and I look forward to SharePoint Saturday Ozarks 2010. I hope to see you there.

This write up also appears on the INETA August Newsletter: here

View previous INETA Newsletters and sign up to receive them via email

Modify Log4Net AdoNetAppender Connection String at run-time

Log4Net

In my every day development I always have to figure out ways to keep my connection information in sync with the environment my application is deployed to.  We currently go through 3 environments; Dev, Test, and Production.  Each with a different set of database and service connections.  Today I was working on setting up Log4Net to use the AdoNetAppender and wanted to have it’s connection string move with my ApplicationSettings so that it would point to the appropriate database for the environment.  After about 3 hours of searching and code pounding I came up with a solution and since it was so hard to find I wanted to share what I learned.

First a little background of how my application is setup.  I have created the following application settings;

  • RunEnvironment: used to show where we are deployed, valid values are Development, Test, or Production
  • Database_Development: stores the database connection for development
  • Database_Test: stores the database connection for test
  • Database_Production: stores the database connection for Production

I also have a static ApplicationSettings class like this:

   1:  using System.Collections.Specialized;      
   2:  using System.Configuration;      
   3:   
   4:  public static class ApplicationSettings
   5:  {
   6:      private static readonly NameValueCollection Settings = ConfigurationManager.AppSettings;
   7:   
   8:      public static string RunEnvironment
   9:      {
  10:          get { return Settings["RunEnvironment"]; }
  11:      }
  12:      
  13:      public static string DatabaseConnectionString
  14:      {
  15:          get { return Settings["Database_" + RunEnvironment]; }
  16:      }
  17:  }

This approach allows me to just ask ApplicationSettings for the DatabaseConnectionString and it is always adjusted for the correct RunEnvironment.

Ok, so now to the Log4Net goodness.  I used the XML Configuration in my app.config to configure Log4Net and tried several ways to get the currently active configuration and manipulate it to reflect the new database connection string.  The solution that finally worked was to implement my own AdoNetAppender derived from the AdoNetAppender and override the ConnectionString Property.

Here is the new CustomAdoNetAppender class:

   1:  using log4net.Appender;
   2:   
   3:  public class CustomAdoNetAppender : AdoNetAppender
   4:  {
   5:      public new string ConnectionString
   6:      {
   7:          get
   8:          {
   9:              return base.ConnectionString;
  10:          }
  11:          set
  12:          {
  13:              base.ConnectionString = ApplicationSettings.DatabaseConnectionString;
  14:          }
  15:      }
  16:  }

 

The next step, which was left out of many of the post regarding this matter, was to modify the Log4Net configuration in your app/web.config to use the new CustomAdoNetAppender like below:

This must be added to the Configuration->ConfigSections of you config file

<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />

After the Configuration->ConfigSections and at the same level in your config file add the Log4Net

   1:  <log4net>
   2:      <appender name="CustomAdoNetAppender" type="MyCustomNamespace.CustomAdoNetAppender">
   3:        <bufferSize value="100" />
   4:        <connectionType value="System.Data.SqlClient.SqlConnection, System.Data,  />
   5:        Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
   6:        <connectionString value="data source=[DbServer];initial catalog=[DbName]; />
   7:        integrated security=false;persist security info=True;User ID=[DB_USER];Password=[DB_PASS]"
   8:        <commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message],[Exception])  />
   9:        VALUES (@log_date, @thread, @log_level, @logger, @message, @exception)"
  10:        <parameter>
  11:          <parameterName value="@log_date" />
  12:          <dbType value="DateTime" />
  13:          <layout type="log4net.Layout.RawTimeStampLayout" />
  14:        </parameter>
  15:        <parameter>
  16:          <parameterName value="@thread" />
  17:          <dbType value="String" />
  18:          <size value="255" />
  19:          <layout type="log4net.Layout.PatternLayout">
  20:            <conversionPattern value="%thread" />
  21:          </layout>
  22:        </parameter>
  23:        <parameter>
  24:          <parameterName value="@log_level" />
  25:          <dbType value="String" />
  26:          <size value="50" />
  27:          <layout type="log4net.Layout.PatternLayout">
  28:            <conversionPattern value="%level" />
  29:          </layout>
  30:        </parameter>
  31:        <parameter>
  32:          <parameterName value="@logger" />
  33:          <dbType value="String" />
  34:          <size value="255" />
  35:          <layout type="log4net.Layout.PatternLayout">
  36:            <conversionPattern value="%logger" />
  37:          </layout>
  38:        </parameter>
  39:        <parameter>
  40:          <parameterName value="@message" />
  41:          <dbType value="String" />
  42:          <size value="4000" />
  43:          <layout type="log4net.Layout.PatternLayout">
  44:            <conversionPattern value="%message" />
  45:          </layout>
  46:        </parameter>
  47:        <parameter>
  48:          <parameterName value="@exception" />
  49:          <dbType value="String" />
  50:          <size value="2000" />
  51:          <layout type="log4net.Layout.ExceptionLayout" />
  52:        </parameter>
  53:      </appender>
  54:      <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
  55:        <layout type="log4net.Layout.PatternLayout">
  56:          <param name="Header" value="[Header]\r\n" />
  57:          <param name="Footer" value="[Footer]\r\n" />
  58:          <param name="ConversionPattern" value="%d [%t] %-5p %m%n" />
  59:        </layout>
  60:      </appender>
  61:      <root>
  62:        <level value="DEBUG" />
  63:        <appender-ref ref="CustomAdoNetAppender" />
  64:        <appender-ref ref="ConsoleAppender" />
  65:      </root>
  66:    </log4net>

You can see on line 2 that we specified our new CustomAdoNetAppender as the name and pointed the type to MyCustomNamespace.CustomAdoNetAppender.  This tells Log4Net what class to use and where to find it.

Now you have a Custom AdoNetAppender that gets the database connection from your application settings at run-time.

Calendar

<<  May 2024  >>
MonTueWedThuFriSatSun
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

View posts in large calendar

Widget Category list not found.

Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))X

Tag cloud

    Widget Month List not found.

    Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))X

    Widget AuthorList not found.

    Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))X

    Widget TextBox not found.

    Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))X