Monday, April 28, 2008

Microsoft is offereing Visual Studio 2008 along with Windows Server 2003, Expression Studio, and XNA game studio at no cost to college students.  Visit the Microsoft DreamSpark site to register and download .  Enjoy.

Saturday, April 12, 2008

Disabling a range of dates on a calendar control is a great way to reduce data-entry error.  For example, imagine a scheduling system for an organization whose doors are open Monday through Friday.  Ideally, any calendar controls should disable Saturday and Sunday to prevent users from accidentally choosing them.  This can be accomplished by taking advantage of the ondayrender event of the calendar control.  First, in your aspx  markup, wire up a method to the event.

<asp:Calendar Visible="false" ID="DisabledWeekendsCalendar" runat="server" ondayrender="DisabledWeekendsCalendar_DayRender"></asp:Calendar>

Finally, in your .NET code, create the method which checks to see if a day is a weekend, and if so disables it.

protected void DisabledWeekendsCalendar_DayRender(object sender, DayRenderEventArgs e)
    {
        if (e.Day.Date.DayOfWeek == DayOfWeek.Saturday || e.Day.Date.DayOfWeek == DayOfWeek.Sunday)
        {
            e.Day.IsSelectable = false;
            e.Cell.ForeColor = System.Drawing.Color.Gray;
        }
    }

Tuesday, April 01, 2008

With Microsoft SQL Server 2005, paging on the database side is simple.  There is a built-in ROW_NUMBER function designed specifically for this task.  However, versions of SQL Server prior to 2005 do not have this capability.  Below is one way to implement similar functionality in pre-2005 versions. 

SELECT TOP X * FROM RECORDS WHERE RecordID NOT IN (SELECT TOP Y RecordID FROM RECORDS)

You must replace X and Y with actual integer values, Unfortuantly, due to sql sytanx, you can’t use varaibles.  The records returned from the above query will follow

Y + 1 = Beginning record
X + Y + 1 = Ending Record

So 10 and 20 plugged in to X and Y respectively would return records 21 thorugh 31.

Thursday, March 20, 2008

Microsoft just released the “Microsoft BizTalk Server Operations Guide” document.  They describe it as, “…detailed information for planning a BizTalk Server environment, as well as recommendations and best practices for configuring, testing, maintaining, monitoring, and optimizing this environment.”  You can view it from MSDN or download a copy for offline use.

Saturday, March 15, 2008

To debug a piece of .NET code called by the BRE you must first attach the Visual Studio debugger to the BRE process.   To accomplish this, open the debug menu and select “attach to process…” and select the Microsoft.RuleComposer process.  Now you can put breakpoints on the desired lines of .NET code and when the rule executes from the BRE, the execution will catch at the first breakpoint.
 
Facts can be asserted to the BRE from .NET code simply by passing them as an argument to the policy’s execute method which takes a variable number of parameters.  For example,

Microsoft.RuleEngine.Policy policy = new Microsoft.RuleEngine.Policy(“PolicyName”);
Policy.Execute(Object1, Object2,…);

There are three types of facts used by the BRE:  An xml document, a Database table, and a .NET class.  The latter two have a couple peculiarities about them which require further explanation. 

Asserting a Database Table

When using a database table, the BRE expects an object of type Microsoft.RuleEngine.DataConnection to be asserted, which tells the BRE where to find the table.  This is achieved with the below code.

//Create the DataConnection
System.Data.SqlClient.SqlConnection connection = new System.Data.SqlClient.SqlConnection(“connectionstring”);
Microsoft.RuleEngine.DataConnection dconn = new Microsoft.RuleEngine.DataConnection(connection);

//Create the policy and assert the DataConnection
Microsoft.RuleEngine.Policy policy = new Microsoft.RuleEngine.Policy(“PolicyName”);
Policy.Execute(dconn);

Static .NET Methods

Calling a static .NET method from the BRE can be achieved without asserting an instance of the class by setting the the StaticSupport (DWORD value) registry key located under HKEY_LOCAL_MACHINE\Software\Microsoft\BusinessRules\3.0 to a value of 1.  Without this registry entry, static method calls within the BRE will require asserting instances of the class that contain the method.
 
Even though the Business Rules Engine (BRE) is included with BizTalk 2006, it does not need to be exclusively called by the BizTalk host.  The BRE has a .NET API library that enables any host to communicate with the engine programmatically.
You must first reference the Microsoft.BizTalk.RuleEngineExtensions.dll from the BizTalk installation directory (the default installation is C:\Program Files\Microsoft BizTalk Server 2006).

You can then call BRE policies with the following code

Microsoft.RuleEngine.Policy policy = new Microsoft.RuleEngine.Policy(“PolicyName”);
Policy.Execute();

The execute method can take any number of objects as a parameter that need to be asserted as facts to the BRE for execution.

Thursday, March 06, 2008

If you are using the Business Rules Engine (BRE) as part of BizTalk or Windows Workflow Foundation and are asking yourself “Why are my rules firing in the wrong order?” you probably need a better understanding of how the BRE executes a set of rules (policy).  The priority property of a rule will control the order in which the action of that rule will fire relative to the other actions in a policy.  Specifically, an action of a rule with a higher priority will fire before an action of a rule with a lower priority.  Notice it is the action of a rule which is affected by the priority and not the evaluation of the rule.  The evaluations themselves will still occur in an arbitrary order.  For example, assume three rules exist in the same policy, “Rule 1”, “Rule 2”, and “Rule 3” with their priority properties set to 3, 2, and 1 respectively.   When the policy is invoked, Rule 2 may be evaluated, then rule 3, and finally rule 1.  Only after evaluation of all rules will the actions of the rules fire in the order specified by the priority values.  What are the practical consequences of this?  A rule dependent on the action of a previous rule within the same policy won’t evaluate as expected. 


There are a couple ways to overcome this problem.  The first is to place rules dependent on each other in separate polices.  This requires the host application to call multiple policies and to be knowledgeable about the order in which they should be called, a detail which should be abstracted from the calling process.  The second technique is to use an update action to let the BRE know an object has changed its state and that any rules that had evaluated this fact need to be re-evaluated.  The process look like this

  1. Execute all rules of a policy (these will be evaluated in an arbitrary order)
  2. Fire any Actions for any rules that evaluated to true  (these will be fired according to the rule’s priority property)
  3. Check if any facts used the update method to notify the BRE that a fact changed its state.
  4. Re-evaluate any rules that contained updated facts
  5. Repeat 2-4 until no facts are updated

Saturday, March 01, 2008

When moving Windows Workflow Foundation (WF) applications between dev/test/production environments, one of the first questions asked about the InvokeWebServiceActivity shape is how to dynamically change the URL of the web service call at runtime.  The appropriate place to implement this is in the Invoking event of the shape, since it is raised before the web request.  The below code will achieve this

Private void WebServiceInvoking(Object sender, InvokeWebServiceEventArgs e)
{
    NamespaceofWebServiceClass.ClassName objWebService;
    objWebService = (NamespaceofWebServiceClass.ClassName)e.WebServiceProxy;
    objWebService.Url = ConfigurationManager.AppSettings[“WebServiceURL”];
}

Saturday, February 09, 2008

Figuring out the credentials passed by an ASP.NET application hosted on an IIS server to a remote resource is a common question in the community forums. Typical errors associated with this type of enquiry are “Acces to the path ‘C:\YourFolder’ is denied” or “Login failed for user ‘username’. Reason: Not associated with a trusted SQL Server connection”. The context under which a thread accessing a remote resource is running under is a function of two settings, the identity element of the web.config file and the authentication settings in IIS.  With the combination of these options, one can arrive at any of the below security contexts.

Temporarily Impersonating

For security reasons, you may have a scenario where you want to impersonate only for a limited section of code and then return back to the application pool identity. To achieve this, Anonymous access must be disabled, else you will get the error “An anonymous identity cannot perform impersonation”. Next, impersonation must not be enabled in your web.config since we are impersonating programmatically. With these two conditions met, your code should look like this

//Code executed here will run under context of the app pool

System.Security.Principal.WindowsImpersonationContext context;
Context = ((System.Security.Principal.WindowsIdentity)User.Identity).Impersonate();

//Code executed here will run under the context of the client account

Context.Undo();

//Code executed here will run under the context of the app pool

Temporarily Reverting To The App Pool Identity

What if you want to do just the opposite? That is, temporarily disable impersonation, run a piece of code under the app pool identity, and then return to impersonating the client. To do this, you will want to enable impersonation in the web.config like so

<identity impersonate="true" />

Also, you will want to disable anonymous access on the IIS server, othersise, with impersonation enabled, the application will run under the identity of the anonymous user (see above diagram). Next, to achieve programmatic reversion to the app pool you will want to write code that looks like this

//Code executed here will run under the context of the client account

System.Security.Principal.WindowsImpersonationContext context;
context = WindowsIdentity.Impersonate(System.IntPtr.Zero)

//Code executed here will run under the context of the app pool

context.Undo();

context.Undo();

Troubleshooting

If you are still having trouble figuring out what credentials a thread is running under, Microsoft has a tool called Process Monitor (a combination of the Sysinternals Filemon and Regmon utilities) that reports process information and events at an incredibly granular level.