Questions on REST with MSMQ

Question:

I am looking for a solution for this situation - we have server, which hosts ASP.NET application with WCF REST API. We also have applications that post data to REST service. However, sometimes these applications are not online but data still needs to be transferred.
How could we use MSMQ binding when applications are offline? How to switch to MSMQ bindings when application is offline?
Both server and client applications use Windows Server 2003, IIS 6.0, .NET 3.5

Answers:

For your scenario, you want to use REST model for the main communication between client asp.net app and backend WCF service, but also use MSMQ when the service application is not available(for persist the requests), correct?
I think you can consider the following approaches:
1) The first idea is exposing two services(different endpoint) on the server. One is the original REST service which may not be available. And another service is using WCF msmq binding which(and turn on reliable and durable message features to ensure message reliabitliy). Thus, your client-side will need to determine the service availablility, if the REST service not available, turn to the MSMQ binding WCF service.  For using msmq binding in WCF, here are some resources.
#Queuing in WCF
http://msdn.microsoft.com/en-us/library/ms789048.aspx

#How Your WCF Service Can Use MSMQ as a Durable Message Store
http://www.devx.com/dotnet/Article/41482

#Sample Starter Project Using WCF and MSMQ
http://www.codeproject.com/KB/WCF/WCF_MSMQ_Integration.aspx
2) The second approach is directly using raw MSMQ programming(via System.Messaging namespace API), which send raw MSMQ message(when your wcf REST service not available), and your WCF service may also need to have a background task thread to monitor the MSMQ queue(which may contains message received during the offline time of the REST service).
For raw MSMQ programming in .NET, here are some useful articles:
#Programming MSMQ in .NET - Part 1
http://www.codeproject.com/KB/dotnet/mgrmsmq.aspx

#Leveraging MSMQ in ASP.NET Applications
http://www.15seconds.com/issue/031202.htm


Please remember to mark the replies as answers if they help and unmark them if they provide no help. Posted in: problems and solutions | Tags: questions answers q&a questions and answers msmq rest wcf reliability wcf service binding library message queue

log4net Dynamic Properties in XML Configuration.

I just learned about a new feature today of log4net that would have saved me a few hours of time had I known or been able to find this earlier.  I learned that you can have dynamic properties stored into log4net’s global context from code and then access them from the XML configuration file. This is useful in the case where dynamic configuration of log4net is needed.

My Case: I have been building console application that will run nightly to sync some integration records and I wanted to setup logging in order to see that status of the job and gather some reporting information (counts, time run, etc).  There was a catch though this process would run multiple times in a night but each time for a different customer.  This would make it difficult to read the logs for a particular customer as all I would have to go on is the file date and time.

I needed a way to break my log files into different customers yet retain the rolling file appender features of log4net.  My first pass at with was to configure log4net using the basic configurator all in code and create the appender, with a dynamic file name, and set the level of the logger programitacally. This was not my preferred way but was my only hope to getting the application out of developement. Then I found how to set properties into log4net’s global context and access them through the configuration file. I did run into a small problem that my app.config file was not being read in so I had to add these two variable to my assembly.

[assembly: log4net.Config.XmlConfigurator(Watch = true)]
[assembly: log4net.Config.Repository]

My goal was to make the file name dynamic based on the CustomerID passed into the application. Please not the file tag as it is the ticket to my case.

<log4net>
    <root>
        <level value="INFO" />
        <appender-ref ref="RollingLogFileAppender" />
    </root>   <!-- New Log File once per execution -->
    <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
        <file type="log4net.Util.PatternString" value="logs\logFile_%property{BrokerID}.txt" /> <!-- Awesomeness -->
        <appendToFile value="false" />
        <rollingStyle value="Size" />
        <maxSizeRollBackups value="-1" />
        <maximumFileSize value="50GB" />
        <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
        </layout>
    </appender>
</log4net>

Here is a sample of my log4net configuration section. Please note the file tag and type attribute to be log4net.Util.PatternString. The pattern of the value is important to, it must be %property{property_name} to get the right replacement. This is the ticket to dynamic values.

private static void InitLogger()
{
    //This is freaking awesome, put a property into the log4net context and using the 
    //  log4net.Util.PatternString type you can dynamically set values for the logging context from code.
    log4net.GlobalContext.Properties["CustomerID"] = (CustomerID!= 0) ? CustomerID.ToString() : "Error";
}

Here is an example of my small InitLogger. This method is the very first item to be called when the main routine starts up. All that needs to be done now is get a logger and start logging. A file will be created based on the CustomerID which in this case is retrieved from the command line arguments before InitLogger is called. If no CustomerID is passed in than the file will be to logFile_Error.txt

private static ILog Logger;   static void Main(string[] args)
{
    if (args.Length > 0)
        CustomerID= Util.GetInt(args[0]);   InitLogger();
    Logger = LogManager.GetLogger("Process");
}

Pretty cool I think, I hope this saves people some headaches. I wish I would have found this a few days ago. Oh well it is to my benefit to learn. Happy coding.

Posted in: programming problems and solutions | Tags: log4net dynamic dynamic properties dynamic property xml configuration configurator programitacally

Breaking Changes in asp.net MVC Preview

The following changes might cause errors in existing ASP.NET MVC 1.0 applications.

Installing ASP.NET MVC 2 Preview 2 Alongside ASP.NET MVC 1.1

The runtime component of ASP.NET MVC is shared by Visual Studio 2008 and Visual Studio 2010. If you have ASP.NET MVC 1.1 installed, you must uninstall it before you install ASP.NET MVC 2 Preview 2. Use the following steps to uninstall ASP.NET MVC 1.1 and install ASP.NET MVC 2:

1. From the Windows Control Panel, open Add/Remove Programs.

2. Uninstall Microsoft Visual Studio 2010 Tools for ASP.NET MVC 1.1

3. Uninstall Microsoft ASP.NET MVC 1.1

4. Install ASP.NET MVC 2

NGen Priority Change

When System.Web.Mvc.dll is installed in the Global Assembly Cache (GAC), the installer also invokes the NGen service to generate a native image. In previous versions of the installer, the service was invoked with a service request priority of 0, which caused the installer to create a native image immediately as part of the setup process. Many customers have reported problems where the NGen service fails, forcing the installation of MVC to be rolled back. These failures can usually be attributed to missing assemblies or corrupt entries inside the registry hive that is maintained by the CLR. However, the cost for customers is that they cannot install MVC until these issues have been addressed.

Starting with MVC 2 Preview 2, all the assemblies for which native images are created are queued by lowering the priority of the service request to 3. This will allow the installation of MVC to complete even if other problems arise, because native images for System.Web.Mvc.dll will be created only when the system is idle after the installation process.

Posted in: problems and solutions asp.net | Tags: asp.net asp.net mvc mvc 2.0 asp.net mvc framework system.web.mvc mvc 2 preview 2 priority ngen alongside

Complex class declaration confusing forms designer?

I have a class declared as:
public class Foo<T> : Panel where T : Control, IFooNode , new()
{
    ...
}

I added it by hand to test it, but I will eventually need something that can be displayed in the Forms designer. The Forms designer doesn't like this, it says:
Could not find type 'FooTestNameSpace.Foo'.
Please make sure that the assembly that
contains this type is referenced.
If this type is a part of your development project, make
sure that the project has been successfully built. 

Interestingly, I ALSO get a warning that is similar, but includes the generic type I used in my declaration of the variable. Warning is:

Could not find type 'FooTestNameSpace.Foo<FooTestNameSpace.FooNodeType>'.
Please make sure that the assembly that contains this type is referenced.
If this type is a part of your development project,
make sure that the project has been successfully built.

The declaration in my simple Form1 class is:

private FooTestNameSpace.Foo myFoo;

(FooNodeType is really just a subclass of Label that has one auxiliary property not yet being used; it does implement IFooNode).

So my question... With this type of set up, how can I get Foo to be displayed on the Forms designer, or at least get it to acknowledge that Foo is legit? Is there any Designer attribute that can handle this? I don't really care if my Foo control appears as an empty box, as long as it appears at all!

Answer:

 

class ConcreteFooCtl : FooCtl<FooNodeType>
{
}

class FooCtl<T> : Panel where T : Control, IFooNode , new()
{
}

The problem seems to be that the Forms designer can't handle any generic control. The forms designer can't handle FooCtl, but has no problems with ConcreteFooCtl. Not an ideal solution, but I think it's at least workable. Maybe the next version of VS will prompt the user to specify a generic type when adding a generic control to a form... ;)

Posted in: programming problems and solutions | Tags: foo forms designer declaration complex

Unable to read project file. Configured to use IIS

Converted a remote solution (resides on development server on intranet) from VS2003 to VS2005. Attempted to open solution from local client using VS2005 SP1 running on Vista. When I attempt to open the solution using VS2005, I get "Unable to read the project file 'proj1.vbproj.' The Web Application Project proj1 is configured to use IIS. Could not find the server 'http://remoteservername' on the local machine.

Belong to administrators group on local client. Ran VS2005 as administrator.

Went into Turn Windows features on and off in control panel on local Vista client and checked all IIS 6 compatability checkboxes as outlined in http://blogs.msdn.com/shahpiyush/archive/2007/06/01/3028325.aspx also, verified that ASP.net box is checked.

The solution is edit the .csproj with notepad and change this line :

<WebProjectProperties>
          <UseIIS>True</UseIIS>

To :

<WebProjectProperties>
          <UseIIS>False</UseIIS>

Posted in: programming problems and solutions | Tags: vsts iis project file webprojectproperties useiis compatability