Welcome to devspade...

You have reached the personal website/blog of Brendan Caffrey. Here I will post updates about software and projects I am working on.

Any questions? Please do not hesitate to contact me.

What follows are posts | thoughts | ideas | etcetera. Enjoy.

So you did it.  You drank the MS Kool Aid and decided to go full bore and implement the Asp.Net Membership Provider.

As with any out of the box solution like the membership provider there are alot of pro’s.  It gives you quite a bit out of the box:

  • Ready made db for storing users, passwords, roles and more
  • Login controls, forgot my password control, etc
  • Lots of API classes to wrap users, roles, etc right out of the box
  • Highly configurable

Sounds great right?  Now say you’re like alot of developers I know and you have one database for development, possibly localhost.  You probably also have a staging or QA environment where your testers can create 100 users and try to break everything.  Then you have production – the real deal.

You’ve decided to use the Sql Membership Provider, you right all your code hitting your localhost db.  Everything runs perfect.  All your unit tests pass.  (You’re writing unit tests right?)  Now the move to QA.  Well step 1 is to create the Membership database on QA.  Ok, let’s a assume you can do this or can get a DBA to do this.

Now what?  All your connection strings point to localhost.  You look at your web.config and ugh – it looks like this:

<connectionStrings>
  <add name="MySqlConnection"   connectionString="Data Source=localhost;  Initial Catalog=aspnetdb;Integrated Security=SSPI;" />
</connectionStrings>
<system.web>
...
  <membership defaultProvider="SqlProvider">
    <providers>
      <clear />
      <add
        name="SqlProvider"
        type="System.Web.Security.SqlMembershipProvider"
        connectionStringName="MySqlConnection"
        applicationName="MyApplication"
        enablePasswordRetrieval="false"
        enablePasswordReset="true"
        requiresQuestionAndAnswer="true"
        requiresUniqueEmail="true"
        passwordFormat="Hashed" />
    </providers>
  </membership>

Ok, cool, I’ll just add a connection string for QA.  Wait, what’s this membership section?  You’re kidding right?  I can only have one connection string for my membership provider?  In short, the answer is yes, you can only have one.

So what’s the fix?

The solution is what I like to call complicated simple.  In theory it seems complicated.  In execution it’s actually pretty simple.  You can create your own membership provider and fix the little “bug”.

Create my own?  But doesn’t that defeat the whole purpose?  not exactly, you create your own, but inherit from all of Microsoft’s classes and only override one very small bit of functionality – the connection string implementation.

Your new Membership Provider:

public class MembershipProvider:SqlMembershipProvider
{
public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
 {
  base.Initialize(name, config);  

  // Update the private connection string field in the base class.
   var connectionString = IAmInQABool ? QAString : DevString;
 // Set private property of Membership provider.
  var connectionStringField = GetType().BaseType.GetField("_sqlConnectionString", BindingFlags.Instance | BindingFlags.NonPublic);
 connectionStringField.SetValue(this, connectionString);
 	}
    }

Note: For the line where I set the connections string you’ll want to implement your own logic here.  Likely some sort of code to determine what system you’re running on and then grabbing the write connection string from your config file.

That’s it.  You’ve created your own Membership Provider.  Now all your really did was take everything MS was giving you by default and use a little reflection to override the connection string.  You new provider will work just like the old.  You can still use the login controls and all that good stuff.

The only last bit of config you’ll need is to update your web.config to not use the default membership provider but yours instead:

<membership defaultProvider="MembershipProvider">
	<providers>
	<clear/>
	<add name="MembershipProvider" type="MyFullNamespace.MembershipProvider, MyProject"          connectionStringName="ApplicationServices" enablePasswordRetrieval="true"          enablePasswordReset="true" requiresQuestionAndAnswer="false"          requiresUniqueEmail="false" passwordFormat="Hashed" maxInvalidPasswordAttempts="5"          minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0"          passwordAttemptWindow="10" passwordStrengthRegularExpression="" applicationName="/"/>
	</providers>
</membership>
<profile>
	<providers>
	<clear/>
	<add name="MembershipProvider" type="MyFullNamespace.MembershipProvider, ResellerDashboard"          connectionStringName="ApplicationServices" applicationName="/"/>
	</providers>
</profile>

That’s all there is to it.  Would love to hear if anyone reads this post and implements this solution.

June 13, 2010 | In: meta

New look, new feel, new stuff

I currently drive a blue Honda CRV.  When I first started looking at  buying the car I knew CRV’s were popular.  But to be honest I didn’t notice that many on the road.  And most of the ones I had seen were black or red.  Well of cours after having the car for a few months now all I see on the road are blue Honda CRVs.  I can’t go to the mall or te supermarket without almost getting in the wrong car when leaving.  I still love the car.  But I guess I’m not as unique and creative as I thought I was.

For a few months now I’ve had some ideas for posts on this site.  Every time I started writing I would get frustrated.  I was disappointed with the look/feel of devspade.  I built version 1 using Blog Engine.  I converted a Word Press theme – Inove – to work with Blog Engine.  Much like my CRV, it seems like I have been cruising the internet and am running across a ton of blogs running the Inove theme.

I kept tweaking and tinkering with small parts of the design.  What ended up happening was I would not write a new post but would end up giving up.

I’m turning the page.  I found the current design on design disease.  I contemplated converting it to Blog Engine but decided instead to move to Wordpress (more on that in a future post).

So for now – new look, new feel, new stuff.

So I haven’t posted here in a bit.  For a variety of reasons.  One of them has been my struggles with BlogEngine which I think I am just now starting to really get down.

My most recent struggle has been with code syntax highlighting.  If you are a developer and you’re going to blog you will inevitably need to put some code on your blog.  So this was my project – make the code pretty.

My thoughts on syntax highlighting is keep it simple.  My requirements:

  • The code should look somewhat like code you might see in an IDE or Notepad++ type product.
  • You should be able to copy it to your clipboard very easily

Solution 1

So I use BlogEngine, I also mostly use Windows Live Writer for the actual “writing” part so here was my first approach:

Step 1: Google “blogengine Code syntax highlighting”.

Step 2:  Do whatever the first link tells me.

Step 3:  Profit.

Somewhere along the way I got lost.  I stumbled upon this plugin.  It seemed to be perfect BlogEngine (check), (Live Writer) check and pretty code (check).  Well I found some issues.  It seemed very brittle.  Sometimes I’d edit a post and the code blocks would lose line breaks.  or I’d re-open the post using Live Writer and it would break the code blocks again.

Solution 2

So in short solution 1 was no good.  I mean I should have smelled that out from the beginning.  Really, I need C# code just to format some code in an HTML page?  I needed a better solution.  More importantly, I need to change my approach.

Step 1:  Find the best code syntax highlighter there is.  If I want to put code in an HTML page what should I use?  After some research there are definitely split opinions but goolge-code-prettify is certainly amongst the best so I went with that.

Step 2:  Has anyone put that to use in BlogEngine before?  How?  Sure enough naspinksi has : http://naspinski.net/post/How-to-use-Google-Code-Prettify-with-BlogEngineNet.aspx.

Followed those steps almost to the letter and it worked.  (Well I also had to rip out the old Syntax Highlighter Extension code which was tedious and annoying but whatever.)

Step 3:  Modified my theme style sheet to format the pre tag a bit:

pre{background:#F4F5F7;      padding:8px 12px 8px 36px;      overflow: scroll; }

Step 4:  Download and install the Windows Live Writer plugin for google-code-prettify.

Step 5:  Profit.  (Well, we’re still working on this one.)

Lesson Learned:

When you have a problem.  Solve that problem.  Don’t create artificial requirements that will ultimately alter the final solution.  The reality is if naspinksi hadn’t posted about how to incorporate google-code-prettify into BlogEngine I could have figure that out.  Heck, I probably could even write the Live Writer plugin if so inclined.  Those issues were more about the toolset I was using then the original problem I set out to solve.

My problem was that I needed to format my code samples in the most robust and lightweight method possible.  And now, I’m kind of doing that.

I came across this question on StackOverflow the other day.  And my first reaction was huh?  My second was, of course!  Brilliant!

One of the keys to writing effective jQuery is being able to write effective selectors.  It’s really one of those things that you just get better at with experience.  But what happens when you have some common set of selectors you find your self always writing.  Well, you can extend jQuery using custom selectors.

A simple example:

Problem:

You often do form validation in jQuery and you always need to identify empty fields on a form.  Your simple form:




    
    


Some Form

Thing 1 Thing 2 Thing 3

Solution:

You could write some simple validation function that might look like this:

function ValidateForm() {
 $('span.validation_error').remove();
 $(':text').each(function() {
    if ($(this).val() == '') {
     $(this).after('*');
    }
  })
}

That would work sufficiently.  But wouldn’t it be nicer and more readable to be able to write:

function ValidateForm() {
 $('span.validation_error').remove();
 $(':textEmpty').each(function() {
  $(this).after('*');
   })
}

Unfortunately there is no :textEmpty selector.  But no problem, we’ll just create one:

$(document).ready(function() {
    $.extend($.expr[':'], {
        textEmpty: function(el) {
            var $el = $(el);
            return ($el.val() == "") && ($el.attr("type") == "text");
        }
    });
});

function ValidateForm() {
    $('span.validation_error').remove();
    $(':textEmpty').each(function() {
       $(this).after('*');
    })
}

Summary:

As you can see it’s relatively trivial to extend jQuery’s selectors.  Of course you don’t need to have your custom selectors defined in the $(document).ready().  You could just as easily create your own file with all your most commonly used selectors in it.

And to say this is just the tip of this iceberg is an understatement.  James Padolsey has a great listing of different ways to extend jQuery selectors.

If you’ve done any good amount of work using the Microsoft CRM Web Service you have most certainly been told on one occasion or another that the “Server is unable to process request”. 

What does this even mean?  Is the server down?  Does my user not have enough permission?  Did I send the right request?  At some point Microsoft could replace that message with “Uh, somethin’ ain’t right boss”.  That would be equally informative and infinitely more amusing.

But there is hope.  If you examine the exception you’ll notice it’s a Soap Exception.  We can examine the SoapException.Detail.OuterXML to see more information – messages like “Invalid user” or “The attribute ‘xxxxx’ does not exist on account”.

The obligatory code sample:

try {
   CrmService s = GetMyService();
   s.Execute(SomeRequest);
}
catch (System.Web.Protocols.SoapException soap_ex)
{
  Console.WriteLine(soap_ex.Detail.OuterXML);
}
catch(System.Exception ex)
{
  Console.WriteLine(ex.Message);
}

I basically divide my work with Microosft CRM into two eras – the first era I call trial and error.  The second I call SoapException.Detail.  Let’s just say the second era was far more productive.

The Problem

When my company first looked at Microsoft CRM a few years ago there were two immediate questions.

  1. (From the higher ups) How can we brand Microsoft CRM, so that our users know it as Company ABC CRM?
  2. (From the tech folks)  Can you please give me back the 100 + pixels of screen real estate at the top of the screen?

As you can see Microsoft is nice enough to insert a massive Microsoft Dynamics CRM logo which takes up a good 15% of your screen real estate and of course kills any chance of branding Microsoft CRM.  Not to mention the fact that the title of every page begins with “Microsoft Dynamics CRM”.

Solution

But what can you do?  It’s their sandbox right?  You have to play by their rules.  Well, kind of.  If you followed my previous post, I talked about how we can insert jQuery and our own custom JavaScript file right into Microsoft CRM.  Well, here’s a good example of what this opens up for us.

In our inserted JavaScript file we could have something like this:

$(document).ready(function() {    UpdateHeader();});

function UpdateHeader(){    $("FRAMESET").each(function() {    if ($(this).attr("rows") == "112,*") {    $(this).attr("rows", "80,*");    }    });

    $("#tdLogoMastHeadBar").css("background-image", "url()").css("font-weight", "bold").height("20px");    if ($("#tdLogoMastHeadBar").html()) {    $("#tdLogoMastHeadBar").html($("#tdLogoMastHeadBar").html().replace("
", "&nbsp;")); } $(".ms-crm-MastHead-SignIn-Org").css("margin-left", "7px").css("margin-right","7px").text(""); $("#leftContextTD").height("20px").next("td"); $(".ms-crm-ContextHeader-Title").css("padding-top", "5px"); if(document.title == "Microsoft Dynamics CRM"){ document.title = "ABC Company CRM"; } }

In this snippet we do 3 basic things:

  1. We find the frame set with the header in it and reduce the rows.  Make it smaller.  Reclaim the real estate.
  2. We clear out the background images, remove some <BR> tags, adjust some margins.  Basically clean up the header to make it more like something we like.
  3. Finally, remove MS’s title in favor of our own.

And the results will be something like this:


Summary

Here we saw an example of how we can use some inserted JavaScript to change the look/feel of Microsoft CRM to fit our needs.  As usual things like this come with the same disclaimer I had on my previous post and of course my overall blog disclaimer.  Good luck!

If you’ve done any decent amount of customization work with Microsoft CRM (version 3.0 or 4.0) you have probably had to remember all the JavaScript you tried so hard to forget.  Maybe you’re trying to do some advanced form validation or want to do some advanced CSS manipulation.  These things are not very simple and writing dozens and dozens of lines of document.getElementById() can get really irritating.

But this problem has already been solved now hasn’t it?  We can write rich unobtrusive JavaScript easily using any of the latest JavaScript libraries (see jQuery, MooTools, Scriptaculous, etc).

How We Do It

The code is actually pretty simple.  I’ll demonstrate using jQuery here but really you can do this with any of the popular libraries.

First, download jQuery from http://www.jquery.com.  Or, choose one of the jQuery CDN’s – including Microsoft’s newest one which supports SSL.  If you are downloading the file, place it on your Microsoft CRM server in the ISV directory (e.g. /ISV/MyCompany/jQuery.js).

Next you’ll need this basic function:

function load_script (url)
 {
    var x = new ActiveXObject("Msxml2.XMLHTTP");
    x.open('GET', url, false); x.send('');
    eval(x.responseText);
    var s = x.responseText.split(/\n/);
    var r = /^function\s*([a-z_]+)/i; 

      for (var i = 0; i < s.length; i++)
      {
          var m = r.exec(s[i]);
          if (m != null)
              window[m[1]] = eval(m[1]);
      }
  } 

This will take a script URL and parse out the functions and insert them into your page.  This will allow us to make a call like this to inject jQuery right into Microsoft CRM:

load_script("/ISV/MyCompany/scripts/jquery-1.3.1.min.js");

You can paste the function and then put this line in your form load and then use jQuery calls the rest of the way.

Take It To The Next Level

One of my biggest frustrations when I got started with Microsft CRM was this concept of pasting my code into some window on their app and hitting “publish”.  As a developer, this was very far from ideal.  Additionally, the only places I could put code was OnLoad and OnSave on Entity Forms.  Well what if I needed more than that?

So here’s the approach I took.  [Big Disclaimer Here :: Note this is an unsupported Microsoft CRM customization.  Microsoft will potentially break this in updates/upgrades.  They probably will not help you if it breaks your stuff.  They will not talk to you at parties.  It will be awkward.  You have been warned.]

In version 4.0 of Microsoft CRM there is a file – /_static/common/scripts/Global.js/  This file is loaded in some 90% of their pages.  So I opened the file and pasted the following at the vey very bottom of the file (be careful not to touch anything else in here – see aforementioned disclaimer).  Note there is an equivalent file in 3.0 as well.

/* Begin Custom Code  */

function load_script (url)
 {
    var x = new ActiveXObject("Msxml2.XMLHTTP");
    x.open('GET', url, false); x.send('');
    eval(x.responseText);
    var s = x.responseText.split(/\n/);
    var r = /^function\s*([a-z_]+)/i; 

      for (var i = 0; i < s.length; i++)
      {
          var m = r.exec(s[i]);
          if (m != null)
              window[m[1]] = eval(m[1]);
      }
  } 

    load_script("/ISV/MyCompany/scripts/jquery-1.3.1.min.js");
    load_script("/ISV/MyCompany/scripts/crm_scripts.js");

/* End Custom Code  */

You probably recognize our load_script function and the call to load jQuery.  The final call loads my own js file into every page.  Now I have a single (or many if your prefer) source controlled file, that I can publish, that has all my custom JavaScript.  The benefits:

  1. File is under source control, allows for easy diffs.
  2. Easy to deploy, do not need to republish MS CRM forms.
  3. Can use custom js now outside of the forms, pretty much anywhere in crm.

 

In future posts I’ll explore some of the doors this opens and just where we can really take this. 

November 24, 2009 | In: .Net

URL Rewriting

So, I started this blog with high hopes and dreams and only a few weeks in and I can’t think of a decent thing to write about.  So, like I will probably do time and again on this blog I checked out StackOverflow, found an answer I posted that others seemed to like and voila – instant blog post.

What is URL Rewriting?

Url rewriting is the process of taking something that looks like this:

http://www.shoes.com/Shopping/ProductDetails.aspx?p=EC1177024&pg=5105736

And turning it into something a human can understand.  Something that might look like this:

http://www.zappos.com/dr-martens-tevin-dark-brown-overdrive

Both go to the same shoes by the way.

Why URL Rewriting?

There a many reasons to user rewriting, let’s break down some of the most important:

  • Google – All else being equal, if I were to Google up “Dr. Marten’s Tevin Shoes” which of the above URL’s would Google prefer?  Zappos.com is a top results while shoes.com falls somewhere around page 4.  And then there’s the little issue of page rank as Jeff Atwood talks about here.

 

 

How?

Ah yes, the critical how question, well the answer very much depends on the technology stack.  I can’t cover every stack here of course so I’ll cover at least a little to give you an idea of how it’s done.

In .Net

In .Net these days there are 2 flavors of applications – MVC and web forms.  MVC apps come with their own built in URL rewriting engine.  It’s covered pretty extensively here.

In the world of web forms there are a lot more shades of gray.  You can always get a product like the one from Managed Fusion and let it do all the heavy lifting for you.  But where’s the fun it that?

But more seriously, there are times you don’t want dependency on a 3rd party library.  Maybe you’re creating your own product to sell.  Maybe you’re creating an open source tool and don’t want the dependency.

Well for web forms URL rewriting you have a couple of options.  Scott Guthrie covers them all pretty well here.  If you’re in a single application, I find the best approach to be creating your own HTTPModule.  You can download Scott’s sample app and check out how it’s done.

Non-Windows Servers

The gold standard in url rewriting is  the Apache mod_rewrite module.  It’s actually the basis of most IIS rewrite engines.  So if you’re using php, jsp, ruby, etc with Apache – this is where you want to look to do your url rewriting.

So to recap

  • Rewrite your URL’s
  • If you’re using .Net, first consider MVC, second consider creating your own HTTP Module
  • For everything else, try to use the Apache mod_rewrite module.

November 3, 2009 | In: meta

Another Developer’s Blog??

I know, I know.  The web needs another blog by some software developer about software developing about as much as it needs…oh I don’t know insert some cliché here.

Well – this is my attempt to contribute, in some small way, things that I have learned from my experiences writing software.  I’ll post some commentary occasionally, maybe an anecdote or two.

If you find something I write – useful, insightful, helpful, garbage, terrible, incorrect, innovative, enlightened, inaccurate, offensive or otherwise thought provoking – please leave a comment.

I 100% agree with Jeff Atwood when when he says:

Authority in our field is a strange thing. Perceived authority is stranger still.

I’ve always thought of myself as nothing more than a rank amateur seeking enlightenment. This blog is my attempt to invite others along for the journey.

So come along…