Thursday, December 20, 2012

Error 21 CA0055 : Could not unify the platforms

After a recent upgrade from Silverlight 4.0 to Silverlight 5.0, I started getting this error from Visual Studio 2010

Error 21 CA0055 : Could not unify the platforms (mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e, mscorlib, Version=5.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e) for '[path to Silverlight project dll]'.

Took me a while to track it down, and I found the solution to my problem in this post.

Being that we don’t use Code Analysis, I just turned it off on my Silverlight project.

2012-12-18_1304

But if you do use it, you’re going to have to run the command line arguments as the post suggests.

Tuesday, December 18, 2012

Error 17 Unknown build error, 'An item with the same key has already been added.'

I recently got this error after doing a code merge. No source file, no line number, just the project name and nothing else to point me in the proper direction to rectify my issue.

After much searching I found the answer to my problem in this post.

The post states this can occur if there are duplicate lines within a <ItemGroup> node in a csproj file.

I did a compare on my project file and found this.

2012-12-18_1053

I removed the duplicate line and everything was right with the world again.

Thursday, November 15, 2012

redgate SQL Source Control Revision Numbers

Anyone that’s developed with me in the last 7 years knows that I’m a HUGE fan of redgate. Honestly, now that I use their tools, I don’t know how I would work on MS SQL databases without them.

Recently, I’ve been taking a deep dive into SQL Source Control and SQL Compare. So far, I love it.

  • SQL Source Control: Is a Microsoft SQL Server Management Studio plug-in which allows me to commit my database schema, static data, and migration scripts into version control.
  • SQL Compare: Is a stand alone tool that allows me to compare and deploy schema changes. From a Database, Backup, Snapshot, Script Folder, or directly from source control to any combination there of.

In my case, I am using SQL Compare to deploy schema changes directly from source control, to my database.

One notable feature, is SQL Compare’s use of Extended Properties to track the version control revision number, in the database.

Here is an example of the script they use:

   1: DECLARE @RG_SC_VERSION BIGINT
   2: SET @RG_SC_VERSION = 13670
   3: IF EXISTS (SELECT 1 FROM fn_listextendedproperty(N'SQLSourceControl Database Revision', NULL, NULL, NULL, NULL, NULL, NULL))
   4:   EXEC sp_dropextendedproperty N'SQLSourceControl Database Revision', NULL, NULL, NULL, NULL, NULL, NULL
   5: EXEC sp_addextendedproperty N'SQLSourceControl Database Revision', @RG_SC_VERSION, NULL, NULL, NULL, NULL, NULL, NULL
   6: GO

This means you can figure out the revision number of your database by querying the Extended Property.

   1: SELECT Name, Value FROM fn_listextendedproperty(N'SQLSourceControl Database Revision', NULL, NULL, NULL, NULL, NULL, NULL)

Why does this matter?

Well, when the time comes to update a client’s database to the latest version, it’s as easy as.

  1. Figure out the version of their database (using the script above)
  2. Using SQL Compare: Set your “Source” to the Head of your source control, set the “Target” to the version of the database the client is at
  3. Using SQL Compare: Compare the two database schemas, and generate a deploy script

So awesome.

Monday, November 12, 2012

Using a delimited list for SQL ‘IN’ statement

Sometimes I want to pass a list of items from my C# code to my stored procedures so they can be used as part of an ‘IN’ clause.

In my greener years I would do something like:

Unsafe Way

<WARNING>Do NOT write code like this. This opens the door to SQL injection. </WARNING>

   1: -- @ProductIDs contains a list of id's delimited by a ',' (i.e. '1,34,56,7,8,98')
   2:  
   3: sp_executesql 'SELECT * FROM Products WHERE ProductID IN (' + @ProductIDs + ')'

Safer Way

My safer solution is adding a function to my database called “SPLIT.”

Function:
   1: CREATE FUNCTION [dbo].[SPLIT] (
   2:     @str_in VARCHAR(8000),
   3:     @separator VARCHAR(4) )
   4: RETURNS @strtable TABLE (strval VARCHAR(8000))
   5:  
   6: AS
   7:  
   8: BEGIN
   9:     DECLARE
  10:         @Occurrences INT,
  11:         @Counter INT,
  12:         @tmpStr VARCHAR(8000)
  13:     
  14:     SET @Counter = 0
  15:  
  16:     IF SUBSTRING(@str_in,LEN(@str_in),1) <> @separator 
  17:         SET @str_in = @str_in + @separator
  18:  
  19:     SET @Occurrences = (DATALENGTH(REPLACE(@str_in,@separator,@separator+'#')) - DATALENGTH(@str_in))/ DATALENGTH(@separator)
  20:     SET @tmpStr = @str_in
  21:  
  22:     WHILE @Counter <= @Occurrences 
  23:     BEGIN
  24:         SET @Counter = @Counter + 1
  25:         INSERT INTO @strtable
  26:             VALUES ( SUBSTRING(@tmpStr,1,CHARINDEX(@separator,@tmpStr)-1))
  27:  
  28:         SET @tmpStr = SUBSTRING(@tmpStr,CHARINDEX(@separator,@tmpStr)+1,8000)
  29:  
  30:         IF DATALENGTH(@tmpStr) = 0
  31:  
  32:         BREAK
  33:     END
  34:  
  35: RETURN 
  36: END

This function takes a “str_in” parameter representing the delimited String, and separator parameter representing the delimiter of the string.

Using these two values, the delimited string is broken apart into a table that can be queried.

Usage:
   1: SELECT *
   2: FROM Products
   3: WHERE
   4: ProductID IN ( SELECT * FROM SPLIT(@ProductIDs, ','))

I’m sure there is a more efficient way to perform the same task, but it works well enough for my needs. However, I am open to suggestions.

 

Happy Coding,

Justin

Tuesday, October 9, 2012

How to dynamically load a JavaScript file.

How do you dynamically load a JavaScript file? With JavaScript of course!

   1: function loadjsFile(filepath) {
   2:      try {
   3:          var h = document.getElementsByTagName('head').item(0); 
   4:          var t = document.createElement('script'); 
   5:          if ('object' != typeof(t)) {
   6:               t = document.standardCreateElement('script');
   7:          } 
   8:          t.setAttribute('src', filepath); 
   9:          t.setAttribute('type', 'text/javascript'); 
  10:          h.appendChild(t);
  11:      } catch(e) { alert('Error: ' + e); }
  12: }
  13:  
  14: // ...
  15: // Later in your code
  16:  
  17: loadjsFile("MyDynamicScript.js");

In fact, dynamically loaded JavaScript is the basic concept for Bookmark Applets (a.k.a Bookmarklet)

With just a few tweaks you can make your own bookmarklet.

<a href="javascript: (function () { try { var h = document.getElementsByTagName('head').item(0); var t = document.createElement('script'); if ('object' != typeof (t)) { t = document.standardCreateElement('script'); } t.setAttribute('src', 'http://www.JustinKohnen.com/bookmarklet/BlogPostBootstrap.js'); t.setAttribute('type', 'text/javascript'); h.appendChild(t); } catch (e) { alert('Error: ' + e); } })();
"
>hyperlink</a>

If you are concerned about caching, you can always append a timestamp to your script reference.

<a href="javascript: (function () { try { var h = document.getElementsByTagName('head').item(0); var t = document.createElement('script'); if ('object' != typeof (t)) { t = document.standardCreateElement('script'); } t.setAttribute('src', 'http://www.JustinKohnen.com/bookmarklet/BlogPostBootstrap.js?x=' + new Date().getTime()); t.setAttribute('type', 'text/javascript'); h.appendChild(t); } catch (e) { alert('Error: ' + e); } })();
"
>hyperlink</a>

Here, try it. Drag this hyperlink up to your bookmark bar and click it. After a few seconds, you should see a special message from me to you.

 

Cheers and happy coding,

Justin

 

<postscript>

If you load reference JS files within Bookmarklet JavaScript you may introduce a race condition. This is why my little demo takes a second to load. I had to put a delay to allow for my reference files to download. And even still, it might not work on slower internet connections.

</postscript>

Friday, April 27, 2012

Good practice when naming a Boolean variable/Property

schema_boolean<soapbox>

When defining a Boolean (true/false) variable or property

  1. Prefix the name with "Is" or "Has"
  2. Do not negate in your variable name.

Bad Boolean variables names:

  • Allowed (No prefix)
  • IsNonUser (Negated Name)
  • IsNotAllowed (Negated Name)
  • Permission (No prefix)

Good boolean variable names:

  • IsAllowed
  • IsUser
  • IsAllowed
  • HasPermission

Why?

Because if statements with negation become easier to read.

I think this if statement is harder to read

   1: if(!IsNotAllowed) 
   2: { 
   3:     ShareCandy(); // "If not is not allowed then share candy"
   4: } 

Then this if statement

   1: if(IsAllowed) 
   2: { 
   3:     ShareCandy(); // "If is allowed then share candy"
   4: } 

</soapbox>

Friday, April 6, 2012

A quote from modernizr

I read this in the modernizr documentation on polyfills and I thought I would repeat it:

And remember, none of your users view your site in more than one browser; It’s okay if it looks and acts differently.

So true. All too often people want their websites to work exactly the same on all browsers. But in reality, users don’t know if there are slight differences because they have nothing to compare it to. As long as the user can get the same information and actions they get on other browsers. It’s ok if it’s off by a few pixels.

Thursday, March 29, 2012

Using an ObjectDataSource in Sharepoint

A Co-worker was trying to use an ObjectDataSource within a UserControl within SharePoint.

After a bit of research. We learned one must use the fully qualified name of the class and assembly when defining the TypeName.

So we did it, but in the code behind.

ASCX Snippet

   1: <asp:ObjectDataSource ID="odsProfit" runat="server" 
   2:     SelectMethod="GetData">
   3:         <SelectParameters>
   4:             <asp:Parameter Name="DataID" Type="Int32" />
   5:         </SelectParameters>
   6: </asp:ObjectDataSource>

ASCX.cs Snippet

   1: protected void Page_Init(object sender, EventArgs e)
   2: {
   3:     odsProfit.TypeName = new ProfitManager()
   4:                                 .GetType()
   5:                                 .AssemblyQualifiedName;
   6: }

I just thought I would share.

Cheers.

Friday, February 3, 2012

How To: Stop IIS7 from timing out while you’re debugging

Have you ever seen this before while you’re debugging an IIS7 application?

2012-01-19_1306

When you’re debugging code such as webpages, services, SharePoint event receivers, and SharePoint workflow handlers. You only have so long before you get a timeout message from IIS7 and you can no longer continue debugging. 

This is because IIS "pings" it’s Application Pools to see if they are still responsive.  You can either disable this or change the response time from the default 90 seconds.

Bring up IIS7 Manager

  1. Expand the Server in the left pane
  2. Click on Application Pools
  3. On each application pool, right click and choose Advanced Settings
  4. Under the Process Model, change Ping Enabled to False or change the Ping Maximum Response Time to a greater value

2012-02-03_0918

Cheers,

Justin

Friday, January 27, 2012

How To: Disable “Attach Security Warning” of Visual Studio

When you attach to a process, you sometimes get the message confirming whether you want to attach the process.

Warning

This happens for each process you are attaching.  ANNOYING!  This is how to disable it.

  1. Make sure Visual Studio 2010 is first shut down
  2. Click Start > Run... Type "regedit" <Enter>
  3. For VS 2010 navigate to HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\10.0\Debugger
    1. For VS 2008 navigate to HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\9.0\Debugger
  4. Set DisableAttachSecurityWarning to 1

Cheers,
Justin