Returning custom HTTP Status codes for WCF SOAP Exceptions

When WCF encounters an unhandled exception, the thrown exception is wrapped up in a FaultException and returned to the client. You can of course throw your own FaultException to have better control over the contents of the error, but one thing you cannot control by default is the HTTP response code. It is always 500.

I had a situation where I needed to return a 503 error under certain circumstances in a WCF SOAP service.

The solution is not as simple as I might like, but it isn’t terrible. There are examples out there for changing the http status code for all exceptions (https://msdn.microsoft.com/es-es/library/ee844556(v=vs.95).aspx), but this was not at all what we want.

The solution uses the same basic framework as the mentioned article however. An Endpoint Behavior Extension registers a Dispatch Message Inspector that watches for faults. In the case of a fault. Inside the BeforeSendReply method, you have access to the reply message. For performance reasons it is best to not unwrap the XML, so we use the SOAP Action header to trigger the HTTP Status code update.

I decided to create a simple custom exception class that sets the SOAP Action to a predefined value

    /// <summary>
    /// Custom Fault Exception that when used with the CustomFaultStatusBehavior Endpoint Behavior
    /// allows returning custom HTTP status codes to the client
    /// </summary>
    public class StatusFaultException : FaultException
    {
        /// <summary>
        /// Create new exception
        /// </summary>
        /// <param name="statusCode">HTTP Status code to be returned to the client</param>
        /// <param name="faultReason">SOAP Fault Reason</param>
        /// <param name="faultCode">SOAP Fault Code</param>
        public StatusFaultException(System.Net.HttpStatusCode statusCode, string faultReason, FaultCode faultCode)
            :base(faultReason, faultCode, "CustomFaultStatus" + ((int)statusCode).ToString())
        {
            //StatusCode is placed in the response Action. Action would be "CustomFaultStatus503" to return a 503 error code
        }
    }

Here is the Custom Behavior that consumes the SOAP Action

    /// <summary>
    /// Endpoint Behavior that allows returning custom HTTP response codes for SOAP Faults 
    /// </summary>
    public class CustomFaultStatusBehavior : BehaviorExtensionElement, IEndpointBehavior
    {
        //based on https://msdn.microsoft.com/es-es/library/ee844556(v=vs.95).aspx
        public override Type BehaviorType
        {
            get
            {
                return typeof(CustomFaultStatusBehavior);
            }
        }

        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
        }

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
            CustomFaultStatusMessageInspector inspector = new CustomFaultStatusMessageInspector();
            endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector);
        }

        public void Validate(ServiceEndpoint endpoint)
        {
        }

        protected override object CreateBehavior()
        {
            return new CustomFaultStatusBehavior();
        }
    }

    /// <summary>
    /// Message Inspector that updates the HTTP response code for faulted messages with a CustomFaultStatus action
    /// </summary>
    public class CustomFaultStatusMessageInspector : IDispatchMessageInspector
    {
        public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
        {
            return null;
        }

        public void BeforeSendReply(ref Message reply, object correlationState)
        {
            if (!reply.IsFault) return;
            if (!reply.Headers.Action.StartsWith("CustomFaultStatus", StringComparison.Ordinal)) return;
            //get the string value for desired response code
            string statusCodeString = reply.Headers.Action.Substring(17);
            //convert to int
            int statusCodeInt;
            if (!int.TryParse(statusCodeString, out statusCodeInt)) return;

            //cast to HttpStatusCode
            System.Net.HttpStatusCode statusCode = System.Net.HttpStatusCode.InternalServerError;
            try
            {
                statusCode = (System.Net.HttpStatusCode)statusCodeInt;
            }
            catch (Exception ex)
            {
                return;
            }

            // Here the response code is changed
            reply.Properties[HttpResponseMessageProperty.Name] = new HttpResponseMessageProperty() { StatusCode = statusCode };
        }
    }

The CustomFaultStatusBehavior must be registered in your web.config as a behavior extension, then it must be referenced in an endpoint behavior. Finally this behavior should be applied to the endpoint using the behaviorConfiguration attribute.

Free Tool: Dynamics CRM User Language Update Tool

Just had an encounter with a user who needed their language updated. The UI Language was set to Korean – I wasn’t able to walk the user through updating it since I don’t read Korean either.

So I whipped up a little tool to do the job for me.
userupdatetool

You supply a connection string for the target CRM Organization (Should support everything – CRM Online, On-Premise – just paste everything in the CRM url up to (but not including) the “/main.aspx”)

You can search for the user by Guid, Full Name or DomainName (aka User Name) (all the search fields auto add wildcards)

The tool returns a list of matching users – select the user to update, select the desired values for language code and click Update. Pretty basic and there are instructions for doing it, but I didn’t see anything so simple out there.

You can get the binaries here: Dynamics CRM User Language Update Tool

And the source code here: Dynamics CRM User Language Update Tool Source Code

(Note that you may need to have Windows Identity Foundation installed – this is a prerequisite of the CRM SDK)

This tool works with Dynamics CRM 2011, Dynamics CRM 2013, Dynamics CRM 2015, Dynamics CRM Online, and the forthcoming Dynamics CRM 2016 (ie everything 2011 and later)

Get the SQL Server and database name from Dynamics CRM

As far as I can tell, there is no way to retrieve the SQL Server name using the Organization Service. If you have the Organization Service URL, there really is no good way to get the database connection string.

(You can use the deployment service to get it, but that only works if you happen to be a deployment administrator)

No good way… but there is a way. When you download a dynamic spreadsheet, the database connection string is embedded in the xml. And you can programmatically download that spreadsheet using an entity that all CRM orgs have.

Using some fiddler experimentation, I was able to make a .NET method that will extract the database connection string, given the organization base url (https://crmserver/orgnam)

        /// <summary>
        /// Given a Dynamics CRM Org URL, retrieve the Database Connection string
        /// </summary>
        /// <param name="crmOrgUrlBase"></param>
        /// <returns></returns>
        private static string GetCrmDatabaseConnectionString(string crmOrgUrlBase)
        {
            string cleanurl = crmOrgUrlBase.ToLowerInvariant().Trim().Replace("/xrmservices/2011/organization.svc", "");
            {
                int mainPos = cleanurl.IndexOf("/main.aspx");
                if (mainPos > 0)
                {
                    cleanurl = cleanurl.Substring(0, mainPos);
                }
            }

            string requestPayload = @"xdpi=96&exportType=list&useSqlQuery=1&fetchXml=%3Cfetch+distinct%3D%22false%22+no-lock%3D%22false%22+mapping%3D%22logical%22+page%3D%221%22+count%3D%2250%22+returntotalrecordcount%3D%22true%22%3E%3Centity+name%3D%22systemuser%22%3E%3Cattribute+name%3D%22systemuserid%22%2F%3E%3Cattribute+name%3D%22fullname%22%2F%3E%3Cattribute+name%3D%22fullname%22%2F%3E%3Corder+attribute%3D%22fullname%22+descending%3D%22false%22%2F%3E%3C%2Fentity%3E%3C%2Ffetch%3E%0D%0A&layoutXml=%3Cgrid+name%3D%22excelGrid%22+select%3D%220%22+icon%3D%220%22+preview%3D%220%22%3E%3Crow+name%3D%22result%22+id%3D%22systemuserid%22%3E%3Ccell+name%3D%22fullname%22+width%3D%22100%22%2F%3E%3C%2Frow%3E%3C%2Fgrid%3E%0D%0A";
            string url = cleanurl + "/_grid/print/export_live.aspx";

            string response = null;


            using (var wc = new System.Net.WebClient())
            {
                wc.UseDefaultCredentials = true;
                wc.Headers.Add("Accept-Encoding", "gzip, deflate");
                wc.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
                wc.Headers.Add("DNT", "1");
                response = wc.UploadString(url, requestPayload);
            }


            var xe = System.Xml.Linq.XElement.Parse(response);


            System.Xml.Linq.XNamespace nn = "urn:schemas-microsoft-com:office:spreadsheet";
            System.Xml.Linq.XNamespace nn2 = "urn:schemas-microsoft-com:office:excel";


            var connectionEl = xe.Element(nn + "Worksheet").Element(nn2 + "QueryTable").Element(nn2 + "QuerySource").Element(nn2 + "Connection");

            string rawString = connectionEl.Value;

            Regex rex = new Regex("SERVER=([^;]+);DATABASE=([^;]+)", RegexOptions.Compiled);

            var m = rex.Match(rawString);

            string server = m.Groups[1].Value;
            string database = m.Groups[2].Value;

            return "DATA SOURCE=" + server +";INITIAL CATALOG=" + database + ";Integrated Security=SSPI";
        }

It is technically unsupported to access export_live.aspx directly, so this may stop working in future releases of CRM.
I have tested this on CRM 2011 UR 11 and UR 17.

Dirt simple method of limiting System.Threading.Task concurrency (max concurrent threads)

Microsoft has an article about creating a Task Scheduler that limits maximum concurrency:
How to: Create a Task Scheduler That Limits the Degree of Concurrency

The provided example class is clunky and kinda hard to grasp. I’ve been searching for a simple way to create a “thread pool” with limited concurrency. I previously experimented with ConcurrentBags of BackgroundWorkers – this worked, but it was also fairy complex and cumbersome.

The solution I came up with uses a Semaphore (or rather the lighter weight SemaphoreSlim type) to manage concurrency.

Simply put – you create a semaphore with a maxCount (and initialCount) equal to the max concurrency you desire. Then when you want to fire off a Task, first call semaphore.Wait(), then call semaphore.Relase() in a ContinueWith().

Contrived example:

    public class LimitedAsync
    {
        private SemaphoreSlim _semaphore;

        public LimitedAsync(int maxConcurrency)
        {
            // Create semaphore with maxConcurrency slots
            _semaphore = new SemaphoreSlim(maxConcurrency, maxConcurrency);
        }

        public void DoSomethingAsync(string param)
        {
            //Wait for semaphore to have availablilty (blocks if semaphore is full)
            _semaphore.Wait();
            //Run DoSomething in a task, then release slot in semaphore
            //ContinueWith is called even if DoSomething faults
            Task.Factory.StartNew(() => DoSomething(param)).ContinueWith((x) => _semaphore.Release());
        }

        public void DoSomething(string param)
        {
            System.Threading.Thread.Sleep(500);
        }
    }

Generating a single flattened WSDL from an existing WCF Service

UPDATE 4/12/2013: Tool included
Download WSDL Flattener Tool
I’m not including source because it’s messy (I prefer to cleanup my code before sharing…) but feel free to decompile with ILSpy if you don’t trust me.

UPDATE 8/11/2015: Command line tool included
WSDL Flattener Command Line Utility
Somehow I forgot to save my update – thanks Luke for pointing it out!

WCF is great – its flexible, standards compliant, super easy to work with, and just altogether nice. That is, until you try to use it with, say, Oracle products. WCF generates so-called modular wsdl files, with separate xsd files for types, and even sometimes multiple wsdl files. Not technically in violation of any standards, but kind-of pushing the limits.

There are plenty of articles out there about modifying a WCF service to generate a flat WSDL. Also if you upgrade to .NET 4.5, you can use the URL parameter ?singleWsdl to get a flattened WSDL.

But what if you don’t have control of the web service? What if you cannot upgrade or modify the code?

For some odd reason, Microsoft added the internal ability to generate a single WSDL but only exposed it through the WCF Service implementation. They didn’t add it to svcutil.exe, and they didn’t expose it in the Framework… publicly that is *evil grin*

Turns out, in the System.ServiceModel.Description namespace, there is an internal static class called “WsdlHelper”, and this class has a public static Method called “GetSingleWsdl” that takes a MetadataSet for a parameter, and returns a System.Web.Services.Description.ServiceDescription object representing the Wsdl as a single entity. All you have to do is call .Write(filename) and you have your file.

“But I don’t see any WsdlHelper class!!!!!!”

It’s internal – you have to use reflection to invoke it.
First, you have to load the metadata from the existing WCF service into a MetadataSet using a MetadataExchangeClient. (Hint: you will probably need to use a custom binding). Then you run that set into something like this:

            var asy = System.Reflection.Assembly.GetAssembly(typeof(WsdlExporter));
            Type t = asy.GetType("System.ServiceModel.Description.WsdlHelper", true);
            var method = t.GetMethod("GetSingleWsdl", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);

            object retVal = method.Invoke(null, new object[] { metadataSet });
            //cast retVal into System.Web.Services.Description.ServiceDescription, and call the .Write() method. All done

Using this, I was able to create a tool that takes a WCF url, and allows you to save a single .wsdl file. You want the tool? Later perhaps. For now put your thinking cap and Google gloves on, and write your own.

Windows 8 Store Application Development: AppBar WTF

I have a great idea for an app that I intend to submit to the Windows 8 store. I am a fairly proficient .NET developer, and I already have a nice little class library all ready to go, I just need a “Modern” UI. This shouldn’t be too hard, right?

I create my project, and start adding controls. I realize I will need that settings thing that pops up when you swipe up from the bottom of the screen. But it isn’t called “settings” – that is something different. Instead it is called the “AppBar”. Now given that I am using a tool called VISUAL Studio, the primary innovation being the ability to rapidly, visually design user interfaces, then write code for interaction. So I figure adding an AppBar should be as simple as adding a menubar was in windows forms, right?

Wrong. Dead Wrong.

An AppBar is like an iFrame. You can put whatever you want in it, and it is completely NON-obvious, and non-intuitive to do so in a meaningful fashion. The Microsoft Quick Start guide only tells you how to do it with some XAML code that they neglect to tell you where to place. Want to follow along? Here is the article: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh781232

 

Continue reading

Dynamics CRM 4.0 truly calculated fields

Microsoft has a real gem with Dynamics CRM. It is both an application and a platform, highly customizable without writing a line of code, and once you throw in the code you can do most anything (depending on how unsupported you want to go)

Internally, CRM has a number of calculated fields. The customer lookup, for example is defined in the database as COALESCE(accountid, contactid). If you wanted to be really bold, I supposed you could create a column then modify it to be a function within the database, but that would be an extremely bad idea. The correct way is to use plugins and / or javascript.

Form JavaScript is fine when you are only considered with maintaining the value when a use opens the form, but what if they print? Or use the field in a view? Or another application uses the web services to retrieve the value?

You need a plugin, and that plugin has a lot of work to do.

I recently created a plugin that permits the creation of lookups that target multiple entities. After finally handling (or chosing not to handle) all the contingent scenarios I learned a few things.

1. Your plugin has to handle the Execute message, as this is the message used for FetchXml. You will have to parse the fetchxml, determine if your entity is in it, determine if your column is in it (and you have to recurse through the link-entities).
You can either register on the post stage and perform your own retrievals to get the data for the calculation, or you can sit on the pre and post stages and modify the fetchxml in the pre stage to include the extra columns needed for your calculated field. This is MUCH MUCH faster. You will need to determine what the ResultXml looks like based on how the fetch is designed.
2. Despite what the Microsoft Documentation suggests, you do not have to register the ReteieveMultiple message for all entities – just the entity in question.
(Unless you intend to handle your calculated field being used in a filter condition. This could get extremely complicated and it is better to just make the field non-searchable)
3. You should make sure your calculated field is configured as non-searchable. This prevents it being used as a filter condition from the UI (advanced find and the like)
4. The same performance recommendation holds for the Retrieve message – register pre and post, modify the ColumnSet to contain the fields needed for the calculation, then modify the result set.
5. CRM doesn’t care if extra columns show up in the result set.
6. If your field is editable (the calculation is two-way) you will need to handle the create and update, filtered for your calculated field. Add the changes to the underlying fields to the InputParameters Target propertybag.

A couple notes about CRM 2011:
I haven’t found explicit documentation of this fact, but Fetch requests no longer use the Execute message – they are instead RetrieveMultiple.
There are two reasons I have inferred for this:
1: It is now possible because the QueryExpression in CRM 2011 allows LinkEntities to have a ColumnSet – thus providing feature parity between Queries and Fetch.
2: Plugins generally now execute within the CRM transaction, so most likely the FetchXml is parsed into a QueryExpression before the plugin is fired.
This is good and bad – it reduces the number of messages you have to listen for, but it means you do have to hook the global RetrieveMultiple.

Since CRM 4.0 is pretty dated I’m guessing there isn’t too much demand for a multilookup akin to the Customer lookups – but I have one, and I have managed to retool the basic functionality to work in CRM 2011 as well. (Who knows, it may end up as a solution!)

Changing a Word Mail Merge Field in C#

The mail merge fields in Microsoft Word are actually just a specific type of the more general Fields. Fields can be used to make fill-in forms, autogenerated text, dates, etc… They typically are displayed surrounded by funny looking square brackets, like <<first_name>>.

Inside the Word Xml, the Field and the display value are stored separately – the field looks like “ MERGEFIELD User_Title “, then in a separate range, the display of “«User_Title»” is stored.

Using the Word Object Model, Document.MailMerge.Fields contains MailMergeField objects for each instance of a merge field. The .Code member contains the range object, of which the .Text member will contain the field code (aka “ MERGEFIELD User_Title “). If you do a replace on this text field, it will update the merge field, but the display will remain the same.

You next have to call Document.Fields.Update() to get the display matching.

Here is some code:

        private void RenameMergeField(Word.Document doc, string oldName, string newName)
        {
            foreach (Word.MailMergeField field in doc.MailMerge.Fields)
            {
                if (field.Code.Text.Contains(oldName))
                {
                    field.Code.Text = field.Code.Text.Replace(oldName, newName);
                }
            }
            doc.Fields.Update();
        }

Handling Invalid Enum values in a DataContractSerializer

This all started when I was trying to serialize a CodeDom graph (actually a CodeNamespace object) using a DataContractSerializer. I hit the dreaded “Enum value ‘20482’ is invalid for type…”

image

(Note: this error was the showstopper after many other errors)

The problem: System.CodeDom.MemberAttributes should have the [Flags] attribute, but it does not. the value of 20482 is the bitwise OR of MemberAttributes.Final (2) and MemberAttributes.Private (20480). One solution was to go through all object in the CodeDom tree with attributes and force it to a single value – this is not really acceptable. Unfortunately, since we are dealing with a .NET Framework type, there is really no way to fix the type itself.

The solution: Fix the serializer… Read on for details.

Continue reading

Determining current laptop battery drain in .NET

My laptop battery’s lifetime has dropped significantly of late, and I wanted some means of determining the actual current being used by the system – sort of like a Power Meter for the laptop battery. I‘ve actually been looking for such a tool off and on for months. I’ve seen things you have to pay for, things that are quite old, and things you can do yourself in C++…

Well I don’t want to pay for something that tells me the power usage in mw (milliwatts). Nor do I want something with “Vista” style. Nor do I want to deal with c++.

1. Performance Monitor

Not sure why I didn’t think to look here – maybe because it’s a big mess – but it turns out the power utilization in mW is in a couple places in windows Performance Monitor:

Under Power Meter –> Power:

image

Do not use the _Total option – at least on my machine it is incorrect. Use all instances, then look to see which instance corresponds to your actual battery. (note: this only works while your laptop is running on battery power. “Power Meter” returns 0 when you are on AC power)

 

You can also use Battery Status –> Discharge Rate. There is also a Charge Rate that will have a value when the battery is charging. The only catch is that access to Battery Status requires Administrator privs.

 

2. .NET Performance Counter – Forms control

Forget WMI queries and System.Management – Be lazy! Visual Studio has a Server Explorer tab that allows you to easily add performance counters to your Windows Forms project.

Open Server Explorer –> You computer –> Performance Counters

image

Find Power Meter, expand Power, and drag whichever power meters you need onto your form. (In my case I just needed Power Meter (0).

image

This will add performanceCounter1 to your project. To get the current power usage in mW, just access performanceCounter1.NextValue().

 

3. .NET Performance Counter – Code

Even easier, once you know the Category (“Power Meter”), Counter (“Power”) and Instance (“Power Meter (0)”), you can create the performance counter in code like so:

(Add a textbox and a button to your form), use this as the button event handler

        private void button1_Click(object sender, EventArgs e)
        {
            var powerCounter = new System.Diagnostics.PerformanceCounter("Power Meter", "Power", "Power Meter (0)", true);
            textBox1.Text = powerCounter.NextValue().ToString();
        }

 

Chances are I will release a (free, open source) tool based on this, but it’s painfully simple to just get that current value. (Now to start seeing the effect of the backlight, and hard drive, and cpu load…)