<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5716364009216068026</id><updated>2012-02-16T03:28:30.748-08:00</updated><category term='debuggable attribute'/><category term='mvc razor unobtrusive javascript'/><category term='release mode'/><category term='debugging'/><category term='debug mode'/><title type='text'>Adam Tuliper's Development Stuff</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>58</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-7721004378978437367</id><published>2012-01-30T07:07:00.000-08:00</published><updated>2012-01-30T07:07:22.298-08:00</updated><title type='text'>VSLive is coming to Vegas!!!</title><content type='html'>I'll be doing two sessions at VSLive Las Vegas &lt;br /&gt;The popular "Hack Proofing your ASP.NET Applications" and&lt;br /&gt;"Entity Framework 4.2 for Web Applications"&lt;br /&gt;&lt;br /&gt;You'll get one on one time with me for any security or EF (or anything else for that matter) questions you might have as well.&lt;br /&gt;&lt;br /&gt;Register with promo code VLSPK25 for some extra savings!!!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Visual Studio Live Las Vegas&lt;br /&gt;Mirage Resort &amp; Casino&lt;br /&gt;March 26-30, 2012&lt;br /&gt;Event web site: http://vslive.com/lasvegas&lt;br /&gt; &lt;br /&gt;Visual Studio Live is five days of practical, Microsoft-supported training for developers to help solve your tough .NET development challenges. You'll find how-to advice and the tips and tricks that you'll be ready to implement as soon as you get back to the office. Our expert faculty - including many Microsoft instructors - makes each session interactive so you can discuss your particular development roadblocks and come away with actionable solutions.&lt;br /&gt; &lt;br /&gt;Visual Studio Live Las Vegas offers in-depth training in:&lt;br /&gt;Cloud Computing&lt;br /&gt;Cross Platform Mobile&lt;br /&gt;Data Management&lt;br /&gt;HTML5&lt;br /&gt;Silverlight / WPF&lt;br /&gt;Visual Studio 2010+/.NET 4+&lt;br /&gt;Web&lt;br /&gt;Windows 8/WinRT&lt;br /&gt;Windows Phone 7&lt;br /&gt; &lt;br /&gt;Visual Studio Live Las Vegas – Expert Solutions for .NET Developers&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-7721004378978437367?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/7721004378978437367/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2012/01/vslive-is-coming-to-vegas.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/7721004378978437367'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/7721004378978437367'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2012/01/vslive-is-coming-to-vegas.html' title='VSLive is coming to Vegas!!!'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-8408802632074604528</id><published>2011-12-08T21:43:00.000-08:00</published><updated>2011-12-08T21:43:36.891-08:00</updated><title type='text'>Using Dependency Injection with MVC</title><content type='html'>This is the code from the brief talk on Dependency Injection with MVC.&lt;br /&gt;There are two projects here. This uses Unity, MVC3, and the UNity.MVC3 nuget package which has some additional code in it to handle lifetime management (ie objects that need disposal need special note in the bootstrapper.cs file.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.gecko-software.com/MVC IoC Demos 2.zip"&gt;IoC MVC Demos&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-8408802632074604528?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/8408802632074604528/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2011/12/using-dependency-injection-with-mvc.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/8408802632074604528'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/8408802632074604528'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2011/12/using-dependency-injection-with-mvc.html' title='Using Dependency Injection with MVC'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-3083718475570153890</id><published>2011-12-05T17:23:00.000-08:00</published><updated>2011-12-05T17:33:44.314-08:00</updated><title type='text'>Stop using MVC's ViewBag in most places, please!</title><content type='html'>Even the built in templates give us support for ViewBag. The scaffolding templates create ViewBag.SomeEnumerable to use for our pages.&lt;br /&gt;Sure - its quick code and since it's auto-generated will likely work ok. The problem comes in from the fact that ViewBag is a dynamic object. There are no compile time type checks. If you misspell something you won't be notified from the compiler.&lt;br /&gt;&lt;br /&gt;I've seen this used in such bad ways, I would love to see it's usage curbed and applications cleaned up. &lt;br /&gt;&lt;br /&gt;So in a controller:&lt;br /&gt;&lt;pre&gt;ViewBag.SomeProperty = "10"&lt;br /&gt;&lt;/pre&gt;and in the view:&lt;br /&gt;&lt;pre&gt;@ViewBag.Som3Pr0p3rty&lt;br /&gt;&lt;/pre&gt;We won't ever know of this error. It won't even generate a runtime error since the misspelled name just generated a null.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Use ViewModels and save yourself from these potential problems. Our templates set a page title in ViewBag as well.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;There are several options in setting a page title. Since this is a well known property one could argue that using it just for Title is ok. I wouldn't argue this. There are other options.&lt;br /&gt;1. Set it in a section in the layout and render it from the client.&lt;br /&gt;2. Use ViewBag.Title&lt;br /&gt;3. Use a filter (seems much too complicated for a title)&lt;br /&gt;4. Use a Model.Title field.&lt;br /&gt;&lt;br /&gt;Since by default we have a ViewBag.Title field created and our templates also get it by default, I'll yield that in this case, its ok.&lt;br /&gt;&lt;br /&gt;What about select lists?&lt;br /&gt;Rather than the default &lt;br /&gt;&lt;br /&gt;&lt;pre&gt; ViewBag.CustomerId = new SelectList(db.Customers, "CustomerId", "FirstName", order.CustomerId);&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Do something like&lt;br /&gt;&lt;pre&gt;yourViewModel.Customers = customers; //a loaded collection&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;and in your view&lt;br /&gt;&lt;pre&gt;@Html.DropDownListFor(x =&gt; x.CustomerId, new SelectList(Model.Customers, "CustomerId", "Name"))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Or if you prefer to set your ViewModel to contain the SelectList&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;yourViewModel.Customers = new SelectList(db.Customers, "CustomerId", "Name", order.CustomerId);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;and now your view would be slightly cleaner as:&lt;br /&gt;&lt;pre&gt;@Html.DropDownListFor(x =&gt; x.CustomerId, x.Customers)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;See, that's not so difficult now is it? Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-3083718475570153890?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/3083718475570153890/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2011/12/stop-using-viewbag-in-most-places.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/3083718475570153890'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/3083718475570153890'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2011/12/stop-using-viewbag-in-most-places.html' title='Stop using MVC&apos;s ViewBag in most places, please!'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-5870800237865310811</id><published>2011-10-07T10:05:00.000-07:00</published><updated>2011-10-07T10:05:05.620-07:00</updated><title type='text'>CodeCamp NYC Entity Framework / MVC code</title><content type='html'>Thanks to all the attendees for a great event! Here is a link to the demo project used both for the MVC and Entity framework application. Some more advanced MVC samples are included in a prior posting in august, but for this demo everything is in the zip.&lt;br /&gt;&lt;a href="https://docs.google.com/viewer?a=v&amp;pid=explorer&amp;chrome=true&amp;srcid=0B5XxGi0aNE6bYzdlZTljYTktODE0Ni00YWY3LWE3ODAtYjliZDNlZThiZmZm&amp;hl=en"&gt;Files here - Note - Click 'download original' in the upper right hand corner once the view loads&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-5870800237865310811?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/5870800237865310811/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2011/10/codecamp-nyc-entity-framework-mvc-code.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/5870800237865310811'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/5870800237865310811'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2011/10/codecamp-nyc-entity-framework-mvc-code.html' title='CodeCamp NYC Entity Framework / MVC code'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-8274664801214649742</id><published>2011-08-19T23:12:00.000-07:00</published><updated>2011-08-22T11:32:11.041-07:00</updated><title type='text'>Learning MVC for the Web Forms Developer - Code + Slides</title><content type='html'>There was a slightly older version of this posted, here's the slides (and code projects) from the current user group presentation. This is a 7-zip file for reduced size (yes - every time 7-zip wins out over zip in my tests!) &lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.gecko-software.com/WebFormsToMVC.zip"&gt;Code and slides&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-8274664801214649742?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/8274664801214649742/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2011/08/learning-mvc-for-web-forms-developer.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/8274664801214649742'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/8274664801214649742'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2011/08/learning-mvc-for-web-forms-developer.html' title='Learning MVC for the Web Forms Developer - Code + Slides'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-4077483698728973843</id><published>2011-08-17T19:05:00.000-07:00</published><updated>2011-08-17T19:05:38.178-07:00</updated><title type='text'>Remote (Ajax) Validation in MVC3</title><content type='html'>&lt;a href="http://www.gecko-software.com/MvcRemoteValidation.zip"&gt;Code for sample app &lt;/a&gt;&lt;br /&gt;Remote validation is a neat new feature in MVC3 that makes it easy to do AJAX validations. Why would you use these? Any time you don't want to use a full postback but must validate data on the server. How about two basic but common scenarios:&lt;br /&gt;1. Ensuring a registered email address is unique &lt;br /&gt;2. Checking if a login name is in use and in turn Recommending a login name for people to choose - as many systems currently do.&lt;br /&gt;&lt;br /&gt;For example, this cheesy app that validates an email address does not equal "test@test.com"&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-VRETeE2vVTs/Tkxvsd4BIuI/AAAAAAAAANU/JfXXOnUmkUI/s1600/CropperCapture%255B24%255D.jpg" imageanchor="1" style=""&gt;&lt;img border="0" height="269" width="400" src="http://1.bp.blogspot.com/-VRETeE2vVTs/Tkxvsd4BIuI/AAAAAAAAANU/JfXXOnUmkUI/s400/CropperCapture%255B24%255D.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;It's quite easy to implement Remote Validation in MVC3. I would recommend getting it working in a small test project first and then migrating to your real project and make sure it works there.&lt;br /&gt;&lt;br /&gt;1. I have this working with jQuery 1.4.4 IE   ~/Scripts/jquery-1.4.4.min.js&lt;br /&gt;2. Include the [Remote()] attribute on the property on your Model to point to the controller's method to call&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c#"&gt;        [RegularExpression(@"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*", ErrorMessage = "Please enter a valid e-mail address")]&lt;br /&gt;        [Required()]&lt;br /&gt;        [Display(Name = "Email Address")]&lt;br /&gt;        [Remote("EmailAddressUsed", "Demo", ErrorMessage = "Email Address Already On File")]&lt;br /&gt;        public string EmailAddress { get; set; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Note here I specify a controller named "Demo" and a method in that controller named EmailAddressUsed. The ErrorMessage attribute above actually didn't work for me, not entirely sure why so I'm returning a message from inside my controller method.&lt;br /&gt;&lt;br /&gt;3. The validation fires upon leaving focus (blur) on the form element.&lt;br /&gt;4. Return a Json result from your controller code. Return true if valid, otherwise I'm returning a validation message here.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c#"&gt;public JsonResult EmailAddressUsed(string emailAddress)&lt;br /&gt;{&lt;br /&gt;    if (emailAddress == "test@test.com")&lt;br /&gt;    {&lt;br /&gt;        return Json(emailAddress + " is already in use.", JsonRequestBehavior.AllowGet);&lt;br /&gt;    }&lt;br /&gt;    else&lt;br /&gt;    {&lt;br /&gt;        return Json(true, JsonRequestBehavior.AllowGet);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;That's all there is to it to get up and running: jQuery, controller method, attribute on the model.&lt;br /&gt;Enjoy!!&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-4077483698728973843?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/4077483698728973843/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2011/08/remote-ajax-validation-in-mvc3.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/4077483698728973843'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/4077483698728973843'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2011/08/remote-ajax-validation-in-mvc3.html' title='Remote (Ajax) Validation in MVC3'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-VRETeE2vVTs/Tkxvsd4BIuI/AAAAAAAAANU/JfXXOnUmkUI/s72-c/CropperCapture%255B24%255D.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-5636881987241682867</id><published>2011-06-08T10:45:00.000-07:00</published><updated>2011-06-08T10:45:06.818-07:00</updated><title type='text'>Finally HtmlEncoding syntax is coming to the databinding tag</title><content type='html'>In ASP.Net 4 MVC and WebForms, we currently have these two methods for automatically HtmlEncoding output without having to call HttpUtility.HtmlEncode(xxx)&lt;br /&gt;&lt;br /&gt;1. @  (Mvc 3 Razor syntax)&lt;br /&gt;2. &lt;%: which both automatically html encode the output to help prevent against XSS (Cross Site Scripting) attacks. This was lacking for data binding syntax for example:&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;%# Eval("FirstName") %&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;This above syntax had no html encoding and you specifically had to call it&lt;br /&gt;&lt;pre&gt;&amp;lt;%# HttpUtility.HtmlEncode((string)Eval("FirstName")) %&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In the future you will be able to just:&lt;pre&gt;&amp;lt;%#: Eval("FirstName") %&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This new syntax will be available in the next version of asp.net (4.1?)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-5636881987241682867?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/5636881987241682867/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2011/06/finally-htmlencoding-syntax-is-coming.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/5636881987241682867'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/5636881987241682867'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2011/06/finally-htmlencoding-syntax-is-coming.html' title='Finally HtmlEncoding syntax is coming to the databinding tag'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-9059713026291615633</id><published>2011-06-07T07:11:00.000-07:00</published><updated>2011-06-07T07:11:58.238-07:00</updated><title type='text'>Tech Ed Atlanta 2011 - Hack Proofing your ASP.Net MVC and WebForms Applications</title><content type='html'>We had a great time at tech ed this year!!&lt;br /&gt;My session on hack proofing is now online - check it out at:&lt;br /&gt;&lt;a href="http://channel9.msdn.com/Events/TechEd/NorthAmerica/2011/DEV333"&gt;http://channel9.msdn.com/Events/TechEd/NorthAmerica/2011/DEV333&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you watch it, please give it a rating so I know that you enjoyed it : )&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-9059713026291615633?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/9059713026291615633/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2011/06/tech-ed-atlanta-2011-hack-proofing-your.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/9059713026291615633'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/9059713026291615633'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2011/06/tech-ed-atlanta-2011-hack-proofing-your.html' title='Tech Ed Atlanta 2011 - Hack Proofing your ASP.Net MVC and WebForms Applications'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-3995456208066505617</id><published>2011-06-03T08:29:00.000-07:00</published><updated>2011-06-06T13:47:10.108-07:00</updated><title type='text'>MVC - Using Views outside of /Views or other content in /Views</title><content type='html'>I learned something new recently regarding this subject.&lt;br /&gt;First - to use a View outside of the /Views folder you must put a copy of your web.config from /Views into your new folder. It's that simple.&lt;br /&gt;&lt;br /&gt;Secondly - Views by default won't allow other content in them. If you drop a css file in the /Views folder and reference it via http://localhost/views/test.css you will get a 404 file not found error.&lt;br /&gt;&lt;br /&gt;If we look in the web.config inside of our views, we have:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;system.web&amp;gt;&lt;br /&gt;    &amp;lt;httpHandlers&amp;gt;&lt;br /&gt;      &amp;lt;add path=&amp;quot;*&amp;quot; verb=&amp;quot;*&amp;quot; type=&amp;quot;System.Web.HttpNotFoundHandler&amp;quot;/&amp;gt;&lt;br /&gt;    &amp;lt;/httpHandlers&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This essentially says make any item referenced in /Views (from path="*") a 404 status code - hence file not found. This means you can't address css files, jpegs, etc. - anything inside of /Views.  &lt;br /&gt;The workaround is easy though. Simply change the defined handler to exclude ONLY *.cshtml (hence views)&lt;br /&gt;&lt;br /&gt;Ideally we probably want to exclude *.cshtml and *.aspx in case we have any web forms view engine code. Unfortunately IIS6 and IIS7 have different syntax here. Changing the web.config in the &lt;b&gt;/Views&lt;/b&gt; folder we have:&lt;br /&gt;&lt;br /&gt;IIS6:&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;system.web&amp;gt;&lt;br /&gt;    &amp;lt;httpHandlers&amp;gt;&lt;br /&gt;      &amp;lt;add path=&amp;quot;*.cshtml,*.aspx&amp;quot; verb=&amp;quot;*&amp;quot; type=&amp;quot;System.Web.HttpNotFoundHandler&amp;quot; /&amp;gt;&lt;br /&gt;    &amp;lt;/httpHandlers&amp;gt;&lt;br /&gt;  &amp;lt;/system.web&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In IIS7:&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;system.webServer&amp;gt;&lt;br /&gt;    &amp;lt;handlers&amp;gt;&lt;br /&gt;      &amp;lt;add name=&amp;quot;ExcludeRazorViews&amp;quot; path=&amp;quot;*.cshtml&amp;quot; verb=&amp;quot;*&amp;quot; type=&amp;quot;System.Web.HttpNotFoundHandler&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;add name=&amp;quot;ExcludeWebFormsViews&amp;quot; path=&amp;quot;*.aspx&amp;quot; verb=&amp;quot;*&amp;quot; type=&amp;quot;System.Web.HttpNotFoundHandler&amp;quot; /&amp;gt;&lt;br /&gt;    &amp;lt;/handlers&amp;gt;&lt;br /&gt;  &amp;lt;/system.webServer&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Note also that the web.config in the /Views folder also contains this one as well at the bottom you'll need to watch out for that is provided for IIS 7 compatibility:&lt;br /&gt;&lt;pre class="brush: xml"&gt;    &amp;lt;handlers&amp;gt;&lt;br /&gt;      &amp;lt;remove name=&amp;quot;BlockViewHandler&amp;quot;/&amp;gt;&lt;br /&gt;      &amp;lt;add name=&amp;quot;BlockViewHandler&amp;quot; path=&amp;quot;*&amp;quot; verb=&amp;quot;*&amp;quot; preCondition=&amp;quot;integratedMode&amp;quot; type=&amp;quot;System.Web.HttpNotFoundHandler&amp;quot; /&amp;gt;&lt;br /&gt;    &amp;lt;/handlers&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-3995456208066505617?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/3995456208066505617/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2011/06/using-views-outside-of-views-or-other.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/3995456208066505617'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/3995456208066505617'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2011/06/using-views-outside-of-views-or-other.html' title='MVC - Using Views outside of /Views or other content in /Views'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-3768697517239273720</id><published>2011-04-23T21:44:00.000-07:00</published><updated>2011-04-25T23:23:54.343-07:00</updated><title type='text'>Learning MVC for the Web Forms Developer - Code + Slides</title><content type='html'>&lt;a href="http://www.gecko-software.com/WebFormsToMVC_Code_And_Slides.zip"&gt;Download code and slides here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Note the file is ~25MB because of the size of the embedded databases. Unzipped around 60MB or so for all of the projects (again mostly because of the databases)&lt;br /&gt;&lt;br /&gt;Let me know if you have any problems setting it up. The first couple slides contain some notes on the projects.&lt;br /&gt;&lt;br /&gt;Thanks for attending!!!&lt;br /&gt;&lt;br /&gt;I realize it was a _ton_ of information to throw at you. This could easily have been turned into a 4+ hour talk but there's a reason I put all of that in this talk. If you are new to MVC it makes it even more difficult, but I feel these are all areas important to getting up and running effectively on MVC. Where to start if you are new? Create a new mvc 3 project. Now go through the slides and create each item. Create a route. Create a model, a controller, a view. Then save data using the PRG pattern. Then try to load some data into a div via an ajax call or even just an ajax form using @Ajax.BeginForm. This will get you off to a nice start - just let me know if you have any questions - I'll try to steer you in the right direction : )&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-3768697517239273720?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/3768697517239273720/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2011/04/learning-mvc-for-web-forms-developer.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/3768697517239273720'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/3768697517239273720'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2011/04/learning-mvc-for-web-forms-developer.html' title='Learning MVC for the Web Forms Developer - Code + Slides'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-3399694692814098866</id><published>2011-04-23T17:30:00.000-07:00</published><updated>2011-04-23T17:30:03.083-07:00</updated><title type='text'>Entity Framework Error - The relationship '{0}' was not loaded because the type '{1}' is not available.</title><content type='html'>I had changed an applications data architecture slightly and instead of going to a network Sql Server instance, I decided to use the App_Data folder to make this application distribute a bit easier for demo purposes.&lt;br /&gt;&lt;br /&gt;This error was caused because my connect string wasn't correct to the database. The connect strings for App_Data databases use a local path to attach to a database file such as:&lt;br /&gt;AttachDbFilename=|DataDirectory|\MyDatabase.mdb&lt;br /&gt;&lt;br /&gt;I thought my connect string was correct in the web.config of the application that used my data access layer and the error doesn't of course tell me anything is wrong with my connect string, but I figured I'd give it a try. &lt;br /&gt;&lt;br /&gt;In order to properly reference my database in _another project_ I needed the dialog to give me the connect string to make sure it was all 100% ok, and then I just would edit the db path to be relative from the absolute path the dialog displays. So - I went back into my data access project and selected to add a new entity framework model. When the dialog came up, I simply copied the app_data database connectstring and then canceled out of the dialog and updated my other project's web.config:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-6Dp0MukXEz8/TbNucQ5SacI/AAAAAAAAAL4/Xjf7h79zdL8/s1600/SecurityDemoEntities.jpg" imageanchor="1" style=""&gt;&lt;img border="0" height="359" width="400" src="http://1.bp.blogspot.com/-6Dp0MukXEz8/TbNucQ5SacI/AAAAAAAAAL4/Xjf7h79zdL8/s400/SecurityDemoEntities.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Schema specified is not valid. Errors:&lt;br /&gt;The relationship 'NASA.FK_Booster_Catalog' was not loaded because the type 'NASA.Catalog' is not available.&lt;br /&gt;Exception Details: System.Data.MetadataException: Schema specified is not valid. Errors:&lt;br /&gt;The following information may be useful in resolving the previous error:&lt;br /&gt;The required property 'Password' does not exist on the type 'NASA.DataAccess.Models.Catalog'.&lt;br /&gt;&lt;br /&gt;Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.&lt;br /&gt;&lt;br /&gt;The required property 'Password' does not exist on the type 'WebStore.DataAccess.Models.Customer'.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Source Error:&lt;br /&gt;&lt;br /&gt;Line 69:         public ObjectSet&lt;Product&gt; Products&lt;br /&gt;Line 70:         {&lt;br /&gt;Line 71:             get { return _catalogs  ?? (_catalogs = CreateObjectSet&lt;Catalog&gt;("Catalogs")); }&lt;br /&gt;Line 72:         }&lt;br /&gt;Line 73:         private ObjectSet&lt;Catalog&gt; _catalogs;&lt;br /&gt;&lt;br /&gt;Stack Trace:&lt;br /&gt;&lt;br /&gt;System.Data.Metadata.Edm.ObjectItemCollection.LoadAssemblyFromCache(ObjectItemCollection objectItemCollection, Assembly assembly, Boolean loadReferencedAssemblies, EdmItemCollection edmItemCollection, Action`1 logLoadMessage) +480&lt;br /&gt;   System.Data.Metadata.Edm.ObjectItemCollection.ImplicitLoadAssemblyForType(Type type, EdmItemCollection edmItemCollection) +84&lt;br /&gt;   System.Data.Metadata.Edm.MetadataWorkspace.ImplicitLoadAssemblyForType(Type type, Assembly callingAssembly) +151&lt;br /&gt;   System.Data.Objects.ObjectContext.GetTypeUsage(Type entityCLRType) +35&lt;br /&gt;   System.Data.Objects.ObjectContext.GetEntitySetForNameAndType(String entitySetName, Type entityCLRType, String exceptionParameterName) +33&lt;br /&gt;   System.Data.Objects.ObjectContext.CreateObjectSet(String entitySetName) +66&lt;br /&gt;..&lt;br /&gt;..&lt;br /&gt;..&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-3399694692814098866?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/3399694692814098866/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2011/04/entity-framework-error-relationship-0.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/3399694692814098866'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/3399694692814098866'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2011/04/entity-framework-error-relationship-0.html' title='Entity Framework Error - The relationship &apos;{0}&apos; was not loaded because the type &apos;{1}&apos; is not available.'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-6Dp0MukXEz8/TbNucQ5SacI/AAAAAAAAAL4/Xjf7h79zdL8/s72-c/SecurityDemoEntities.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-2414386676035899227</id><published>2011-04-23T10:08:00.000-07:00</published><updated>2011-04-23T10:08:30.202-07:00</updated><title type='text'>I finally joined 2011 and created my twitter account</title><content type='html'>My twitter account is @AdamTuliper - I feel so 'modern' : ) Stay tuned for various links, updates, tech ed info, etc!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-2414386676035899227?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/2414386676035899227/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2011/04/i-finally-joined-2011-and-created-my.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/2414386676035899227'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/2414386676035899227'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2011/04/i-finally-joined-2011-and-created-my.html' title='I finally joined 2011 and created my twitter account'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-4323362156590147240</id><published>2011-04-22T06:46:00.000-07:00</published><updated>2011-04-22T06:46:44.942-07:00</updated><title type='text'>MVC MVC MVC</title><content type='html'>Its been a busy couple weeks!! Presentations in NYC, Philly, CT, and now Tech Ed Atlanta coming up. For those that attended the MVC presentation on "Learning MVC for the Web Forms Developer" - Thanks!  I'll be posting the code and slides shortly, I just need to make sure the projects don't just work on my machine and are easy for you to setup - including database access. Please check back shortly, hopefully this weekend I'll have everything up there.&lt;br /&gt;&lt;br /&gt;A special thanks to the guys that took me out after last nights Manhattan presentation for a couple brews : )&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-4323362156590147240?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/4323362156590147240/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2011/04/mvc-mvc-mvc.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/4323362156590147240'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/4323362156590147240'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2011/04/mvc-mvc-mvc.html' title='MVC MVC MVC'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-8211772435396993673</id><published>2011-03-11T15:03:00.000-08:00</published><updated>2011-03-11T15:03:15.478-08:00</updated><title type='text'>R.I.P. To our friend, The Free Version of Reflector</title><content type='html'>Reflector is one of the best tools every invented and unfortunately is no longer free. If this was a brand new product, I would have no issue paying the mere $35 for it - however this tool has _always_ been free. Red Gate bought this tool a couple years ago and as of this month it is no longer free. OK - so run the older version. Well - it deletes itself.&lt;br /&gt;&lt;br /&gt;So this shows a bit of premeditation built into their software that they would one day delete this from people's systems. I have a problem with this. A free tool is a FREE tool. Not 'free until we decide to make you pay and delete the free version you had'. I don't feel this is correct in any way.&lt;br /&gt;&lt;br /&gt;With that said if the Pro version of this tool was $35 with built in debugging for compiled assemblies, I would think that would be a great deal. Alas, we are paying $35 to regain what we already had in this tool.&lt;br /&gt;&lt;br /&gt;This practice has made quite a few people angry. I love Red Gate's products, but I really believe they went about this the wrong way by deleting free software installed on our machines. &lt;br /&gt;&lt;br /&gt;I now will be recommending ILSpy. An open source program that started development when Red Gate announced they would be charging for Reflector.&lt;br /&gt;&lt;br /&gt;http://wiki.sharpdevelop.net/ilspy.ashx&lt;br /&gt;&lt;br /&gt;Is it as good as reflector? No. Is it free? Yes!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-8211772435396993673?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/8211772435396993673/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2011/03/rip-to-our-friend-free-version-of.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/8211772435396993673'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/8211772435396993673'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2011/03/rip-to-our-friend-free-version-of.html' title='R.I.P. To our friend, The Free Version of Reflector'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-1557461589802673337</id><published>2011-02-28T18:23:00.000-08:00</published><updated>2011-02-28T18:23:15.563-08:00</updated><title type='text'>The WRONG way to use stored procedure calls</title><content type='html'>Stored procedures are an excellent way to prevent sql injection attacks. However they must be called using parameters, and in addition, using parameters _correctly_.&lt;br /&gt;The following is an example of how NOT to call a stored procedure.&lt;br /&gt;&lt;br /&gt;We start with the following procedure&lt;br /&gt;&lt;pre class="brush: sql"&gt;Create Procedure Proc_GetUser&lt;br /&gt;@userId int&lt;br /&gt;AS&lt;br /&gt;Select UserName, Password From User Where UserId = @userId &lt;br /&gt;GO&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And the following code call&lt;br /&gt;&lt;pre class="brush: csharp"&gt;using (SqlCommand command = new SqlCommand("proc_GetUser(@UserId='" + userId.ToString() + "')", ctx.Connection))&lt;br /&gt;{&lt;br /&gt;    SqlDataReader dataReader = command.ExecuteReader();&lt;br /&gt;    //use data reader here..&lt;br /&gt;    //...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;What is wrong with this? It uses a named parameter, isn't that OK?&lt;br /&gt;&lt;br /&gt;Nope.&lt;br /&gt;&lt;br /&gt;I've seen this done in production applications, and it is susceptible to sql injection. If an attacker sets UserId to something like:&lt;br /&gt;nobody');EVILSQL;print (' &lt;br /&gt;This makes our sql statment now &lt;br /&gt;&lt;pre class="brush: sql"&gt;Proc_GetUser(@UserId='nobody');EVILSQL; print ('')&lt;br /&gt;&lt;/pre&gt;They have just executed the first call and then the second batch of "EVILSQL" and have successfully closed off your query with "print('" to form "print('')" which then does nothing.&lt;br /&gt;&lt;br /&gt;The correct way to do this is as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp"&gt;using (SqlCommand command = new SqlCommand("Proc_GetUser", ctx.Connection))&lt;br /&gt;{&lt;br /&gt;    command.CommandType = System.Data.CommandType.StoredProcedure;&lt;br /&gt;    command.Parameters.AddWithValue("@UserId", userId);&lt;br /&gt;    SqlDataReader dataReader = command.ExecuteReader();&lt;br /&gt;    //use data reader here..&lt;br /&gt;    //...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-1557461589802673337?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/1557461589802673337/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2011/02/wrong-way-to-use-stored-procedure-calls.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/1557461589802673337'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/1557461589802673337'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2011/02/wrong-way-to-use-stored-procedure-calls.html' title='The WRONG way to use stored procedure calls'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-8646896606760687565</id><published>2011-02-28T18:03:00.000-08:00</published><updated>2011-06-07T07:07:48.302-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mvc razor unobtrusive javascript'/><title type='text'>Unobstrusive Javascript in MVC 3 helps clean up your forms</title><content type='html'>A great new feature in MVC 3 is unobstrusive javascript. This uses the magic of jQuery to hook attributes on your page without injecting a bunch of javascript into your forms as was done before.&lt;br /&gt;&lt;br /&gt;To enable it, simply add this to your web.config&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;configuration&amp;gt;&lt;br /&gt;&amp;lt;appSettings&amp;gt;&lt;br /&gt;&amp;lt;add key=&amp;quot;UnobtrusiveJavaScriptEnabled&amp;quot; value=&amp;quot;true&amp;quot;/&amp;gt;&lt;br /&gt;&amp;lt;/appSettings&amp;gt;&lt;br /&gt;&amp;lt;/configuration&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This makes ajax form submission code extremely easy. If you've ever tried to debug why a form wasn't submitted because of the emitted javascript from Ajax.BeginForm, you'll be happy to know your forms now are so much more readable. &lt;br /&gt;&lt;br /&gt;We'll discuss the various options available shortly, but let's explain this from the beginning. If you want this all to happen automagically, you don't need to do anything but include the scripts (mentioned below), use mvc 3, and continue to use Ajax.BeginForm. The 'javascript-less' form tag will be emitted. If you want to do this manually, you enable your forms by including data-ajax="true" such as:&lt;br /&gt;&amp;lt;form data-ajax="true" ...&amp;gt;&lt;br /&gt;&lt;br /&gt;The inclusion of data-ajax="true" is where the magic comes into play.&lt;br /&gt;&lt;br /&gt;In the unobtrusive jQuery library (jQuery.unobtrusive-ajax.js), we see this piece of code below that finds certain elements with data-ajax="true" and hooks them using the .live() method of jQuery. This methods hooks anything that exists in the DOM now and anything that is dynamically created in the DOM later via code.&lt;br /&gt;&lt;pre class="brush: js"&gt;//A HREF links hooked&lt;br /&gt;$(&amp;quot;a[data-ajax=true]&amp;quot;).live(&amp;quot;click&amp;quot;, function (evt) {&lt;br /&gt;evt.preventDefault();&lt;br /&gt;asyncRequest(this, {&lt;br /&gt;url: this.href,&lt;br /&gt;type: &amp;quot;GET&amp;quot;,&lt;br /&gt;data: []&lt;br /&gt;});&lt;br /&gt;});&lt;br /&gt;&lt;br /&gt;//images hooked inside a form&lt;br /&gt;$(&amp;quot;form[data-ajax=true] input[type=image]&amp;quot;).live(&amp;quot;click&amp;quot;, function (evt) {&lt;br /&gt;var name = evt.target.name,&lt;br /&gt;$target = $(evt.target),&lt;br /&gt;form = $target.parents(&amp;quot;form&amp;quot;)[0],&lt;br /&gt;offset = $target.offset();&lt;br /&gt;&lt;br /&gt;$(form).data(data_click, [&lt;br /&gt;{ name: name + &amp;quot;.x&amp;quot;, value: Math.round(evt.pageX - offset.left) },&lt;br /&gt;{ name: name + &amp;quot;.y&amp;quot;, value: Math.round(evt.pageY - offset.top) }&lt;br /&gt;]);&lt;br /&gt;&lt;br /&gt;setTimeout(function () {&lt;br /&gt;$(form).removeData(data_click);&lt;br /&gt;}, 0);&lt;br /&gt;});&lt;br /&gt;&lt;br /&gt;//Form submit function hooked&lt;br /&gt;$(&amp;quot;form[data-ajax=true] :submit&amp;quot;).live(&amp;quot;click&amp;quot;, function (evt) {&lt;br /&gt;var name = evt.target.name,&lt;br /&gt;form = $(evt.target).parents(&amp;quot;form&amp;quot;)[0];&lt;br /&gt;&lt;br /&gt;$(form).data(data_click, name ? [{ name: name, value: evt.target.value }] : []);&lt;br /&gt;&lt;br /&gt;setTimeout(function () {&lt;br /&gt;$(form).removeData(data_click);&lt;br /&gt;}, 0);&lt;br /&gt;});&lt;br /&gt;&lt;br /&gt;//Form hooked&lt;br /&gt;$(&amp;quot;form[data-ajax=true]&amp;quot;).live(&amp;quot;submit&amp;quot;, function (evt) {&lt;br /&gt;var clickInfo = $(this).data(data_click) || [];&lt;br /&gt;evt.preventDefault();&lt;br /&gt;if (!validate(this)) {&lt;br /&gt;return;&lt;br /&gt;}&lt;br /&gt;asyncRequest(this, {&lt;br /&gt;url: this.action,&lt;br /&gt;type: this.method || &amp;quot;GET&amp;quot;,&lt;br /&gt;data: clickInfo.concat($(this).serializeArray())&lt;br /&gt;});&lt;br /&gt;});&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So, using this we no longer have to use code like such (but WE CAN still use this syntax if you want, as long as unobtrusive javascript is enabled in the web.config, the new form syntax will automatically be emitted):&lt;br /&gt;&lt;pre class="brush: csharp"&gt;&amp;lt;% using (Ajax.BeginForm(&amp;quot;Index&amp;quot;, &amp;quot;Customer&amp;quot;, new AjaxOptions { UpdateTargetId = &amp;quot;customerArea&amp;quot;, LoadingElementId = &amp;quot;customerWaitImage&amp;quot;, OnFailure=&amp;quot;ajaxCustomerFailed&amp;quot;, OnSuccess=&amp;quot;ajaxCustomerSuccess&amp;quot; } )) { %&amp;gt;&lt;br /&gt;..&lt;br /&gt;..&lt;br /&gt;&amp;lt;%}%&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;We can now simply&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;form data-ajax="true" data-ajax-failure="ajaxCustomerFailed" data-ajax-success="ajaxCustomerSuccess" data-ajax-update="customerArea" data-ajax-loading="customerWaitImage" data-ajax-method="Post" &amp;gt;&lt;br /&gt;...&lt;br /&gt;..&lt;br /&gt;&amp;lt;/form&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Its very readable, requires no inline code, and renders with no javascript emitted to the page. You must make sure though you&lt;br /&gt;&lt;pre&gt;1. Set the mentioned flag in the web.config: &amp;lt;add key="UnobtrusiveJavaScriptEnabled" value="true"/&amp;gt;&lt;br /&gt;2. Include a reference to the jQuery library ~/Scripts/jquery-1.4.4.js&lt;br /&gt;3. Include a reference to the library that hooks this magic at ~/Scripts/jquery.unobtrusive-ajax.js&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;If you do not have the script reference, note - the form will do a full post as opposed to an ajax post.&lt;br /&gt;&lt;br /&gt;The options that are supported map directly from what was available in Ajax.BeginForm's AjaxOptions. The only reference I could find was the table I included below from &lt;a href="http://bradwilson.typepad.com/blog/2010/10/mvc3-unobtrusive-ajax.html"&gt;Brad Wilson's blog&lt;/a&gt;, it doesn't seem as though Microsoft has the documentation available at the moment of this writing. &lt;br /&gt;&lt;br /&gt;&lt;table cellspacing="0" cellpadding="4" border="1"&gt;&lt;tbody&gt;&lt;tr&gt; &lt;th&gt;AjaxOptions&lt;/th&gt;  &lt;th&gt;HTML attribute&lt;/th&gt; &lt;/tr&gt;&lt;tr&gt;&lt;/tr&gt;&lt;tr&gt; &lt;td&gt;Confirm&lt;/td&gt;  &lt;td&gt;data-ajax-confirm&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;HttpMethod&lt;/td&gt;  &lt;td&gt;data-ajax-method&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;InsertionMode&lt;/td&gt;  &lt;td&gt;data-ajax-mode *&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;LoadingElementDuration&lt;/td&gt;  &lt;td&gt;data-ajax-loading-duration **&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;LoadingElementId&lt;/td&gt;  &lt;td&gt;data-ajax-loading&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;OnBegin&lt;/td&gt;  &lt;td&gt;data-ajax-begin&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;OnComplete&lt;/td&gt;  &lt;td&gt;data-ajax-complete&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;OnFailure&lt;/td&gt;  &lt;td&gt;data-ajax-failure&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;OnSuccess&lt;/td&gt;  &lt;td&gt;data-ajax-success&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;UpdateTargetId&lt;/td&gt;  &lt;td&gt;data-ajax-update&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;Url&lt;/td&gt;  &lt;td&gt;data-ajax-url&lt;/td&gt; &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;Again, remember - you can get the benefit of this by doing this manually in your form element, or simply continue using Ajax.BeginForm with unobtrusive javascsript enabled in the web.config and you will get the benefits of this new form syntax.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp"&gt;@using (Ajax.BeginForm("ControllerMethod", "ControllerName", new AjaxOptions() { LoadingElementId="loadingImage", OnSuccess = "success", OnFailure = "error", UpdateTargetId = "testDialog", InsertionMode = InsertionMode.Replace })){&lt;br /&gt;&amp;lt;div id="testDialog"&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A couple of extras - if you want to disable validation for a particular button you need to call &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: javascript"&gt;&lt;br /&gt;$("#myinput").rules("remove");&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;See &lt;br /&gt;&lt;a href="http://docs.jquery.com/Plugins/Validation/rules#.22remove.22rules"&gt;jQuery rules remove&lt;/a&gt;&lt;br /&gt; for more details&lt;br /&gt;&lt;br /&gt;Secondly, if you want to check via script if the form is valid you can check onsubmit (or other functions) easily as follows:&lt;br /&gt;&lt;pre class="brush: javascript"&gt;&lt;br /&gt;$(function () &lt;br /&gt;{&lt;br /&gt;  $(&amp;#39;#yourForm&amp;#39;).submit(&lt;br /&gt;        function () {&lt;br /&gt;                 if(!$(this).valid()) {&lt;br /&gt;                                       //form is not valid         &lt;br /&gt;                                      }     &lt;br /&gt;                     }); &lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Enjoy - I love this new feature especially when trying to debug ajax partial views as it makes my life easier : )&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-8646896606760687565?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/8646896606760687565/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2011/02/unobstrusive-javascript-in-mvc-3-helps.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/8646896606760687565'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/8646896606760687565'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2011/02/unobstrusive-javascript-in-mvc-3-helps.html' title='Unobstrusive Javascript in MVC 3 helps clean up your forms'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-7077575856713280074</id><published>2011-02-26T20:59:00.000-08:00</published><updated>2011-02-26T21:02:37.901-08:00</updated><title type='text'>Converting MVC 2.0 projects to MVC 3 (Razor)</title><content type='html'>Microsoft has outlined the steps to convert a project from MVC 2 to 3 here:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.asp.net/learn/whitepapers/mvc3-release-notes"&gt;Upgrading an ASP.NET MVC 2 Project to ASP.NET MVC 3&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;You also have the option of using a tool to do this, see&lt;br /&gt;&lt;a href="http://aspnet.codeplex.com/releases/view/59008"&gt;ASP.NET MVC 3 Application Upgrader&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;It may be easiest to simply import all your files into the new project and migrate each web.config section over. However - if you do decide to convert your projects over there are two additional things to keep in mind.&lt;br /&gt;&lt;br /&gt;After upgrading you should&lt;br /&gt;1. Be aware that keeping the existing binding redirect that exists in 2.0 projects to force all 1.x-2.0 System.Web.MVC libraries to bind to MVC 2.0 can cause your worker process to crash. This was in 2.0 projects by default. You MUST remove this (replace it with a binding to 3.0 and not 2.0)&lt;br /&gt;&lt;pre class="brush: xml;"&gt;&lt;br /&gt;&amp;lt;runtime&amp;gt;&lt;br /&gt;    &amp;lt;assemblyBinding xmlns=&amp;quot;urn:schemas-microsoft-com:asm.v1&amp;quot;&amp;gt;&lt;br /&gt;      &amp;lt;dependentAssembly&amp;gt;&lt;br /&gt;        &amp;lt;assemblyIdentity name=&amp;quot;System.Web.Mvc&amp;quot; publicKeyToken=&amp;quot;31bf3856ad364e35&amp;quot; /&amp;gt;&lt;br /&gt;        &amp;lt;bindingRedirect oldVersion=&amp;quot;2.0.0.0&amp;quot; newVersion=&amp;quot;2.0.0.0&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;/dependentAssembly&amp;gt;&lt;br /&gt;    &amp;lt;/assemblyBinding&amp;gt;&lt;br /&gt;  &amp;lt;/runtime&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You should _replace_ it with the following&lt;br /&gt;&lt;pre class="brush: xml;"&gt;&lt;br /&gt;&amp;lt;runtime&amp;gt;&lt;br /&gt;    &amp;lt;assemblyBinding&lt;br /&gt;  xmlns=&amp;quot;urn:schemas-microsoft-com:asm.v1&amp;quot;&amp;gt;&lt;br /&gt;      &amp;lt;dependentAssembly&amp;gt;&lt;br /&gt;        &amp;lt;assemblyIdentity&lt;br /&gt;      name=&amp;quot;System.Web.Mvc&amp;quot;&lt;br /&gt;&lt;br /&gt;      publicKeyToken=&amp;quot;31bf3856ad364e35&amp;quot;/&amp;gt;&lt;br /&gt;        &amp;lt;bindingRedirect&lt;br /&gt;      oldVersion=&amp;quot;1.0.0.0-2.0.0.0&amp;quot; newVersion=&amp;quot;3.0.0.0&amp;quot;/&amp;gt;&lt;br /&gt;      &amp;lt;/dependentAssembly&amp;gt;&lt;br /&gt;    &amp;lt;/assemblyBinding&amp;gt;&lt;br /&gt;  &amp;lt;/runtime&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;2. Let's say all of my views use the MVCContrib grid and the Microsoft Futures or other features. Rather than having import statements on all of your razor views such as:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;@using MvcContrib.UI.Grid;&lt;br /&gt;@using Microsoft.Web.Mvc&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You can simply include these imports in the web.config as you can with web forms projects, but the section to include them is different for mvc 3. &lt;br /&gt;&lt;br /&gt;first add this to the &amp;lt;configuration&amp;gt;&amp;lt;configSections&amp;gt; section&lt;br /&gt;&lt;pre class="brush: xml;"&gt;&lt;br /&gt; &amp;lt;sectionGroup name=&amp;quot;system.web.webPages.razor&amp;quot; type=&amp;quot;System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&amp;quot;&amp;gt;&lt;br /&gt;      &amp;lt;section name=&amp;quot;host&amp;quot; type=&amp;quot;System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&amp;quot; requirePermission=&amp;quot;false&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;section name=&amp;quot;pages&amp;quot; type=&amp;quot;System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&amp;quot; requirePermission=&amp;quot;false&amp;quot; /&amp;gt;&lt;br /&gt;    &amp;lt;/sectionGroup&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now add this section under your &amp;lt;configuration&amp;gt;&lt;br /&gt;&lt;pre class="brush: xml;"&gt;&lt;br /&gt;  &amp;lt;system.web.webPages.razor&amp;gt;&lt;br /&gt;    &amp;lt;pages pageBaseType=&amp;quot;System.Web.Mvc.WebViewPage&amp;quot;&amp;gt;&lt;br /&gt;      &amp;lt;namespaces&amp;gt;&lt;br /&gt;        &amp;lt;add namespace=&amp;quot;MvcContrib.UI.Grid&amp;quot; /&amp;gt;&lt;br /&gt;        &amp;lt;add namespace=&amp;quot;Microsoft.Web.Mvc&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;/namespaces&amp;gt;&lt;br /&gt;    &amp;lt;/pages&amp;gt;&lt;br /&gt;  &amp;lt;/system.web.webPages.razor&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;See it all here:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-5K1xVWSdyUA/TWnZawn0FII/AAAAAAAAALw/X0znM-5KxCQ/s1600/webconfig.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 213px;" src="http://3.bp.blogspot.com/-5K1xVWSdyUA/TWnZawn0FII/AAAAAAAAALw/X0znM-5KxCQ/s400/webconfig.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5578228667226788994" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-7077575856713280074?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/7077575856713280074/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2011/02/converting-mvc-20-projects-to-mvc-3.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/7077575856713280074'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/7077575856713280074'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2011/02/converting-mvc-20-projects-to-mvc-3.html' title='Converting MVC 2.0 projects to MVC 3 (Razor)'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-5K1xVWSdyUA/TWnZawn0FII/AAAAAAAAALw/X0znM-5KxCQ/s72-c/webconfig.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-6127100593377800795</id><published>2010-12-13T21:03:00.001-08:00</published><updated>2010-12-13T21:41:25.456-08:00</updated><title type='text'>Status Message Handling in MVC</title><content type='html'>Here's a quick method I use to handle status messages in MVC. It uses an extension method. This means when you use Intellisense on TempData or ViewData, this method will appear as TempData.AddStatusMessage or ViewData.AddStatusMessage.&lt;br /&gt;&lt;br /&gt;The problem to solve here is after we save a user, we want to display something like 'User Saved', but since good MVC design practices dictate using the PRG pattern (Post/Redirect/Get), GET requests do not lend themselves nicely to status messages and thus we have a problem.&lt;br /&gt;&lt;br /&gt;Remember that we cannot simply set a label from a code behind as may be done in Asp.Net Web Forms. We need another way to accomplish this in the scope of MVC.&lt;br /&gt;&lt;br /&gt;I go not recommend using a parameter as a status message as it gives a direct attack vector into your application from a security standpoint. A user can do something along the lines of&lt;br /&gt;/Users/Index?status=&lt;script&gt;evil script&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Yes - you can help prevent this by encoding the message before displaying, but why even open up the possibility when there are other ways to accomplish this.&lt;br /&gt;&lt;br /&gt;So let's have these requirements:&lt;br /&gt;1. Any code in a controller can add a status message (pages cannot add status messages via this mechanism in my design since the data for the view should already be formed. anything else can use conditional view logic on the page)&lt;br /&gt;2. Status messages can be for the current request (for example, when a post request fails and needs to redisplay data immediately without a redirect)&lt;br /&gt;3. Status messages can be for the next request (IE the GET portion of the Post/Redirect/Get pattern, for ex. 'User Saved Successfully'&lt;br /&gt;&lt;br /&gt;To use this code, simply put the following code in your Site.Master (or any page the results should be rendered to)&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c#;"&gt;&lt;br /&gt;&amp;lt;%= ViewData.GetMessageSummary()%&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;&amp;lt;%= TempData.GetMessageSummary()%&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;To add a message to tempdata, so it will show up on the next request only (as this is how TempData works)&lt;br /&gt;&lt;pre class="brush: c#;"&gt;&lt;br /&gt;TempData.AddStatusMessage("User Saved Successfully");&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;To add a message that is displayed when the current request is rendered&lt;br /&gt;&lt;pre class="brush: c#;"&gt;&lt;br /&gt;ViewData.AddStatusMessage("Please fix the errors below");&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The code is as follows&lt;br /&gt;&lt;pre class="brush: c#;"&gt;&lt;br /&gt;    public static class ViewDataExtensions&lt;br /&gt;    {&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Gets the status messages from TempData and ViewData.&lt;br /&gt;        /// When this is called, the status messages are cleared.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="viewData"&amp;gt;&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="message"&amp;gt;&amp;lt;/param&amp;gt;&lt;br /&gt;        public static string GetMessageSummary(this IDictionary&amp;lt;string, object&amp;gt; viewData)&lt;br /&gt;        {&lt;br /&gt;&lt;br /&gt;            //&amp;lt;/div&amp;gt;", &lt;br /&gt;            //&amp;lt;label style="background-color: &amp;lt;%:  ViewData["JobStatusMessageColor"] %&amp;gt;"&amp;gt;&lt;br /&gt;            //&amp;lt;%: ViewData["StatusMessage"]%&amp;gt;&amp;lt;/label&amp;gt;&lt;br /&gt;&lt;br /&gt;            List&amp;lt;string&amp;gt; messageItems = (List&amp;lt;string&amp;gt;)viewData["StatusMessages"];&lt;br /&gt;            if (messageItems != null)&lt;br /&gt;            {&lt;br /&gt;                StringBuilder sb = new StringBuilder();&lt;br /&gt;                sb.Append("&amp;lt;br&amp;gt;&amp;lt;div class=\"status-message\"&amp;gt;\r\n&amp;lt;ul&amp;gt;");&lt;br /&gt;&lt;br /&gt;                foreach (string item in messageItems)&lt;br /&gt;                {&lt;br /&gt;                    sb.Append(string.Format("&amp;lt;li&amp;gt;{0}&amp;lt;/li&amp;gt;\r\n", item));&lt;br /&gt;                }&lt;br /&gt;                sb.Append("&amp;lt;/ul&amp;gt;\r\n&amp;lt;/div&amp;gt;");&lt;br /&gt;                return sb.ToString();&lt;br /&gt;            }&lt;br /&gt;            //Im assuming internally this is thread safe since its ViewData or TempData being used. it could be false but going with that for now : )&lt;br /&gt;            viewData.Remove("StatusMessages");&lt;br /&gt;            return "";&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Adds a status message to ViewData, meant to be displayed on the _current_ request&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="viewData"&amp;gt;Since this is an extension method, this operates on TempData.AddStatusMessage&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="message"&amp;gt;The message to be added to the collection&amp;lt;/param&amp;gt;&lt;br /&gt;        public static void AddStatusMessage(this ViewDataDictionary viewData, string message)&lt;br /&gt;        {&lt;br /&gt;            AddStatusMessageToDictionary(viewData, message);&lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Adds a status message to TempDate, meant to be displayed on the very _next_ request.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="viewData"&amp;gt;Since this is an extension method, this operates on TempData.AddStatusMessage&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="message"&amp;gt;The message to be added to the collection&amp;lt;/param&amp;gt;&lt;br /&gt;        public static void AddStatusMessage(this TempDataDictionary viewData , string message)&lt;br /&gt;        {&lt;br /&gt;            AddStatusMessageToDictionary(viewData, message);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Adds a message to be displayed to the user. This works with ViewData and TempData&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="viewData"&amp;gt;&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="message"&amp;gt;&amp;lt;/param&amp;gt;&lt;br /&gt;        private static void AddStatusMessageToDictionary(this IDictionary&amp;lt;string, object&amp;gt; viewData, string message)&lt;br /&gt;        {&lt;br /&gt;            List&amp;lt;string&amp;gt; messageItems;&lt;br /&gt;            if (viewData.ContainsKey("StatusMessages"))&lt;br /&gt;            {&lt;br /&gt;&lt;br /&gt;                messageItems = (List&amp;lt;string&amp;gt;)viewData["StatusMessages"];&lt;br /&gt;            }&lt;br /&gt;            else&lt;br /&gt;            {&lt;br /&gt;                messageItems = new List&amp;lt;string&amp;gt;(5);&lt;br /&gt;                viewData["StatusMessages"] = messageItems;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            messageItems.Add(message);&lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-6127100593377800795?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/6127100593377800795/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2010/12/status-message-handling-in-mvc.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/6127100593377800795'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/6127100593377800795'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2010/12/status-message-handling-in-mvc.html' title='Status Message Handling in MVC'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-6435989663712563054</id><published>2010-10-27T20:08:00.000-07:00</published><updated>2010-10-27T23:19:04.991-07:00</updated><title type='text'>Logging in and Authentication Providers in MVC</title><content type='html'>First let me state there is no login control in an MVC application. You CAN use one - since you can use ASPX pages and controls in an MVC application. However, if you want to use 'pure' MVC and no Web Forms controls then you should do it the way the Visual Studio MVC template does it. &lt;br /&gt;&lt;br /&gt;By default MVC creates a new web application that follows the following methods for logging a user on:&lt;br /&gt;The master page contains a user control which if Request.IsAuthenticated, displays a logoff link, otherwise a login link.&lt;br /&gt;&lt;br /&gt;The login view is rendered when the user clicks on the login link.&lt;br /&gt;Upon filling out the details and clicking to submit the login page, the following actions happen:&lt;br /&gt;&lt;br /&gt;1. We have a model containing a username, password, and 'remember me' being posted and passed to the LogOnMethod via this signature&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public ActionResult LogOn(LogOnModel model, string returnUrl)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;2. This model posts to the AccountController&lt;br /&gt;3. The LogOn method validates the model:  if (ModelState.IsValid)&lt;br /&gt;4. The LogOn method checks the user against the profile provider: MembershipService.ValidateUser(model.UserName, model.Password)&lt;br /&gt;5. The LogOn method then calls: FormsService.SignIn(model.UserName, model.RememberMe);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The same happens for 'Register'. If you do NOT want any user to be able to be registered, then REMOVE THE REGISTER METHOD or - add security to it such as a SystemAdministrators role:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;[Authorize( Roles="SystemAdministrators")]&lt;br /&gt;[HttpPost]&lt;br /&gt;public ActionResult Register(RegisterModel model)&lt;br /&gt;{}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-6435989663712563054?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/6435989663712563054/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2010/10/profiles-and-providers-in-mvc.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/6435989663712563054'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/6435989663712563054'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2010/10/profiles-and-providers-in-mvc.html' title='Logging in and Authentication Providers in MVC'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-5813907424534474120</id><published>2010-10-11T18:25:00.001-07:00</published><updated>2010-10-11T19:04:09.676-07:00</updated><title type='text'>Code Camp Slides and Code</title><content type='html'>See the attached zip. Email me if you have any questions.&lt;br /&gt;Some of the 'fixes' are already in place from the live demo so not all of the code is still 'broke', so please investigate. Please read the directions at the bottom of the first slide as to which virtual directories should go where.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.gecko-software.com/Security-ASP.Net and MVC Demos.zip"&gt;Slides and Code (about 10mb) &lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-5813907424534474120?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/5813907424534474120/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2010/10/code-camp-slides-and-code.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/5813907424534474120'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/5813907424534474120'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2010/10/code-camp-slides-and-code.html' title='Code Camp Slides and Code'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-4666756930765076312</id><published>2010-10-11T09:22:00.000-07:00</published><updated>2010-10-11T09:25:06.329-07:00</updated><title type='text'>Code Camp 2010 - Hack Proofing your ASP.Net and MVC Web Applications</title><content type='html'>The event was a great day indeed at Devry. If you saw my presentation there.. please rate it at:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://codecamp.phillydotnet.org/2010-2/Lists/Evaluation%202/NewForm.aspx?source=/2010-2/SitePages/Thank%20You.aspx"&gt;Evaluations&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The evaluations are an important part of code camp. I hope you liked my presentation : )&lt;br /&gt;&lt;br /&gt;I will be posting all of the code and slides very shortly, just converting my foot notes to make more sense to others.&lt;br /&gt;&lt;br /&gt;Thanks!!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-4666756930765076312?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/4666756930765076312/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2010/10/code-camp-2010-hack-proofing-your.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/4666756930765076312'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/4666756930765076312'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2010/10/code-camp-2010-hack-proofing-your.html' title='Code Camp 2010 - Hack Proofing your ASP.Net and MVC Web Applications'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-5024828142249457760</id><published>2010-09-05T22:10:00.001-07:00</published><updated>2010-09-05T22:20:32.178-07:00</updated><title type='text'>ASP.NET/MVC/Entity Framework Error "Unable to load type....required for deserialization."</title><content type='html'>Issue: Once you compile a change in your application and run it again you can receive this error, usually upon a post to a page:&lt;br /&gt;&lt;br /&gt;Unable to load type System.Data.Entity.DynamicProxies.ClassName_A1398804A2AD2636A55B88C252D769E3468A12F2C5A773B1895C58D312108335 required for deserialization.&lt;br /&gt;&lt;br /&gt;Or:&lt;br /&gt;&lt;br /&gt;Unable to find assembly 'EntityFrameworkDynamicProxies-XXXX, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;What is happening here is that you are likely using POCO objects for the Entity Framework. These objects have proxy classes automatically generated for them behind the scenes. Upon a first visit to the application they are compiled, however if they are used in a post (for instance when posting data to an MVC Action) and that type is used in serialization then they have not yet been created.&lt;br /&gt;&lt;br /&gt;Your code may look like:&lt;br /&gt;[HttpPost]&lt;br /&gt;public ActionResult Edit(Job job, [Deserialize] List&lt;SomeClass&gt; someClasses)&lt;br /&gt;&lt;br /&gt;When you post to this, the framework will NOT create the proxies automatically. You must access the page via a normal manner (ie via HttpGet) and the proxies will all be created. If you must have this feature, then you may possibly be able to do something in Application_Start to reference an Entity class and thus all of them should be auto generated.&lt;br /&gt;&lt;br /&gt;In short - this fix is simply refresh the page. If posting to the page requires deserializing POCO objects from the page, then you will need to implement some mechanism to use the POCO Entities before the method is attempted, possibly in Application_Start.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-5024828142249457760?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/5024828142249457760/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2010/09/aspnetmvcentity-framework-error-unable.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/5024828142249457760'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/5024828142249457760'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2010/09/aspnetmvcentity-framework-error-unable.html' title='ASP.NET/MVC/Entity Framework Error &quot;Unable to load type....required for deserialization.&quot;'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-8001037865899319843</id><published>2010-05-24T09:22:00.000-07:00</published><updated>2010-05-24T09:39:19.234-07:00</updated><title type='text'>Changing log4net configuration parameters at runtime</title><content type='html'>Since most of log4net configuration is specified in your application's configuration a question does come up on occasion how may I change this at runtime, depending on the user, etc. &lt;br /&gt;Changing parameters at runtime for log4net is fairly simple - see the following code sample:&lt;br /&gt;&lt;pre class="brush: c#;"&gt;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// SMTP Appender custom configuration&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        public void InitializeLog4Net()&lt;br /&gt;        {&lt;br /&gt;            //We need access to the repositories for the loggers&lt;br /&gt;            ILoggerRepository repository = LogManager.GetRepository();&lt;br /&gt;            &lt;br /&gt;            //Get only SmtpAppenders&lt;br /&gt;            //can do it as such:&lt;br /&gt;            //var appenders = repository.GetAppenders().Where(o =&gt; o is SmtpAppender).Select(o =&gt; (SmtpAppender)o);&lt;br /&gt;&lt;br /&gt;            //Or a bit more readable&lt;br /&gt;            var appenders= from o in repository.GetAppenders()&lt;br /&gt;                      where o is SmtpAppender&lt;br /&gt;                      select (SmtpAppender)o;&lt;br /&gt;&lt;br /&gt;            foreach (SmtpAppender smtpAppender in appenders)&lt;br /&gt;            {&lt;br /&gt;                smtpAppender.To = "adam_tuliper@nowhere";&lt;br /&gt;                //Make this config change active immediately&lt;br /&gt;                smtpAppender.ActivateOptions();&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-8001037865899319843?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/8001037865899319843/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2010/05/changing-log4net-configuration.html#comment-form' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/8001037865899319843'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/8001037865899319843'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2010/05/changing-log4net-configuration.html' title='Changing log4net configuration parameters at runtime'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-3837989982401446693</id><published>2010-05-22T09:12:00.000-07:00</published><updated>2010-05-22T09:47:58.457-07:00</updated><title type='text'>Setting up RESTful services in Windows XP</title><content type='html'>If you chance you haven't upgraded or your company still requires XP usage and skipped Vista and is waiting on Windows 7 - you may need to get WCF and RESTful services working together. **Really this applies to any dynamic routing required - it could be pure WCF as well and anything that uses a RouteTable class such as&lt;br /&gt;&lt;br /&gt;RouteTable.Routes.Add(new ServiceRoute("YourFriendlyURLPortion", new WebServiceHostFactory(), typeof(CustomerSearch)));&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Once you have your project you will need to do the following:&lt;br /&gt;1. Configure IIS to use .net 4 - go into the properties of your virtual directory and then the ASP.Net tab. &lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_iMjR6GifR0g/S_gKNMVPz6I/AAAAAAAAAKY/bjYuZzM2npA/s1600/net+4.gif"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 394px;" src="http://2.bp.blogspot.com/_iMjR6GifR0g/S_gKNMVPz6I/AAAAAAAAAKY/bjYuZzM2npA/s400/net+4.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5474136568833757090" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;2. Setup a global mapping so ALL files get routed to ASP.Net&lt;br /&gt;Right Click on the virtual directory, go to properties, and then to the Virtual Directory tab. Then click on the Configuration button. You will need to map ALL files to your .net 4 isapi dll. Since IIS 5.1 does not have integrated pipeline for .net, ASP.Net sits on top of IIS via an isapi extension.&lt;br /&gt;Select "All Verbs" (or whatever ones you require if you are limiting to say.. only GET/PUT although that violates RESTful design if you also need delete and update operations which require DELETE and PUT verbs)&lt;br /&gt;&lt;br /&gt;I have my isapi dll set to:&lt;br /&gt;C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll&lt;br /&gt;In the following image you will see the setup. You must specify .* for the extension (not *.*) otherwise your "OK" button will never enable. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_iMjR6GifR0g/S_gJz2huuhI/AAAAAAAAAKQ/B8135h_Jjsk/s1600/global.gif"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 233px;" src="http://4.bp.blogspot.com/_iMjR6GifR0g/S_gJz2huuhI/AAAAAAAAAKQ/B8135h_Jjsk/s400/global.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5474136133483805202" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Reset IIS then attempt to go to your service url/help and see if you get the nice new RESTFUL service web page. &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_iMjR6GifR0g/S_gH3jz2QSI/AAAAAAAAAJw/uZQvfJFB70I/s1600/helpurl.JPG"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 205px;" src="http://3.bp.blogspot.com/_iMjR6GifR0g/S_gH3jz2QSI/AAAAAAAAAJw/uZQvfJFB70I/s400/helpurl.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5474133998155743522" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-3837989982401446693?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/3837989982401446693/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2010/05/setting-up-restful-services-in-windows.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/3837989982401446693'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/3837989982401446693'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2010/05/setting-up-restful-services-in-windows.html' title='Setting up RESTful services in Windows XP'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_iMjR6GifR0g/S_gKNMVPz6I/AAAAAAAAAKY/bjYuZzM2npA/s72-c/net+4.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-4665426063734729486</id><published>2010-05-22T06:48:00.001-07:00</published><updated>2010-06-03T08:27:43.927-07:00</updated><title type='text'>Why don't I see my JSON RESTful response in the browser?</title><content type='html'>When testing RESTful services, one common option is to use JSON (Javascript Object Notation) which can significantly decrease the size of the service response. As we&lt;br /&gt;A quick note on unexpected behavior (at first) when request the SAME url through different means.&lt;br /&gt;If I request to get customer 1:&lt;br /&gt;http://localhost/CustomerSearch/1&lt;br /&gt;GET /CustomerSearch/1 HTTP/1.1&lt;br /&gt;&lt;br /&gt;&lt;pre id=pretty&gt;&lt;br /&gt;Host: localhost.:1046&lt;br /&gt;User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.9) Gecko/20100315 Firefox/3.5.9 (.NET CLR 3.5.30729)&lt;br /&gt;Accept: application/json, text/javascript, */*&lt;br /&gt;Accept-Language: en-us,en;q=0.5&lt;br /&gt;Accept-Encoding: gzip,deflate&lt;br /&gt;Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7&lt;br /&gt;Keep-Alive: 300&lt;br /&gt;Connection: keep-alive&lt;br /&gt;Referer: http://localhost:2592/&lt;br /&gt;Origin: http://localhost:2592&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;My response is indeed JSON&lt;br /&gt;&lt;br /&gt;&lt;pre id=pretty&gt;&lt;br /&gt;HTTP/1.1 200 OK&lt;br /&gt;Server: ASP.NET Development Server/10.0.0.0&lt;br /&gt;Date: Sat, 22 May 2010 06:12:06 GMT&lt;br /&gt;X-AspNet-Version: 4.0.30319&lt;br /&gt;Content-Length: 153&lt;br /&gt;Cache-Control: private&lt;br /&gt;Content-Type: application/json; charset=utf-8&lt;br /&gt;Connection: Close&lt;br /&gt;&lt;br /&gt;{"DateOfHire":"\/Date(1072933200000-0500)\/","EmployeeId":"dd98655a-8706-4b2f-b648-874079015295","FirstName":"Jane","LastName":"Doe","SSN":"123-45-6789"}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If my request url stays the same, but I change my Accept: header, I no longer get JSON back but instead xml:&lt;br /&gt;&lt;pre id=pretty&gt;&lt;br /&gt;&lt;br /&gt;GET /CustomerSearch/1 HTTP/1.1&lt;br /&gt;Host: localhost.:1046&lt;br /&gt;User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.9) Gecko/20100315 Firefox/3.5.9 (.NET CLR 3.5.30729)&lt;br /&gt;Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&lt;br /&gt;Accept-Language: en-us,en;q=0.5&lt;br /&gt;Accept-Encoding: gzip,deflate&lt;br /&gt;Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7&lt;br /&gt;Keep-Alive: 300&lt;br /&gt;Connection: keep-alive&lt;br /&gt;Cookie: ASP.NET_SessionId=yypfhriihodesh553qpmaam4&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre id=pretty&gt;&lt;br /&gt;HTTP/1.1 200 OK&lt;br /&gt;Server: ASP.NET Development Server/10.0.0.0&lt;br /&gt;Date: Sat, 22 May 2010 06:12:06 GMT&lt;br /&gt;X-AspNet-Version: 4.0.30319&lt;br /&gt;Content-Length: 153&lt;br /&gt;Cache-Control: private&lt;br /&gt;Content-Type: application/json; charset=utf-8&lt;br /&gt;Connection: Close&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;My response is indeed JSON&lt;br /&gt;{"DateOfHire":"\/Date(1072933200000-0500)\/","EmployeeId":"dd98655a-8706-4b2f-b648-874079015295","FirstName":"Jane","LastName":"Doe","SSN":"123-45-6789"}&lt;br /&gt;&lt;br /&gt;So what is going on here?&lt;br /&gt;In one case Im request via the browser and I get xml back. In the other case I request via jQuery:&lt;br /&gt;$.getJSON&lt;br /&gt;&lt;br /&gt;which happily sends over&lt;br /&gt;&lt;br /&gt;Accept: application/json, text/javascript, */*&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-4665426063734729486?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/4665426063734729486/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2010/05/why-dont-i-see-my-json-restful-response.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/4665426063734729486'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/4665426063734729486'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2010/05/why-dont-i-see-my-json-restful-response.html' title='Why don&apos;t I see my JSON RESTful response in the browser?'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-1615792461333847358</id><published>2010-05-15T10:19:00.001-07:00</published><updated>2010-05-22T07:35:21.388-07:00</updated><title type='text'>Eliminating delegates in threading</title><content type='html'>Just a quick note on threading. One way to start a new thread with parameters was the following:&lt;br /&gt;&lt;pre class="brush: c#;"&gt;&lt;br /&gt;Thread processingThread = new Thread(new ThreadStart(delegate { someClass.SomeMethod(); }));&lt;br /&gt;&lt;br /&gt;processingThread.Start();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;One can do the same thing with a lambda expression which in my opinion is a bit cleaner. Why? I don't know  - personal preference - I seem to remember lambda syntax more often : )&lt;br /&gt;&lt;pre class="brush: c#;"&gt;&lt;br /&gt;               Thread workerThread = new Thread(&lt;br /&gt;                ()=&gt; someClass.SomeMethod()(employeeId)&lt;br /&gt;                                       );&lt;br /&gt;                workerThread.Start();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Or doing this inline with the start right away:&lt;br /&gt;&lt;pre class="brush: c#;"&gt;&lt;br /&gt;            (new Thread(() =&gt;&lt;br /&gt;            {&lt;br /&gt;                someClass.SomeMethod()(employeeId)&lt;br /&gt;&lt;br /&gt;            }&lt;br /&gt;            )).Start();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;That's all there is to it. Remember in Win32 API when creating threads, and security descriptors, etc? Its so nice and easy in the managed world.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-1615792461333847358?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/1615792461333847358/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2010/05/eliminating-delegates-in-threading.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/1615792461333847358'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/1615792461333847358'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2010/05/eliminating-delegates-in-threading.html' title='Eliminating delegates in threading'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-2539590868644844306</id><published>2010-04-26T18:28:00.000-07:00</published><updated>2010-05-14T07:32:27.427-07:00</updated><title type='text'>Quick way to cross thread invoke</title><content type='html'>In windows forms, everything is still single threaded. If you've ever tried to use multiple threads and various controls (form timers for example - the non thread safe kind) you will realize properties start disappearing because they all use TLS (Thread Local Storage) which of course - is thread specific. You must set properties and call events on the thread that created the control. You can cross post messages into another app's message queue (which interestingly enough was the source of the 'shatter' attack some years ago allowing attacking applications to take control of other apps by malformed wm_timer message) without a problem but that's a bit more rare now in managed code than it was in native code days.&lt;br /&gt;&lt;br /&gt;If you need to set a property or call a method on a control from a worker thread in you needed to create a delegate. The syntax was sometimes a pain. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;To easily call this without a 'outside' (ie in class declarations as was typical) setup of the delegates&lt;br /&gt;simply call it directly by creating a delegate inline using an anonymous method or lambda expression. Either one works - it's your preference on syntax:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c#;"&gt;&lt;br /&gt;yourControl.Invoke((MethodInvoker)delegate() {  yourControl.Value=0; });&lt;br /&gt;&lt;br /&gt;//Or&lt;br /&gt;&lt;br /&gt;yourControl.Invoke((Action) ( () =&gt; yourControl.Value=0));&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;What does this save?&lt;br /&gt;1. You don't have to create a separate method.&lt;br /&gt;2. You don't have to declare a separate delegate.&lt;br /&gt;&lt;br /&gt;So let's say you wanted to increase the count on a progess bar from a worker thread, you could simply do (off the top of my head.. I believe the invoke needs to be called on the container StatusStrip control) :&lt;br /&gt;&lt;pre class="brush: c#;"&gt;&lt;br /&gt;statusBar.Invoke((MethodInvoker)delegate() {  progressBar.Increment(1); });&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Hope this helps - I use it quite frequently. Of course, please don't sprinkle the same line all over your code, wrap it in a method call in case you need to change it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-2539590868644844306?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/2539590868644844306/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2010/04/quick-way-to-cross-thread-invoke.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/2539590868644844306'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/2539590868644844306'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2010/04/quick-way-to-cross-thread-invoke.html' title='Quick way to cross thread invoke'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-8206521905947608435</id><published>2010-04-26T18:13:00.001-07:00</published><updated>2010-04-30T20:55:44.837-07:00</updated><title type='text'>Animating the Visibility Property in Silverlight</title><content type='html'>&lt;span style="font-weight:bold;"&gt;Problem&lt;/span&gt;&lt;br /&gt;If you define an animation in silverlight and try to animate the Visibility property (IE to hide or show an element on animation with other effects) it does not work. You will fine when you set the Visibility property it stays the entire animation and doesn't change.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Cause&lt;/span&gt;&lt;br /&gt;If you are animating your properties, chances are you are using a double animation, which handles, you guessed it - double values. Visibility is not a double value. Its a specific enumeration value that requires in XAML the text name of the enum value.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Resolutions&lt;/span&gt;&lt;br /&gt;In your animation simply add &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&lt;br /&gt;&amp;lt;Storyboard x:Name=&amp;quot;closeControl&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;ObjectAnimationUsingKeyFrames BeginTime=&amp;quot;00:00:00&amp;quot; Storyboard.TargetName=&amp;quot;controlToAnimate&amp;quot; Storyboard.TargetProperty=&amp;quot;(UIElement.Visibility)&amp;quot;&amp;gt;&lt;br /&gt;    &amp;lt;DiscreteObjectKeyFrame KeyTime=&amp;quot;00:00:00&amp;quot;&amp;gt;&lt;br /&gt;        &amp;lt;DiscreteObjectKeyFrame.Value&amp;gt;&lt;br /&gt;            &amp;lt;Visibility&amp;gt;Visible&amp;lt;/Visibility&amp;gt;&lt;br /&gt;        &amp;lt;/DiscreteObjectKeyFrame.Value&amp;gt;&lt;br /&gt;    &amp;lt;/DiscreteObjectKeyFrame&amp;gt;&lt;br /&gt;    &amp;lt;DiscreteObjectKeyFrame KeyTime=&amp;quot;00:00:02&amp;quot;&amp;gt;&lt;br /&gt;        &amp;lt;DiscreteObjectKeyFrame.Value&amp;gt;&lt;br /&gt;            &amp;lt;Visibility&amp;gt;Collapsed&amp;lt;/Visibility&amp;gt;&lt;br /&gt;        &amp;lt;/DiscreteObjectKeyFrame.Value&amp;gt;&lt;br /&gt;    &amp;lt;/DiscreteObjectKeyFrame&amp;gt;&lt;br /&gt;&amp;lt;/ObjectAnimationUsingKeyFrames&amp;gt;&lt;br /&gt;&amp;lt;DoubleAnimationUsingKeyFrames&amp;gt;&lt;br /&gt;...&lt;br /&gt;&amp;lt;/DoubleAnimationUsingKeyFrames&amp;gt;&lt;br /&gt;&amp;lt;/Storyboard&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I included a placeholder there for a double animation to show this XAML simply goes on top of your existing DoubleAnimation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-8206521905947608435?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/8206521905947608435/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2010/04/animating-visibility-property-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/8206521905947608435'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/8206521905947608435'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2010/04/animating-visibility-property-in.html' title='Animating the Visibility Property in Silverlight'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-8344847157906040105</id><published>2010-04-23T11:57:00.000-07:00</published><updated>2010-04-23T12:07:55.907-07:00</updated><title type='text'>The Dangers of Internet Explorer Mime-Type Sniffing</title><content type='html'>Internet explorer 4+ has a unique feature called Mime-Type sniffing. It sometimes doesn't pay attention to the extension of your file, but instead wants to determine what kind of file it is for itself. This can be easily exploited via various sites that allow images to be uploaded and provide links to those images.&lt;br /&gt;&lt;br /&gt;If the first few bytes of an image file are changed - say.. after bytes 12, to &lt;br /&gt;&amp;lt;script&amp;gt;alert('bip');&amp;lt;/script&amp;gt;&lt;br /&gt;Internet Explorer now thinks this is content type text/html and not image/gif.&lt;br /&gt;So if you were to click on a link to this image you would run whatever script was there in your browser.&lt;br /&gt;&lt;br /&gt;Thanksfully, mime type detection for images has been disabled in IE8.&lt;br /&gt;You can also turn off all Mime sniffing by doing:&lt;br /&gt;&lt;strong&gt;Response.Headers.Add("X-Content-Type-Options", "nosniff");&lt;/strong&gt;to get: X-Content-Type-Options: nosniff &lt;br /&gt;to the client browser.&lt;br /&gt;&lt;br /&gt;The lesson: never ever ever trust image uploads. You can actually check the mime type yourself upon file upload by using the following:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class=pretty&gt;&lt;br /&gt;//goes in the beginning of your class&lt;br /&gt;        [DllImport("urlmon.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = false)]&lt;br /&gt;        static extern int FindMimeFromData(IntPtr pBC,&lt;br /&gt;              [MarshalAs(UnmanagedType.LPWStr)] string pwzUrl,&lt;br /&gt;             [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.I1, SizeParamIndex = 3)] &lt;br /&gt;        byte[] pBuffer,&lt;br /&gt;              int cbSize,&lt;br /&gt;                 [MarshalAs(UnmanagedType.LPWStr)]  string pwzMimeProposed,&lt;br /&gt;              int dwMimeFlags,&lt;br /&gt;              out IntPtr ppwzMimeOut,&lt;br /&gt;              int dwReserved);&lt;br /&gt;&lt;br /&gt;//calling code would be like:&lt;br /&gt;            string mimeType = GetMimeFromFile(txtFileName.Text);&lt;br /&gt;            MessageBox.Show(mimeType);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;//method to check would be:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// Ensures that file exists and retrieves the content type &lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        /// &lt;param name="file"&gt;&lt;/param&gt;&lt;br /&gt;        /// &lt;returns&gt;Returns for instance "images/jpeg" &lt;/returns&gt;&lt;br /&gt;        public static string GetMimeFromFile(string file)&lt;br /&gt;        {&lt;br /&gt;            IntPtr mimeout;&lt;br /&gt;            if (!System.IO.File.Exists(file))&lt;br /&gt;                throw new FileNotFoundException(file + " not found");&lt;br /&gt;&lt;br /&gt;            int MaxContent = (int)new FileInfo(file).Length;&lt;br /&gt;            if (MaxContent &gt; 4096) MaxContent = 4096;&lt;br /&gt;            FileStream fs = File.OpenRead(file);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;            byte[] buf = new byte[MaxContent];&lt;br /&gt;            fs.Read(buf, 0, MaxContent);&lt;br /&gt;            fs.Close();&lt;br /&gt;            int result = FindMimeFromData(IntPtr.Zero, file, buf, MaxContent, null, 0, out mimeout, 0);&lt;br /&gt;&lt;br /&gt;            if (result != 0)&lt;br /&gt;                throw Marshal.GetExceptionForHR(result);&lt;br /&gt;            string mime = Marshal.PtrToStringUni(mimeout);&lt;br /&gt;            Marshal.FreeCoTaskMem(mimeout);&lt;br /&gt;            return mime;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-8344847157906040105?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/8344847157906040105/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2010/04/dangers-of-internet-explorer-mime-type.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/8344847157906040105'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/8344847157906040105'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2010/04/dangers-of-internet-explorer-mime-type.html' title='The Dangers of Internet Explorer Mime-Type Sniffing'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-2888400734709732478</id><published>2010-04-20T20:46:00.001-07:00</published><updated>2010-04-30T20:56:57.429-07:00</updated><title type='text'>Transitioning from non-ssl to ssl and back again for login</title><content type='html'>&lt;strong&gt;Problem&lt;/strong&gt;&lt;br /&gt;You have a web site that needs to transition from non-ssl, to an ssl login page, back to non-ssl for the rest of the site navigation. This must use forms authentication&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Details&lt;/strong&gt;&lt;br /&gt;Forms authentication has a method FormsAuthentication.RedirectFromLoginPage()&lt;br /&gt;However the url is passed over the querystring as login.aspx?RedirectUrl=somepage.aspx&lt;br /&gt;This is all automatic and you cannot specify an absolute url here. Even if you make it an absolte url such as &lt;br /&gt;login.aspx?RedirectUrl=http://www.mysite.com/somepage.aspx  (of course this would need to be url encoded) this wont work.&lt;br /&gt;Also an oddity in my testing if you specify an absolute url for the login page, forms authentication - even with a valid login- redirects you right back to the login page.&lt;br /&gt;For example: If my web.config contains:&lt;br /&gt;&amp;lt;forms loginUrl="http://localhost/secure/Login.aspx"  &lt;br /&gt;Or SSL&lt;br /&gt;&amp;lt;forms loginUrl="https://localhost/secure/Login.aspx"  &lt;br /&gt;&lt;br /&gt;Both of these cause forms authentication to send out a redirect NOT to the RedirectUrl, but right back to the login page!&lt;br /&gt;&lt;br /&gt;If you are currently surfing a non-http site and need the login page to go SSL there doesn't seem to be an easy way to do this considering the problem above (at least on my laptop Im using for testing) . Even if you set the flag &amp;lt;forms requireSsl=true it just errors out if you are not using an ssl connection but it does not redirect to ssl.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;br /&gt;1. For your login url in forms authentication you can specify the full https:// url. OR you can use &lt;br /&gt;&amp;lt;forms loginUrl="~/secure/Login.aspx"  &lt;br /&gt;On your login.aspx page&lt;br /&gt;&lt;pre class="brush: c#"&gt;&lt;br /&gt;if (!Request.IsSecureConnection)&lt;br /&gt;{&lt;br /&gt;  Response.Redirect( --form your https url here or read from config);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;OR you can use &lt;br /&gt;&amp;lt;forms loginUrl="https://localhost/secure/Login.aspx"  &lt;br /&gt;and then in your login page, use a login control. Hook into the Logged_In method.&lt;br /&gt;&lt;pre class="brush: c#"&gt;&lt;br /&gt;&lt;br /&gt;        protected void Login1_LoggedIn(object sender, EventArgs e)&lt;br /&gt;        {&lt;br /&gt;            //see below for code on GetNonSslRedirectUrl&lt;br /&gt;            Response.Redirect(GetNonSslRedirectUrl(""));&lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If you are not using a login control, then simply do something like such:&lt;br /&gt;&lt;pre class="brush: c#"&gt;&lt;br /&gt;if (Authenticate(userName, password))&lt;br /&gt;{&lt;br /&gt;    string redirectUrl = GetNonSslRedirectUrl(userName);&lt;br /&gt;    FormsAuthentication.SetAuthCookie(userName, false);&lt;br /&gt;    Response.Redirect(redirectUrl);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;/// &lt;summary&gt;&lt;br /&gt;/// Returns an http url (not https) to redirecto to a non-secure page&lt;br /&gt;/// after being at a secure login page.&lt;br /&gt;/// &lt;/summary&gt;&lt;br /&gt;/// &lt;param name="userName"&gt;The username attempting the login.&lt;/param&gt;&lt;br /&gt;/// &lt;returns&gt;The http://... url&lt;/returns&gt;&lt;br /&gt;private string GetNonSslRedirectUrl(string userName)&lt;br /&gt;{&lt;br /&gt;    string redirectUrl = FormsAuthentication.GetRedirectUrl(userName, false);&lt;br /&gt;    //if its ssl, make non ssl.&lt;br /&gt;    if (redirectUrl.Contains("https://"))&lt;br /&gt;    {&lt;br /&gt;        redirectUrl = redirectUrl.Replace("https://", "http://");&lt;br /&gt;    }&lt;br /&gt;    //if it doesnt contain http:// then its a relative path. append http and the host to it.&lt;br /&gt;    if (!redirectUrl.Contains("http://"))&lt;br /&gt;    {&lt;br /&gt;        if (redirectUrl.StartsWith("/"))&lt;br /&gt;        {&lt;br /&gt;            redirectUrl = string.Format("http://{0}{1}", Request.Url.Host, redirectUrl);&lt;br /&gt;        }&lt;br /&gt;        else&lt;br /&gt;        {&lt;br /&gt;            //it needs a / in it.  url is just 'something.aspx' - not sure if this can happen, its a failsafe&lt;br /&gt;            redirectUrl = string.Format("http://{0}/{1}", Request.Url.Host, redirectUrl);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    return redirectUrl;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-2888400734709732478?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/2888400734709732478/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2010/04/transitioning-from-non-ssl-to-ssl-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/2888400734709732478'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/2888400734709732478'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2010/04/transitioning-from-non-ssl-to-ssl-and.html' title='Transitioning from non-ssl to ssl and back again for login'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-3123376184411532561</id><published>2010-04-17T09:18:00.000-07:00</published><updated>2010-04-30T20:58:05.169-07:00</updated><title type='text'>Determining a user's permissions on sql objects</title><content type='html'>I use a variant of this for auditing user permissions for security checks. My preference is a user should only have execute access to a stored procedure and thats it. This will find tables the user has select access on (to return all permissions simply remove the: where permission_name='select' and subentity_name =''  )&lt;br /&gt;&lt;br /&gt;This will work for users who receive permissions as part of role membership as well as direct permissions on an object.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: sql"&gt;&lt;br /&gt;--this WILL work for role based permissions as well.&lt;br /&gt;select b.name + '.' + a.name, permissions.permission_name from sys.tables a &lt;br /&gt;inner join sys.schemas b on a.schema_id=b.schema_id&lt;br /&gt;cross apply (select * From fn_my_permissions(b.name + '.' + a.name, 'object') where permission_name='select' and subentity_name ='') as permissions&lt;br /&gt;where a.type='u'&lt;br /&gt;&lt;br /&gt;--should only have execute&lt;br /&gt;select b.name + '.' + a.name, permissions.permission_name from sys.procedures  a &lt;br /&gt;inner join sys.schemas b on a.schema_id=b.schema_id&lt;br /&gt;cross apply (select * From fn_my_permissions(b.name + '.' + a.name, 'object') ) as permissions&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-3123376184411532561?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/3123376184411532561/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2010/04/determining-users-permissions-on-sql.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/3123376184411532561'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/3123376184411532561'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2010/04/determining-users-permissions-on-sql.html' title='Determining a user&apos;s permissions on sql objects'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-3377105137288180834</id><published>2010-04-06T06:46:00.000-07:00</published><updated>2010-04-30T20:59:27.081-07:00</updated><title type='text'>Hasing Passwords</title><content type='html'>I think some people aren't sure the best way to implement password hashing for storing in a database or config file. Its super fast and super easy.&lt;br /&gt;&lt;br /&gt;Simply open snippet compiler an essential tool at ( &lt;a href="http://www.sliver.com/dotnet/SnippetCompiler/"&gt;&lt;/a&gt; ) and add a reference to system.web&lt;br /&gt;then add:&lt;br /&gt;using System.Web.Security;&lt;br /&gt;&lt;br /&gt;and the code is simply:&lt;br /&gt;&lt;pre class="brush: c#"&gt;&lt;br /&gt;string hashedText = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile("test", "SHA1");&lt;br /&gt;Console.WriteLine(hashedText);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;if you want the full class to use in snippet compiler for copying and pasting it is simply&lt;br /&gt;&lt;pre class="brush: c#"&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Web.Security;&lt;br /&gt;public class HashPassword&lt;br /&gt;{&lt;br /&gt; public static void RunSnippet()&lt;br /&gt; {&lt;br /&gt;  string hashedText = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile("test", "SHA1");&lt;br /&gt;  Console.WriteLine(hashedText);&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; #region Helper methods&lt;br /&gt; &lt;br /&gt; public static void Main()&lt;br /&gt; {&lt;br /&gt;  try&lt;br /&gt;  {&lt;br /&gt;   RunSnippet();&lt;br /&gt;  }&lt;br /&gt;  catch (Exception e)&lt;br /&gt;  {&lt;br /&gt;   string error = string.Format("---\nThe following error occurred while executing the snippet:\n{0}\n---", e.ToString());&lt;br /&gt;   Console.WriteLine(error);&lt;br /&gt;  }&lt;br /&gt;  finally&lt;br /&gt;  {&lt;br /&gt;   Console.Write("Press any key to continue...");&lt;br /&gt;   Console.ReadKey();&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private static void WL(object text, params object[] args)&lt;br /&gt; {&lt;br /&gt;  Console.WriteLine(text.ToString(), args); &lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; private static void RL()&lt;br /&gt; {&lt;br /&gt;  Console.ReadLine(); &lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; private static void Break() &lt;br /&gt; {&lt;br /&gt;  System.Diagnostics.Debugger.Break();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; #endregion&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-3377105137288180834?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/3377105137288180834/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2010/04/hasing-passwords.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/3377105137288180834'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/3377105137288180834'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2010/04/hasing-passwords.html' title='Hasing Passwords'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-8864528270151657773</id><published>2010-03-28T19:06:00.000-07:00</published><updated>2010-04-30T21:00:16.135-07:00</updated><title type='text'>Using LINQ to query dataset for Distinct</title><content type='html'>I just wanted to query (quickly) a dataset to get a distinct pair of values.&lt;br /&gt;Heres a quick way of doing it&lt;br /&gt;&lt;pre class="brush: c#"&gt;&lt;br /&gt;var distinctValues = (from row in dataSet.Tables[0].AsEnumerable()&lt;br /&gt;           select new&lt;br /&gt;                      {&lt;br /&gt;                          SomeColumn1 = row["SomeColumn1"],&lt;br /&gt;                          SomeColumn2 = row["SomeColumn2"]&lt;br /&gt;                      }).Distinct().OrderBy(o=&gt;o.SomeSolumn1).ToArray();&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-8864528270151657773?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/8864528270151657773/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2010/03/using-linq-to-query-dataset-for.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/8864528270151657773'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/8864528270151657773'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2010/03/using-linq-to-query-dataset-for.html' title='Using LINQ to query dataset for Distinct'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-3121118494831665006</id><published>2009-12-27T19:08:00.000-08:00</published><updated>2009-12-27T19:14:57.771-08:00</updated><title type='text'>Quick way to query /script foreign key constraints</title><content type='html'>I needed to constantly query foreign key constraints as I was adding many new ones to a database for testing and removing:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;select name, object_name(parent_obj) from sysobjects where xtype='f'&lt;br /&gt;or if you want to use sys.objects instead:&lt;br /&gt;&lt;br /&gt;select name, OBJECT_NAME(parent_object_id) from sys.objects where type='f'&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;F = foreign key constraint&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;using this you can create a script to drop constraints:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;SELECT 'ALTER TABLE [dbo].[' +OBJECT_NAME(parent_object_id) +'] DROP CONSTRAINT [' +   OBJECT_NAME(OBJECT_ID) + ']'&lt;br /&gt;FROM sys.objects&lt;br /&gt;WHERE type='f'&lt;br /&gt;&lt;br /&gt;or I can add them. In this case I want to add a field called CompanyId to every table, and add a constraint to every table to reference this field.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;SELECT &lt;br /&gt;'ALTER TABLE [dbo].[' +name +'] add [CompanyId] [int] NOT NULL CONSTRAINT [DF_' + name + '_CompanyId]  DEFAULT ((1))',&lt;br /&gt;'ALTER TABLE [dbo].[' +name +'] WITH CHECK ADD CONSTRAINT [FK_' +   name + '_Company] FOREIGN KEY([CompanyId]) REFERENCES [dbo].[Company] ([CompanyId])'&lt;br /&gt;FROM sysobjects where type='u'&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-3121118494831665006?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/3121118494831665006/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2009/12/quick-way-to-query-script-foreign-key.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/3121118494831665006'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/3121118494831665006'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2009/12/quick-way-to-query-script-foreign-key.html' title='Quick way to query /script foreign key constraints'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-7667392277704226727</id><published>2009-12-20T21:26:00.000-08:00</published><updated>2010-04-17T09:22:31.755-07:00</updated><title type='text'>Caution with using asp.net session timeout and FormsAuthentication timeout together</title><content type='html'>Problem: You've set your session timeout to 20 minutes and forms authentication timeout to 20 minutes. However you notice sometimes your session is not valid and yet people are still logged on. how can this be you ask!?!?!&lt;br /&gt;&lt;br /&gt;So we have our session timeout as:&lt;br /&gt;&lt;pre id='pretty'&gt;&lt;br /&gt;&amp;lt;sessionState timeout="1000"&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;and the forms authentication timeout as:&lt;br /&gt;&lt;pre id='pretty'&gt;&lt;br /&gt;&amp;lt;forms timeout="1000" loginUrl="Login.aspx" name=".ASPXFORMSAUTH"&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Unfortunately session timeouts and forms authentication timeouts work completely different. Session timeouts are just that - the amount of time from the last request is when it will timeout. IE upon every request.. the 'timer' is reset to 20 minutes.&lt;br /&gt;&lt;br /&gt;In forms authentication - it is not reset upon every request. For 'performance enhancement' reasons so new cookies don't have to get created/encrypted on every single request, this value only gets update when approximately half of the time remains. IE if the timeout is 20 minutes, for the first 10 minutes of requests.. the timer still 'ticks away' on the ticket even if you request every second. It isn't until after 10 minutes have passed AND you request a page again that the ticket is updated. Secondly.. IIS resets do not reset forms authentication tickets, yet they reset sessions.&lt;br /&gt;&lt;br /&gt;So here is a scenario that 'breaks' this:&lt;br /&gt;Request a page at 1:00 PM.&lt;br /&gt;IIS Resets at 1:05 - the session is now invalid, however the forms authentication ticket is still VALID.&lt;br /&gt;&lt;br /&gt;The user requests a page and their session is gone, and all sorts of errors start occuring.&lt;br /&gt;&lt;br /&gt;How to prevent this:&lt;br /&gt;In global.asax.cs define a method that gets called at the beginning of every request. This method will check to make sure that we have a session if the ticket is valid, otherwise it logs the user out.&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettycode"&gt;&lt;br /&gt;        protected void Application_PreRequestHandlerExecute(object sender, EventArgs e)&lt;br /&gt;        {&lt;br /&gt;            //Only access session state if it is available&lt;br /&gt;            if (Context.Handler is IRequiresSessionState || Context.Handler is IReadOnlySessionState)&lt;br /&gt;            {&lt;br /&gt;                //If we are authenticated AND we dont have a session here.. redirect to login page.&lt;br /&gt;                HttpCookie authenticationCookie = Request.Cookies[FormsAuthentication.FormsCookieName];&lt;br /&gt;                if (authenticationCookie != null)&lt;br /&gt;                {&lt;br /&gt;                    FormsAuthenticationTicket authenticationTicket = FormsAuthentication.Decrypt(authenticationCookie.Value);&lt;br /&gt;                    if (!authenticationTicket.Expired)&lt;br /&gt;                    {&lt;br /&gt;//of course.. replace ANYKNOWNVALUEHERETOCHECK with "UserId" or something you set on the login that you can check here to see if its empty.&lt;br /&gt;                        if (Session[ANYKNOWNVALUEHERETOCHECK] == null)&lt;br /&gt;                        {&lt;br /&gt;                            //This means for some reason the session expired before the authentication ticket. Force a login.&lt;br /&gt;                            FormsAuthentication.SignOut();&lt;br /&gt;                            Response.Redirect(FormsAuthentication.LoginUrl, true);&lt;br /&gt;                            return;&lt;br /&gt;                        }&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-7667392277704226727?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/7667392277704226727/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2009/12/caution-with-using-sessiontimeout-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/7667392277704226727'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/7667392277704226727'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2009/12/caution-with-using-sessiontimeout-and.html' title='Caution with using asp.net session timeout and FormsAuthentication timeout together'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-621339912038779242</id><published>2009-12-18T23:29:00.000-08:00</published><updated>2009-12-18T23:40:48.283-08:00</updated><title type='text'>Regular Expression to fix exception handling</title><content type='html'>I was doing a code review and saw a common mistake throughout the code:&lt;br /&gt;&lt;pre class="prettycode"&gt;&lt;br /&gt;try&lt;br /&gt;{&lt;br /&gt;}&lt;br /&gt;catch(Exception ex)&lt;br /&gt;{&lt;br /&gt;   throw ex;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;this is incorrect. When you rethrow an exception like this, you reset the call stack and hose the good error information.&lt;br /&gt;&lt;br /&gt;The correct method is:&lt;br /&gt;&lt;pre class="prettycode"&gt;&lt;br /&gt;try&lt;br /&gt;{&lt;br /&gt;}&lt;br /&gt;catch(Exception ex)&lt;br /&gt;{&lt;br /&gt;   throw;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I came up with a quick regular expression you can use in visual studio to fix these. Press control-shift-f and check the box "use " where it says "regular expressions"&lt;br /&gt;&lt;br /&gt;In the "Find What" section enter in:&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettycode"&gt;&lt;br /&gt;{catch[:Wh]*\{[:Wh]*throw}{ ex}{;[:Wh]*\}}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In the "Replace with" enter:&lt;br /&gt;\1\3&lt;br /&gt;&lt;br /&gt;What does this do? In visual studio regular expressions the groupings are done by {} so the first place I have {} is \1, the second place is \2, etc&lt;br /&gt;&lt;br /&gt;so this expression: {catch[:Wh]*\{[:Wh]*throw}{ ex}{;[:Wh]*\}}&lt;br /&gt;breaks down to:&lt;br /&gt;{catch[:Wh]*\{[:Wh]*throw}   =\1&lt;br /&gt;{ ex}                        =\2&lt;br /&gt;{;[:Wh]*\}}                  =\3&lt;br /&gt;so by replacing with \1\3 I simply exclude the " ex"&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Click "replace" or "replace all" - by clicking replace you can preview one at a time.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_iMjR6GifR0g/SyyCtn3X65I/AAAAAAAAAHw/6cG-I-9H1xI/s1600-h/regex.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 268px; height: 400px;" src="http://4.bp.blogspot.com/_iMjR6GifR0g/SyyCtn3X65I/AAAAAAAAAHw/6cG-I-9H1xI/s400/regex.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5416848172126825362" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-621339912038779242?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/621339912038779242/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2009/12/regular-expression-to-fix-exception.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/621339912038779242'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/621339912038779242'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2009/12/regular-expression-to-fix-exception.html' title='Regular Expression to fix exception handling'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_iMjR6GifR0g/SyyCtn3X65I/AAAAAAAAAHw/6cG-I-9H1xI/s72-c/regex.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-6717526028578166593</id><published>2009-12-17T21:29:00.000-08:00</published><updated>2009-12-20T20:43:24.820-08:00</updated><title type='text'>Adding permissions to add items to the gac for other user accounts</title><content type='html'>Trying to have a user add an assembly to the gac you receive:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Failure adding assembly to the cache: Access denied. You might not have administrative credentials to perform this task. &lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;or you may receive this error:&lt;br /&gt;&lt;strong&gt;Failed to execute the request because the ASP.NET process identity does not have read permissions to the global assembly cache. Error: 0x80070005 Access is denied.  &lt;/strong&gt;&lt;br /&gt;(This error message sometimes _lies_ btw...if aspnet (xp) or network service (above windows xp) doesn't have permissions to your app folder you can receive this message.)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In our case the account we used to run our cruise control build process (ccnet) that then called off to nant scripts which in turn added assemblies to the gac was failing.&lt;br /&gt;One solution is to add your user to the administrators group. You may not want to do this though. If we look at the permissions on the folder (you must use a command line utility or change the shell options.. we'll stick with command line option cacls.exe here)&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettycode"&gt;&lt;br /&gt;&lt;br /&gt;C:\&gt;cacls c:\windows\assembly&lt;br /&gt;c:\windows\assembly BUILTIN\Users:R&lt;br /&gt;                    BUILTIN\Users:(OI)(CI)(IO)(special access:)&lt;br /&gt;                                              GENERIC_READ&lt;br /&gt;                                              GENERIC_EXECUTE&lt;br /&gt;&lt;br /&gt;                    BUILTIN\Power Users:C&lt;br /&gt;                    BUILTIN\Power Users:(OI)(CI)(IO)C&lt;br /&gt;                    BUILTIN\Administrators:F&lt;br /&gt;                    BUILTIN\Administrators:(OI)(CI)(IO)F&lt;br /&gt;                    NT AUTHORITY\SYSTEM:F&lt;br /&gt;                    NT AUTHORITY\SYSTEM:(OI)(CI)(IO)F&lt;br /&gt;                    MyLocalMachine\Administrator:F&lt;br /&gt;                    CREATOR OWNER:(OI)(CI)(IO)F&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You can see Administrators and System have Full Control (F).&lt;br /&gt;Users have read, so web applications have no problem accessing the gac.&lt;br /&gt;Running a web app therefore can access the gac (read only) because of the&lt;br /&gt;                    BUILTIN\Users:(OI)(CI)(IO)(special access:)&lt;br /&gt;                                              GENERIC_READ&lt;br /&gt;                                              GENERIC_EXECUTE&lt;br /&gt;&lt;br /&gt;To add the user to the ACL for the gac run&lt;br /&gt;(you can use %WINDIR% in place of c:\windows so you can use %WINDIR%\assembly)&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettycode"&gt;&lt;br /&gt;&lt;br /&gt;CACLS c:\windows\assembly /e /t /p user@domain:F&lt;br /&gt;&lt;br /&gt;or&lt;br /&gt;&lt;br /&gt;CACLS c:\windows\assembly /e /t /p username:F&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This is not always enough though depending on your inheritance permissions. since the gac install is a two phase install process and the temp and tmp folders may be used you may also at times need the following commands, but first try without.&lt;br /&gt;Also note where I have "username" that of course means replace with the username to add permissions for.&lt;br /&gt;&lt;pre class="prettycode"&gt;&lt;br /&gt;&lt;br /&gt;CACLS c:\windows\assembly\temp /e /t /p username:F&lt;br /&gt;&lt;br /&gt;CACLS c:\windows\assembly\tmp /e /t /p username:F&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If this still doesn't resolve, Microsoft has a posting that deals with some other causes:&lt;br /&gt;&lt;a href="http://support.microsoft.com/default.aspx?kbid=811320"&gt;http://support.microsoft.com/default.aspx?kbid=811320&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you want to edit the permissions in explorer.. you can do this by first disabling the 'gac' view in windows explorer and make it a normal folder again:&lt;br /&gt;&lt;pre class="prettycode"&gt;&lt;br /&gt;regsvr32 -u C:\WINNT\Microsoft.NET\Framework\v2.0.50727\shfusion.dll&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;and to register the shell view again (IE make c:\windows\assembly the 'gac' view rather than just a normal folder) run:&lt;br /&gt;&lt;&lt;pre class="prettycode"&gt;&lt;br /&gt;C:\&gt;regsvr32 C:\WINNT\Microsoft.NET\Framework\v2.0.50727\shfusion.dll&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-6717526028578166593?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/6717526028578166593/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2009/12/adding-permissions-to-add-items-to-gac.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/6717526028578166593'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/6717526028578166593'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2009/12/adding-permissions-to-add-items-to-gac.html' title='Adding permissions to add items to the gac for other user accounts'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-1765954447692882670</id><published>2009-12-08T19:11:00.001-08:00</published><updated>2009-12-08T19:24:14.685-08:00</updated><title type='text'>Adding PresentationHost and PresentationUI (Microsoft WPF) assemblies to Sql Server</title><content type='html'>We received various errors when trying to install an assembly of ours that uses CSLA. CSLA uses WPF items rather than System.Windows.Forms. Unfortunately we do not want to make the widespread changes that would need ot occur to CSLA. In the end we actually decided to move anything csla related into another assembly that would not be loaded, however meanwhile I did find a fix which I will describe below.&lt;br /&gt;When adding them we received several errors, one of them being:&lt;br /&gt;&lt;br /&gt;"The assembly returned from the host store has a different strong name signature than the corresponding one in GAC"&lt;br /&gt;&lt;br /&gt;The following reference paths are in different locations and BOTH refer to each other... so you are stuck with a chicken/egg problem here in running:&lt;br /&gt;&lt;br /&gt;CREATE ASSEMBLY [PresentationFramework] AUTHORIZATION dbo FROM 'C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\PresentationFramework.dll' WITH permission_set = unsafe &lt;br /&gt;&lt;br /&gt;It will then try to find PresentationUI which is in a different folder, specifically C:\Windows\Microsoft.NET\Framework\v3.0\WPF\PresentationUI.dll&lt;br /&gt;If you try to add that assembly you will get an error it cannot find PresentationFramework (since PresentationFramework is in a different folder)&lt;br /&gt;&lt;br /&gt;CREATE ASSEMBLY [PresentationUI] AUTHORIZATION dbo FROM 'C:\Windows\Microsoft.NET\Framework\v3.0\WPF\PresentationUI.dll' WITH permission_set = unsafe &lt;br /&gt;&lt;br /&gt;What I did however incorrect it may be (although it works) is to temporarily copy the PresentationUI.dll to the "Reference Assemblies" location (IE the same folder PresentationFramework.dll is located in).&lt;br /&gt;&lt;br /&gt;Then when you run&lt;br /&gt;CREATE ASSEMBLY [PresentationFramework] AUTHORIZATION dbo FROM 'C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\PresentationFramework.dll' WITH permission_set = unsafe &lt;br /&gt;&lt;br /&gt;it will look in the current folder for presentationui.dll now in &lt;br /&gt;C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\PresentationUI.dll &lt;br /&gt;and add the assembly. Once sql server imports it, you can remove the copied file.&lt;br /&gt;&lt;br /&gt;This is not the only dll required in our case, in fact there is another blog entry out there that describes a bunch of the libraries required at:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;http://weblogs.asp.net/albertpascual/archive/2009/07/27/sql-2008-clr-triggers-use-a-net-class-library-in-sql-using-wpf.aspx&lt;br /&gt;&lt;br /&gt;Note: Once you add an assembly that references another assembly, sql server will automatically add that referenced assembly for you.&lt;br /&gt;&lt;br /&gt;We ended up using this list:&lt;br /&gt;&lt;br /&gt;CREATE ASSEMBLY [SMDiagnostics]  FROM 'C:\Windows\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\SMDiagnostics.dll'  WITH permission_set = unsafe &lt;br /&gt;&lt;br /&gt;CREATE ASSEMBLY [System.Runtime.Serialization] AUTHORIZATION dbo FROM 'C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\System.Runtime.Serialization.dll' WITH permission_set = unsafe &lt;br /&gt;&lt;br /&gt;CREATE ASSEMBLY [System.Data.Linq] AUTHORIZATION dbo FROM 'C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5\System.Data.Linq.dll'  WITH permission_set = unsafe &lt;br /&gt;&lt;br /&gt;CREATE ASSEMBLY [System.Core] AUTHORIZATION dbo FROM 'C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5\system.core.dll' WITH permission_set = unsafe &lt;br /&gt;CREATE ASSEMBLY [WindowsBase] AUTHORIZATION dbo FROM 'C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\windowsbase.dll' WITH permission_set = unsafe &lt;br /&gt;CREATE ASSEMBLY [PresentationCFFRasterizer] AUTHORIZATION dbo FROM 'C:\Windows\Microsoft.NET\Framework\v3.0\WPF\PresentationCFFRasterizer.dll' WITH permission_set = unsafe &lt;br /&gt;CREATE ASSEMBLY [System.Drawing] AUTHORIZATION dbo FROM 'C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Drawing.dll' WITH permission_set = unsafe &lt;br /&gt;CREATE ASSEMBLY [PresentationCore] AUTHORIZATION dbo FROM 'C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\PresentationCore.dll' WITH permission_set = unsafe &lt;br /&gt;CREATE ASSEMBLY [PresentationHost] AUTHORIZATION dbo FROM 'C:\Windows\Microsoft.NET\Framework\v3.0\WPF\PresentationHostDLL.dll' WITH permission_set = unsafe &lt;br /&gt;CREATE ASSEMBLY [System.Windows.Forms] AUTHORIZATION dbo FROM 'C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Windows.Forms.dll' WITH permission_set = unsafe &lt;br /&gt;CREATE ASSEMBLY [System.DirectoryServices] AUTHORIZATION dbo FROM 'C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.DirectoryServices.dll' WITH permission_set = unsafe &lt;br /&gt;CREATE ASSEMBLY [PresentationUI] AUTHORIZATION dbo FROM 'C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\PresentationUI.dll' WITH permission_set = unsafe &lt;br /&gt;CREATE ASSEMBLY [PresentationFramework] AUTHORIZATION dbo FROM 'C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\PresentationFramework.dll' WITH permission_set = unsafe &lt;br /&gt;--CREATE ASSEMBLY [PresentationUI] AUTHORIZATION dbo FROM 'C:\Windows\Microsoft.NET\Framework\v3.0\WPF\PresentationUI.dll' WITH permission_set = unsafe &lt;br /&gt;CREATE ASSEMBLY [System.Web] AUTHORIZATION dbo FROM 'C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Web.dll' WITH permission_set = unsafe &lt;br /&gt;CREATE ASSEMBLY [System.Messaging] AUTHORIZATION dbo FROM 'C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Messaging.dll' WITH permission_set = unsafe &lt;br /&gt;CREATE ASSEMBLY [System.IdentityModel] AUTHORIZATION dbo FROM 'C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\System.IdentityModel.dll' WITH permission_set = unsafe &lt;br /&gt;CREATE ASSEMBLY [System.IdentityModel.Selectors] AUTHORIZATION dbo FROM 'C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\System.IdentityModel.Selectors.dll' WITH permission_set = unsafe &lt;br /&gt;CREATE ASSEMBLY [Microsoft.Transactions.Bridge] AUTHORIZATION dbo FROM 'C:\Windows\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\Microsoft.Transactions.Bridge.dll' WITH permission_set = unsafe &lt;br /&gt;CREATE ASSEMBLY [System.ServiceModel] AUTHORIZATION dbo FROM 'C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\System.ServiceModel.dll' WITH permission_set = unsafe &lt;br /&gt;CREATE ASSEMBLY [System.Web.Extensions] AUTHORIZATION dbo FROM 'C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5\System.Web.Extensions.dll' WITH permission_set = unsafe &lt;br /&gt;&lt;br /&gt;CREATE ASSEMBLY[System.Web] from'C:\WINDOWS\Microsoft.NET\Framework64\v2.0.50727\System.Web.dll' with permission_set = UNSAFE&lt;br /&gt;CREATE ASSEMBLY [System.Design] AUTHORIZATION dbo FROM 'C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.Design.dll' WITH permission_set = unsafe&lt;br /&gt;&lt;br /&gt;CREATE ASSEMBLY [Microsoft.Build.Utilities] AUTHORIZATION dbo FROM 'C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Microsoft.Build.Utilities.dll' WITH permission_set = unsafe&lt;br /&gt;&lt;br /&gt;CREATE ASSEMBLY [Microsoft.Build.Tasks] AUTHORIZATION dbo FROM 'C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Microsoft.Build.Tasks.dll' WITH permission_set = unsafe&lt;br /&gt;&lt;br /&gt;CREATE ASSEMBLY [System.Workflow.Runtime] AUTHORIZATION dbo FROM 'C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\System.Workflow.Runtime.dll' WITH permission_set = unsafe&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-1765954447692882670?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/1765954447692882670/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2009/12/adding-presentationhost-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/1765954447692882670'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/1765954447692882670'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2009/12/adding-presentationhost-and.html' title='Adding PresentationHost and PresentationUI (Microsoft WPF) assemblies to Sql Server'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-4304829132819166691</id><published>2009-11-02T14:02:00.000-08:00</published><updated>2009-12-20T21:11:46.978-08:00</updated><title type='text'>Debugging in the GAC - All ways to accomplish this</title><content type='html'>I'm writing this post as a result of a recent discussion with some coworkers and realizing again there is a common misconception in regards to several things with the gac.&lt;br /&gt;&lt;br /&gt;This is a bit of a long post but hopefully will give you a more detailed understanding of PDB fies and the GAC and the various method to debug assemblies in the GAC.&lt;br /&gt;&lt;br /&gt;Since this post is about debugging, Im assuming you have a debug build. There are other builds that use PDB files, read about them &lt;br /&gt;&lt;a href="http://completedevelopment.blogspot.com/2009/07/determining-if-assembly-is-compiled-in.html"&gt;Determining if an assembly is compiled in release or debug mode&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;1. How Visual studio handles adding references to an assembly in the gac&lt;br /&gt;2. How is the PDB used and can one debug with an assembly in the gac? I have a local pdb sitting next to my reference file, do I need to actually put the pdb in the gac? Isn't there another way? (quick answer, there is another way but some choose the gac)&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;The easiest method is defined at the very bottom of this article.&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;How Visual studio handles adding references to an assembly in the gac&lt;/strong&gt;When you click "Add Reference" to a project and get the resulting window. &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_iMjR6GifR0g/Su9ZAd33zqI/AAAAAAAAAG0/pJOyww12rpI/s1600-h/references.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 334px;" src="http://2.bp.blogspot.com/_iMjR6GifR0g/Su9ZAd33zqI/AAAAAAAAAG0/pJOyww12rpI/s400/references.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5399632342794358434" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;These results ARE NOT from the GAC. Visual Studio has these folders stored at:&lt;br /&gt;HKLM\Software\Microsoft\VisualStudio\X.X\AssemblyFolders &lt;br /&gt;where X.X is a version number.&lt;br /&gt;Here you can see how Infragistics shows up in the list because of the folder added under AssemblyFolders&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_iMjR6GifR0g/Su9bgRthwdI/AAAAAAAAAG8/pKMSFRim_IE/s1600-h/references002.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 119px;" src="http://4.bp.blogspot.com/_iMjR6GifR0g/Su9bgRthwdI/AAAAAAAAAG8/pKMSFRim_IE/s400/references002.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5399635088308814290" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;There is another key which contains more information as well located under HKLM\Software\Microsoft\.NETFramework\AssemblyFolders as shown here:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_iMjR6GifR0g/Su9hrd0IAdI/AAAAAAAAAHE/gYVANi_cpKc/s1600-h/references003.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 206px;" src="http://3.bp.blogspot.com/_iMjR6GifR0g/Su9hrd0IAdI/AAAAAAAAAHE/gYVANi_cpKc/s400/references003.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5399641877606040018" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Again, the references window  is _not_ looking at the gac, this is fully registry (and hence path, not gac) based. If you want to add your own folders simply follow the directions by ms to update the registry keys as outlined here:&lt;br /&gt;&lt;a href="http://support.microsoft.com/kb/306149"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So if you need to add a reference to your own assembly that is in the GAC you can either browse for assembly or add a project reference. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;There is something very important to realize here. When you select your item, Visual Studio does check if the assembly you are selecting is ALSO in the GAC. You must have another local copy of that file to reference. What if you don't have it? I lost my file! My dog ate it! This may never ever happen to you but more to increase understanding on this in theory you can go to a command line and make a local copy of this library in most cases. &lt;br /&gt;&lt;pre class="prettycode"&gt;&lt;br /&gt;Follow these steps:&lt;br /&gt;1. open a command line and go to c:\windows\assembly&lt;br /&gt;2. run dir *assemblyname* /s&lt;br /&gt;(that will find the folder in your assembly, or course replacing assemblyname with some portion of your assembly name or just type your whole assembly name)&lt;br /&gt;3. when the results come up go all the way into the assemblyname and then the version folder - you must do this at the command line, there is shell integration with the GAC so you cannot view this folder through explorer.&lt;br /&gt;4. Run the copy command to copy the dll out for instance copy *.* c:\temp&lt;br /&gt;5. Add your reference from the temp folder&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;How is the PDB used and can one debug with an assembly in the GAC? I have a local PDB sitting next to my reference file, do I need to actually put the PDB in the GAC? Isn't there another way?&lt;/strong&gt;&lt;br /&gt;You can indeed debug an assembly in the gac and its quite easy. There are several ways to do it, and it depends on your version of Visual Studio and how you want to do this. &lt;br /&gt;&lt;br /&gt;First what is the GAC - the GAC is a place for shared libraries. If you develop a component and five applications use it, the GAC is a great place to house that component. You only need to ever update one location - the GAC.&lt;br /&gt;&lt;br /&gt;Whats inside the gac?&lt;br /&gt;If you navigate to c:\windows\assembly you will find in explorer you cannot get there in a regular file view because of the shell integration. So, you must view this folder at the command line:  dir c:\windows\assembly&lt;br /&gt;&lt;br /&gt;Note the results:&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_iMjR6GifR0g/Sx8ZTN2UyrI/AAAAAAAAAHk/tz6QFGKwSYo/s1600-h/cwindowsassembly.GIF"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 250px;" src="http://2.bp.blogspot.com/_iMjR6GifR0g/Sx8ZTN2UyrI/AAAAAAAAAHk/tz6QFGKwSYo/s400/cwindowsassembly.GIF" border="0" alt=""id="BLOGGER_PHOTO_ID_5413073095048350386" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettycode"&gt;&lt;br /&gt;GAC Folders&lt;br /&gt;&lt;strong&gt;GAC &lt;/strong&gt;- .net 1.x asemblies&lt;br /&gt;&lt;strong&gt;GAC_32&lt;/strong&gt; - 32 bit assemblies. If you are on a 64 bit machine you will see a GAC_64 as well. This was new to .net 2&lt;br /&gt;&lt;strong&gt;GAC_MSIL &lt;/strong&gt; - Images that can run in either 32 or 64 bit&lt;br /&gt;&lt;strong&gt;NativeImages*&lt;/strong&gt; - These are ngen'd images running as native compiled code (rather than intermediate language)&lt;br /&gt;&lt;strong&gt;temp/tmp &lt;/strong&gt; tmp is used for gac installation and temp is used for the uninstall. At times these folders will contain files that upon a reboot will clean up. Sometimes failed install will leave files here as well.&lt;br /&gt;See more on this subject at:&lt;br /&gt;&lt;a href="http://blogs.msdn.com/junfeng/archive/2005/10/24/484063.aspx"&gt;GAC Assemblies: Install and Uninstall&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In order to debug, you need a PDB (program database file) You cannot install a pdb into the gac via gacutil.exe, you can only install an assembly with gacutil. You have two choice here. There are problems with this method which I will describe below&lt;br /&gt;&lt;br /&gt;A. Put the pdb in the GAC manually. This will work. I did see a posting that claimed it did not work, it does indeed work, I've done it quite a few times in the past. You can copy it from a command line by something like the following at a command line:&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettycode"&gt;&lt;br /&gt;1. cd c:\windows\assembly\gac_msil&lt;br /&gt;2. cd *aPartOfYourAssemblyName*     then using that path:&lt;br /&gt;3. cd C:\WINDOWS\assembly\GAC_MSIL\MyAssembly\1.0.0.0__121ade23gaef410&lt;br /&gt;now copy it into the gac folder by:&lt;br /&gt;4. copy c:\source\MyAssembly\bin\debug\MyAssembly.pdb .&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Restart your application and attach the debugger. &lt;br /&gt;&lt;br /&gt;Secondly, you can also simply set your build "output path" in visual studio on your project properties -&gt; Build tab to be the specific gac folder. IE instead of doing the manual copy above, just set that gac folder as the build output folder. You will need to install your assembly into the gac first to get the proper folder name, and you want to make sure the version of your assembly isn't changing with each build or.. this just won't work.. so the technique isn't the best.. but it's possible.&lt;br /&gt;&lt;br /&gt;There is another problem with this method. If something has your pdb loaded (ie visual studio/w3wp/aspnet) and your assembly is part of a solution that deploys it into the gac using gacutil, you may fail the compile. The reason is, your GAC folder is removed when you update it. If there is a PDB file with a reference to it, fusion cannot remove it when doing the install process.&lt;br /&gt; &lt;br /&gt;&lt;strong&gt;Then there is the method where you don't need to copy the pdb file.&lt;/strong&gt;&lt;br /&gt;Configure Visual Studio (versions 2005 and up), to debug code besides "just my code" which is an option under tools-&gt;options-&gt;debugging-&gt;Enable Just My Code. &lt;span style="font-weight:bold;"&gt;Uncheck this option&lt;/span&gt;&lt;br /&gt;Visual Studio will then search the path you gave it to reference your gac library and look for a pdb file. Set the path of your PDB file on the Tools-&gt;Options-&gt;Debugging-&gt;Symbols tab. &lt;br /&gt;&lt;br /&gt;What is 'just my code'? Basically this is code that falls under the following criteria:&lt;br /&gt;Not optimized&lt;br /&gt;No Symbols&lt;br /&gt;Assembly has the DebuggerNonUserCodeAttribute &lt;br /&gt;(info from: &lt;a href="http://blogs.msdn.com/saraford/archive/2008/08/12/did-you-know-what-is-just-your-code-289.aspx"&gt;Sarah Ford: Did you know… what is just your code&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Also make sure you have "Suppress JIT Optimizations on module load" to help prevent issues determining "just my code" (ie if its optimized then it will be determined to be not your code)&lt;br /&gt;This can be set on : Tools–&gt;Options-&gt;Debugging–&gt;General-&gt;Suppress JIT optimization on module load (Managed only)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;C. Configure Visual Studio to look to a symbol server. This is a strong method - as you can publish your symbols to a symbol server or to a folder and always have the required version available. For instance, if you need to setup remote debugging against a production release, the proper version pdb files will automatically load once you pull down the required source code. This way requires you to deploy the symbols for a specific version to the symbol server. I will add more steps to this hopefully in the future. &lt;br /&gt; &lt;br /&gt;&lt;br /&gt;Who hangs onto the pdb? Visual studio and aspnet_wp.exe or w3wp.exe (iis 6+) both will use the pdb. Why aspnet_wp/w3wp you ask? If you've ever seen an error on a webpage with a fill callstack and source code information, then understand these processes will use the .pdb file to properly determine this information.This is only made possible by having a pdb available.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;The easiest method available is to simply start debugging and tell visual studio where to find the pdb file.&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Select Debug-&gt;Windows-&gt;Modules once you start debugging (for example attach to aspnet_wp.exe or w3wp.exe)&lt;br /&gt;Here you can see "Symbol Status" shows that it cannot find the symbols. Since this is a Microsoft assembly, I can simply get the symbols from Microsoft by right clicking and selecting "Load Symbols From-&gt;Microsoft Symbol Servers"&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_iMjR6GifR0g/Sy8BIXJa1YI/AAAAAAAAAH4/la-w8OUVssY/s1600-h/2009-12-18_01-01-49-970.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 107px;" src="http://1.bp.blogspot.com/_iMjR6GifR0g/Sy8BIXJa1YI/AAAAAAAAAH4/la-w8OUVssY/s400/2009-12-18_01-01-49-970.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5417550119914100098" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Here we see Visual Studio contacting Microsoft for the symbols&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_iMjR6GifR0g/Sy8BIiHWsMI/AAAAAAAAAIA/NSSP9Fmmf9I/s1600-h/2009-12-18_01-02-24-954.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 81px;" src="http://2.bp.blogspot.com/_iMjR6GifR0g/Sy8BIiHWsMI/AAAAAAAAAIA/NSSP9Fmmf9I/s400/2009-12-18_01-02-24-954.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5417550122858229954" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Once the symbols have loaded you can select "Symbol Load Information" (actually you can do this on any item and you will see  the search it did to try to find the symbols, very helpful sometimes in determining why your symbols didn't get loaded)&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_iMjR6GifR0g/Sy8BI4r0fwI/AAAAAAAAAII/azfflMP_STY/s1600-h/show+loaded+info.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 142px;" src="http://1.bp.blogspot.com/_iMjR6GifR0g/Sy8BI4r0fwI/AAAAAAAAAII/azfflMP_STY/s400/show+loaded+info.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5417550128916758274" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The results:&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_iMjR6GifR0g/Sy8BJBbFgaI/AAAAAAAAAIQ/i7g9QozBjCk/s1600-h/loadedinfo.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 223px;" src="http://3.bp.blogspot.com/_iMjR6GifR0g/Sy8BJBbFgaI/AAAAAAAAAIQ/i7g9QozBjCk/s400/loadedinfo.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5417550131262488994" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If we click on "Symbol Settings" in the above dialog we see a temporary folder has automatically been chosen to download thhe symbols from Microsoft into:&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_iMjR6GifR0g/Sy8BJcpUsBI/AAAAAAAAAIY/CRxImcLsixA/s1600-h/autofilled+directory.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 237px;" src="http://3.bp.blogspot.com/_iMjR6GifR0g/Sy8BJcpUsBI/AAAAAAAAAIY/CRxImcLsixA/s400/autofilled+directory.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5417550138569961490" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Now if we look at the modules window, it is very clear our symbols have been loaded.&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_iMjR6GifR0g/Sy8BQmvydkI/AAAAAAAAAIg/vWTJZhXnaKY/s1600-h/symbols+loaded+status.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 46px;" src="http://2.bp.blogspot.com/_iMjR6GifR0g/Sy8BQmvydkI/AAAAAAAAAIg/vWTJZhXnaKY/s400/symbols+loaded+status.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5417550261540517442" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;so how do we use this for non-Microsoft assemblies? Very easy. You right click, select 'Load Symbols From-&gt;Symbol Path' and enter in the path to your .pdb file. Thats it, and its dynamic so may be the easiest solution for you.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-4304829132819166691?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/4304829132819166691/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2009/11/debugging-in-gac-all-ways-to-accomplish.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/4304829132819166691'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/4304829132819166691'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2009/11/debugging-in-gac-all-ways-to-accomplish.html' title='Debugging in the GAC - All ways to accomplish this'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_iMjR6GifR0g/Su9ZAd33zqI/AAAAAAAAAG0/pJOyww12rpI/s72-c/references.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-405001292885385008</id><published>2009-10-22T07:52:00.000-07:00</published><updated>2009-12-22T14:21:49.580-08:00</updated><title type='text'>Executing many scripts at once in Sql Mangement Studio</title><content type='html'>I have 110 stored procedures to execute. I can use a tool such as Red Gate's Sql Toolbelt to script the differences, however I'm setting up a new database. I have several choices:&lt;br /&gt;1. create one large script file.&lt;br /&gt;2. script differences&lt;br /&gt;3. run each script in management studio one by one&lt;br /&gt;4. call osql.exe for each and every script&lt;br /&gt;5. load all scripts (drag and drop) into management studio without being prompted every time (quickest method)&lt;br /&gt;&lt;br /&gt;scenario 1 - I have to put everything into one hugggeee query file. This will take time to run and execute.&lt;br /&gt;&lt;br /&gt;scenario 2 - I can script changes, however this doesn't guarantee we have current changes in our source control system. Quite often changes can get into a database that aren't properly scripted. I'm a fan of this, but it is always good to establish a baseline with your scripts to make sure they are correct (if your environment is source control and script based). The issue is in the database Im about to compare, there are many many other changes that are not required for the application functionality I'm working on.&lt;br /&gt;&lt;br /&gt;scenario 3 - last time I tried opening 110 files in management studio, it crashed. Also it prompts for _every_ connection and there is no auto-connect option in the application's interface.&lt;br /&gt;&lt;br /&gt;scenario 4 - this requires writing a script, which is generally trivial to enumerate a folder and run osql, however this requires combing through the output for errors and running queries with issues again. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;scenario 5 - If I can only get management studio to not prompt me, I can run a script and see the output and continue. By default, management studio will prompt you on each and every query you open. However, if you launch a command line with a list of files, or a single INVALID file, it will retain the connection info, and all new items you drag and drop will automatically be opened with this connection.&lt;br /&gt;&lt;br /&gt;so simply run the command:&lt;br /&gt;&lt;br /&gt;sqlwb -s ServerName -d DatabaseName -u UserName -p Password -e  fakefilename.txt&lt;br /&gt;&lt;br /&gt;(im assuming sql authentication here for this example not integrated).&lt;br /&gt;Now drag and drop all of your scripts here and they will open with a connection, and without prompting you.&lt;br /&gt;&lt;br /&gt;You will still have to press f5 for every script, but for me it took two minutes to process 110 files pressing f5 to execute each one and clicking the x to close each one after there were no errors.&lt;br /&gt;&lt;br /&gt;This saved me a little bit of time : )&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-405001292885385008?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/405001292885385008/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2009/10/executing-many-scripts-at-once-in-sql.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/405001292885385008'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/405001292885385008'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2009/10/executing-many-scripts-at-once-in-sql.html' title='Executing many scripts at once in Sql Mangement Studio'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-4868934274241383006</id><published>2009-07-15T08:40:00.000-07:00</published><updated>2011-06-10T06:57:53.949-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='debuggable attribute'/><category scheme='http://www.blogger.com/atom/ns#' term='release mode'/><category scheme='http://www.blogger.com/atom/ns#' term='debugging'/><category scheme='http://www.blogger.com/atom/ns#' term='debug mode'/><title type='text'>Determining if an assembly is compiled in release or debug mode</title><content type='html'>To determine if an assembly was compiled in debug mode, look for the following Debuggable attribute at the assembly level. You will need to look at the flags set on it which have the following values:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:js"&gt;Default = int32(1)&lt;br /&gt;DisableOptimizations = int32(0x100)&lt;br /&gt;EnableEditAndContinue = int32(4)&lt;br /&gt;IgnoreSymbolStoreSequencePoints = int32(2)&lt;br /&gt;None = int32(0)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If the attribute is there, it does not mean it is or is not a debug/release build. What is important to check is the flag values, and what you are looking for. You can have a release build, and still generate PDB information. This pdb information is more limited, since optimizations are still enabled you will not be able to debug this program at a source level. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;How do you find this attribute on a compiled assembly?&lt;/strong&gt;&lt;br /&gt;1. Open the assembly in reflector&lt;br /&gt;2. Click on the assembly at the base level (ie do not click on any classes underneath the root level, make sure the assembly name is highlighted in reflector)&lt;br /&gt;3. Hit the spacebar to make sure you can view the disassembly on the right hand side.&lt;br /&gt;4. Look at the output for the Debuggable attribute.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The scenarios here show:&lt;br /&gt;1. Default Debug release (So no optimizations set and full debug info being generated)&lt;br /&gt;2. Default Release (Enable Optimizations checked off and pdb-only option set)&lt;br /&gt;3. Release mode with no pdb info being generated&lt;br /&gt;4. Release mode with full pdb info being generated&lt;br /&gt;5. Release with optimizations unchecked and full pdb info being generated&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Where are the mentioned settings?&lt;/strong&gt;&lt;br /&gt;In Visual Studio 2008 go into the project properties and then the build section. There is a checkbox there for "Optimize Code". The second option is under the "Advanced" button at the bottom of the screen. The setting is "Debug Info" and the options are "none, pdb-only, full"&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Scenario 1&lt;/strong&gt;&lt;br /&gt;Default debug release the assembly shows the following (other attributes removed)&lt;br /&gt;We see the value is 107, so look at the enum values to figure out the options:&lt;br /&gt;DisableOptimizations (100)&lt;br /&gt;EnableEditAndContinue (4)&lt;br /&gt;IgnoreSymbolStoreSequencePoints (2)&lt;br /&gt;Default (1)&lt;br /&gt;We OR these bits all together (IE add them) and we come up with 107&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:js"&gt;.assembly DebuggableTest&lt;br /&gt;{&lt;br /&gt;.custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype &lt;br /&gt;&lt;br /&gt;[mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = { int32(0x107) }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Scenario 2&lt;/strong&gt;&lt;br /&gt;Release mode:&lt;br /&gt;&lt;br /&gt;Options set:&lt;br /&gt;IgnoreSymbolStoreSequencePoints &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:js"&gt;.assembly DebuggableTest&lt;br /&gt;{&lt;br /&gt;.custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = { int32(2) }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Scenario 3&lt;/strong&gt;&lt;br /&gt;Release mode with no pdb info being generated (ie debug info set to "none" in the advanced options)&lt;br /&gt;Notice there is no Debuggable attribute set in this option&lt;br /&gt;Options set:&lt;br /&gt;NONE&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:js"&gt;.assembly DebuggableTest&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Scenario 4&lt;/strong&gt;&lt;br /&gt;Release mode with the "full" option set for debug info (ie full pdb info being generated )&lt;br /&gt;Options set:&lt;br /&gt;IgnoreSymbolStoreSequencePoints &lt;br /&gt;Default&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:js"&gt;.assembly DebuggableTest&lt;br /&gt;{&lt;br /&gt;.custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = { int32(3) }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Scenario 5&lt;/strong&gt;&lt;br /&gt;Release mode with optimizations unchecked and full pdb info being generated. In theory this is the same as a debug build. Lets check:&lt;br /&gt;Options set:&lt;br /&gt;DisableOptimizations (100)&lt;br /&gt;EnableEditAndContinue (4)&lt;br /&gt;IgnoreSymbolStoreSequencePoints (2)&lt;br /&gt;Default (1)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:js"&gt;.assembly DebuggableTest&lt;br /&gt;{&lt;br /&gt;.custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = { int32(0x107) }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;To do this in code - I got this I believe from:&lt;br /&gt;http://www.jamesewelch.com/2007/08/30/how-to-tell-if-a-net-assembly-is-debug-or-release/&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:c#"&gt;Assembly assemb = Assembly.LoadFile(Path.GetFullPath(fileName));&lt;br /&gt;bool isDebug = false;&lt;br /&gt;foreach (object attribute in assemb.GetCustomAttributes(false))&lt;br /&gt;{&lt;br /&gt;     if (attribute is DebuggableAttribute)&lt;br /&gt;     {&lt;br /&gt;          isDebug = ((DebuggableAttribute)attribute ).IsJITTrackingEnabled;&lt;br /&gt;     }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if(isDebug)&lt;br /&gt;{&lt;br /&gt;  //'got me some debug code!&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Hope this helps!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-4868934274241383006?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/4868934274241383006/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2009/07/determining-if-assembly-is-compiled-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/4868934274241383006'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/4868934274241383006'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2009/07/determining-if-assembly-is-compiled-in.html' title='Determining if an assembly is compiled in release or debug mode'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-6743534653986963796</id><published>2009-06-22T20:14:00.000-07:00</published><updated>2009-06-22T20:16:41.757-07:00</updated><title type='text'>Quick way to determine row count from index</title><content type='html'>I use the following query for two reasons:&lt;br /&gt;1. as a quick way to determine row count. Rather than doing select count(columnname) which touches every single row, this looks up the row count from the index.&lt;br /&gt;&lt;br /&gt;2. When I want to clear information out of a large test database for local use - this allows me to see what tables have the most information so I know which tables to work on clearing some information out of first.&lt;br /&gt;&lt;br /&gt;SELECT rows ,OBJECT_NAME(id), * FROM sysindexes WHERE indid &lt; 2 ORDER BY [rowcnt] DESC&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-6743534653986963796?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/6743534653986963796/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2009/06/quick-way-to-determine-row-count-from.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/6743534653986963796'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/6743534653986963796'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2009/06/quick-way-to-determine-row-count-from.html' title='Quick way to determine row count from index'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-8748400329868188619</id><published>2009-06-06T09:54:00.000-07:00</published><updated>2010-10-21T12:03:57.660-07:00</updated><title type='text'>Multiple host headers, ssl, and WCF failures</title><content type='html'>Came across an interesting scenario in deploying a wcf service that used transport security (ssl). &lt;br /&gt;&lt;br /&gt;Symptoms:&lt;br /&gt;&lt;br /&gt;Navigating to your WCF service in the browser shows you the wrong internal address.&lt;br /&gt;You are trying to access your site as www.PublicAddress.com/MyService.svc and the page coming back tells you to run&lt;br /&gt;&lt;br /&gt;svcutil.exe  http://www.PrivateMachineName/MyService.svc&lt;br /&gt;&lt;br /&gt;NOOooo you say. That's not what I want! Luckily the solution isn't that difficult but you do have several choices in increasing difficulty.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Solutions:&lt;br /&gt;1. Set host header&lt;br /&gt;    This method is the quickest but you have to be aware of a couple situations.&lt;br /&gt;    a. You are not using ssl - Simply go into IIS (Im assuming 6 for this posting) and right click on your site, then click "advanced" to add the host headers. Typical scenarios have it configured as "All unassigned addresses" to port 80. Or a specific IP address assigned to port 80, with no host header listed. If either of these fit your case, just click "edit" and add your host name such as www.PublicSite.com&lt;br /&gt;NOTE: If you already have a host header listed or need two host headers, which is very common for sites (such as www.publicsite.com and publicsite.com) WCF will fail when you try to run your service with:&lt;br /&gt;This collection already contains an address with scheme http.  There can be at most one address per scheme in this collection. &lt;br /&gt;&lt;br /&gt;You CANNOT by default start a wcf service with multiple host names bound to an address. Doh! If you must add multiple hosts to your site, then you cannot use this method. In that case it may make sense to create another site in IIS that responds to a different host header. Such as services.publicsite.com and you can add your host header to iis for that new site, update your web.config if necessary to fit the new address (if you have specified an identity in your web.config then change it, if not then your service will figure out what the proper identity is). For example you only need to update your config if the following case fits or you need ssl on your site and need to modify  the &lt;serviceCredentials&gt;&lt;serviceCertificate&gt; element&lt;br /&gt;&lt;pre code="pretty"&gt;&lt;br /&gt;&amp;lt;!-- &lt;br /&gt;Upon deployment, the following identity element should be removed or replaced to reflect the &lt;br /&gt;identity under which the deployed service runs.  If removed, WCF will infer an appropriate identity &lt;br /&gt;automatically.&lt;br /&gt;--&amp;gt;&lt;br /&gt;&amp;lt;identity&amp;gt;&lt;br /&gt;      &amp;lt;dns value="www.publicsite.com"/&amp;gt;&lt;br /&gt;&amp;lt;/identity&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now, if you are using ssl it becomes a tiny bit trickier. You see adding the host header to port 80 binding in iis like we did above does not apply to ssl. You must specifically add the host header for ssl using the adsutil.vbs script usually located at c:\inetpub\adminscripts  &lt;br /&gt;if it is not there and it was possibly removed and you don't feel like installing it sometimes it can be found on a server at %SYSTEMROOT%\ServicePackFiles\i386&lt;br /&gt;&lt;br /&gt;You can add host headers for port 80 here as well, so lets go over both.&lt;br /&gt;&lt;br /&gt;1. If you are running more than one site on the machine verify the site id to use in the scripts by running at a command prompt:&lt;br /&gt;cscript.exe adsutil.vbs ENUM /P W3SVC&lt;br /&gt;&lt;br /&gt;Shows:&lt;br /&gt;Microsoft (R) Windows Script Host Version 5.6&lt;br /&gt;Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.&lt;br /&gt;&lt;br /&gt;[/W3SVC/1]&lt;br /&gt;[/W3SVC/439224544]&lt;br /&gt;[/W3SVC/AppPools]&lt;br /&gt;[/W3SVC/Filters]&lt;br /&gt;[/W3SVC/Info]&lt;br /&gt;&lt;br /&gt;Take note in this case I have two sites setup. The first site is /1, the second is a random number.&lt;br /&gt;&lt;br /&gt;Check the server bindings&lt;br /&gt;a. Cscript.exe adsutil.vbs GET W3SVC/1/ServerBindings      this will return something like the following, note no host header listed after port 80&lt;br /&gt;ServerBindings                  : (LIST)  (1 Items)&lt;br /&gt;"23.16.44.11:80: "&lt;br /&gt;&lt;br /&gt;b. If this is not the site you want, you need to look up the site id by running this command, and substitute the /1/ above with the actual site  id returned from the ENUM command above.&lt;br /&gt;&lt;br /&gt;c. Add the binding for non-ssl and ssl&lt;br /&gt;Cscript.exe adsutil.vbs set W3SVC/1/ServerBindings ":80:www.mysite.com"&lt;br /&gt;Cscript.exe adsutil.vbs set W3SVC/1/SecureBindings ":443:www.mysite.com"&lt;br /&gt;&lt;br /&gt;Note if you want to have just mysite.com, you will run into a problem because of multiple host headers since you will have www.mysite.com and mysite.com&lt;br /&gt;&lt;br /&gt;You can verify changes by running these commands, and you should now see the beta.drtms.net listed for each item.&lt;br /&gt;d. Cscript.exe adsutil.vbs GET W3SVC/1/ServerBindings&lt;br /&gt;e. Cscript.exe adsutil.vbs GET W3SVC/1/SecureBindings&lt;br /&gt;&lt;br /&gt;For e. above, yes it true, just because you have a host header assigned in iis does not mean ssl inherits it. You must explicitly set this via the script here to work with WCF. Once done, reset iis (run iisreset as a command line) and that should do it for you.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;2. Try binding filters (I'll edit this post shortly on this item)&lt;br /&gt;3. Implement a custom factory to tell ServiceHost which uris to bind to.&lt;br /&gt;4. Avoid the whole problem and use restful services. This involves changing a bit of your code so will consider it not as easy as the main solution here.&lt;br /&gt;5. Implement with web services and let IIS fully handle ssl without worrying about multiple bindings. If you required authentication use basic authentication over ssl configured in IIS. If you don't want to use windows accounts for basic authentication you can implement a custom basic auth provider, such as shown here on codeplex: &lt;a href="http://www.codeplex.com/CustomBasicAuth"&gt;http://www.codeplex.com/CustomBasicAuth&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-8748400329868188619?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/8748400329868188619/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2009/06/multiple-host-headers-ssl-and-wcf.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/8748400329868188619'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/8748400329868188619'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2009/06/multiple-host-headers-ssl-and-wcf.html' title='Multiple host headers, ssl, and WCF failures'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-1765218249419621265</id><published>2009-06-02T20:24:00.000-07:00</published><updated>2010-06-15T11:17:09.430-07:00</updated><title type='text'>Multiple host headers / ssl / incorrect wsdl addresses using local machine</title><content type='html'>Came across an interesting scenario in deploying a wcf service that used transport security (ssl). &lt;br /&gt;&lt;br /&gt;Symptoms:&lt;br /&gt;&lt;br /&gt;Navigating to your WCF service in the browser shows you the wrong internal address.&lt;br /&gt;You are trying to access your site as www.PublicAddress.com/MyService.svc and the page coming back tells you to run&lt;br /&gt;&lt;br /&gt;svcutil.exe  http://www.PrivateMachineName/MyService.svc&lt;br /&gt;&lt;br /&gt;NOOooo you say. That's not what I want! Luckily the solution isn't that difficult but you do have several choices in increasing difficulty.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Solutions:&lt;br /&gt;1. Set host header&lt;br /&gt;    This method is the quickest but you have to be aware of a couple situations.&lt;br /&gt;    a. You are not using ssl - Simply go into IIS (Im assuming 6 for this posting) and right click on your site, then click "advanced" to add the host headers. Typical scenarios have it configured as "All unassigned addresses" to port 80. Or a specific IP address assigned to port 80, with no host header listed. If either of these fit your case, just click "edit" and add your host name such as www.PublicSite.com&lt;br /&gt;NOTE: If you already have a host header listed or need two host headers, which is very common for sites (such as www.publicsite.com and publicsite.com) WCF will fail when you try to run your service with:&lt;br /&gt;This collection already contains an address with scheme http.  There can be at most one address per scheme in this collection. &lt;br /&gt;&lt;br /&gt;You CANNOT by default start a wcf service with multiple host names bound to an address. Doh! If you must add multiple hosts to your site, then you cannot use this method. In that case it may make sense to create another site in IIS that responds to a different host header. Such as services.publicsite.com and you can add your host header to iis for that new site, update your web.config if necessary to fit the new address (if you have specified an identity in your web.config then change it, if not then your service will figure out what the proper identity is). For example you only need to update your config if the following case fits or you need ssl on your site and need to modify  the &lt;serviceCredentials&gt;&lt;serviceCertificate&gt; element&lt;br /&gt;&lt;pre code="pretty"&gt;&lt;br /&gt;&amp;lt;!-- &lt;br /&gt;Upon deployment, the following identity element should be removed or replaced to reflect the &lt;br /&gt;identity under which the deployed service runs.  If removed, WCF will infer an appropriate identity &lt;br /&gt;automatically.&lt;br /&gt;--&amp;gt;&lt;br /&gt;&amp;lt;identity&amp;gt;&lt;br /&gt;      &amp;lt;dns value="www.publicsite.com"/&amp;gt;&lt;br /&gt;&amp;lt;/identity&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now, if you are using ssl it becomes a tiny bit trickier. You see adding the host header to port 80 binding in iis like we did above does not apply to ssl. You must specifically add the host header for ssl using the adsutil.vbs script usually located at c:\inetpub\adminscripts  &lt;br /&gt;if it is not there and it was possibly removed and you don't feel like installing it sometimes it can be found on a server at %SYSTEMROOT%\ServicePackFiles\i386&lt;br /&gt;&lt;br /&gt;You can add host headers for port 80 here as well, so lets go over both.&lt;br /&gt;&lt;br /&gt;1. If you are running more than one site on the machine verify the site id to use in the scripts by running:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;2. Try binding filter&lt;br /&gt;3. Implement custom factory&lt;br /&gt;4. Avoid the whole problem and use restful services&lt;br /&gt;5. Implement with web services and let IIS fully handle ssl without worrying about multiple bindings. If you required authentication use basic authentication over ssl configured in IIS. If you don't want to use windows accounts for basic authentication you can implement a custom basic auth provider, such as shown here on codeplex: &lt;a href="http://www.codeplex.com/CustomBasicAuth"&gt;http://www.codeplex.com/CustomBasicAuth&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;#4 was recommended to us, but if you've already developed the service then its not the best solution imho since there are relatively easy ways&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-1765218249419621265?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/1765218249419621265/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2009/06/multiple-host-headers-ssl-incorrect.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/1765218249419621265'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/1765218249419621265'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2009/06/multiple-host-headers-ssl-incorrect.html' title='Multiple host headers / ssl / incorrect wsdl addresses using local machine'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-6212174878271811402</id><published>2009-05-27T11:16:00.001-07:00</published><updated>2009-12-17T21:41:16.928-08:00</updated><title type='text'>Using nUnit AND Mstest (Visual Studio Unit Testing) together in perfect harmony</title><content type='html'>I like mstest. I like the integration. I like right clicking on a method and adding a unit test SNAP done.&lt;br /&gt;It works great for me. nUnit is 'ok' to me. Integration is poor without third party tools. You have to change things around to get it to work. Sometimes I get strange errors I just dont get using mstest.&lt;br /&gt;You have to set config files up to be named the same as the project. Not intuitive at first since nothing actually tells you this - you expect to be able to tell it your assembly and voila. Now.. you can use a different sequence of events to prevent this, such as add assembly before creating a project in nUnit, but thats not obvious to anyone first using it. &lt;br /&gt;&lt;br /&gt;however.. to use nUnit on a build server I dont need to install Visual Studio. In order to use Microsoft's unit testing, you need to either install Visual Studio on the build server or go through a hack to get the components on there. Its not pretty. So nUnit shines here. But.. why not use mstest in the IDE and nUnit on your build server? They have different namespaces - but you can change the aliases around to do this successfully. &lt;br /&gt;&lt;br /&gt;At the top of your classes in your unit test projects define the following to default to microsoft testing unless a build constant is defined called NUNIT&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettycode"&gt;&lt;br /&gt;#if !NUNIT&lt;br /&gt;using Microsoft.VisualStudio.TestTools.UnitTesting;&lt;br /&gt;using Category = Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute;&lt;br /&gt;#else&lt;br /&gt;using NUnit.Framework;&lt;br /&gt;using TestInitialize = NUnit.Framework.SetUpAttribute;&lt;br /&gt;using TestContext = System.Object;&lt;br /&gt;using TestProperty = NUnit.Framework.PropertyAttribute;&lt;br /&gt;using TestClass = NUnit.Framework.TestFixtureAttribute;&lt;br /&gt;using TestMethod = NUnit.Framework.TestAttribute;&lt;br /&gt;using TestCleanup = NUnit.Framework.TearDownAttribute;&lt;br /&gt;#endif&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Go into Visual Studio, choose the Build menu and select "Configuration Manager"&lt;br /&gt;Select "new" and name this build Nunit (or mstest or whatever you want to NOT be your debug/release build). Personally.. I use a build name called MsTest since my debug builds are what get automatically tested every night with cruisecontrol.net/nant/nUnit so I want my default builds to compile with nUnit, but when I want to add/debug unit tests in the IDE I simply change my build to MsTest.&lt;br /&gt;&lt;br /&gt;Once you create a new build name, go into each of your projects once you select the build, and go to prokect properties. In the Build tab under "Conditional Compilation Symbols" type in MSTEST or NUNIT.&lt;br /&gt;Use NUNIT if you call your build nUnit and use the code above. This will assume you want your default debug/release build to default to Microsoft. Case DOES matter for the conditional compilation constants.. make sure you use all uppercase.. its easier.&lt;br /&gt;&lt;br /&gt;If you want to create a separate build configuration for testing Microsoft unit tets, but want to keep the default debug/release for nUnit then your headers would look like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettycode"&gt;&lt;br /&gt;#if MSTEST&lt;br /&gt;using Microsoft.VisualStudio.TestTools.UnitTesting;&lt;br /&gt;using Category = Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute;&lt;br /&gt;#else&lt;br /&gt;using NUnit.Framework;&lt;br /&gt;using TestInitialize = NUnit.Framework.SetUpAttribute;&lt;br /&gt;using TestContext = System.Object;&lt;br /&gt;using TestProperty = NUnit.Framework.PropertyAttribute;&lt;br /&gt;using TestClass = NUnit.Framework.TestFixtureAttribute;&lt;br /&gt;using TestMethod = NUnit.Framework.TestAttribute;&lt;br /&gt;using TestCleanup = NUnit.Framework.TearDownAttribute;&lt;br /&gt;#endif&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;hope this helps : )&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-6212174878271811402?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/6212174878271811402/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2009/05/blog-post.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/6212174878271811402'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/6212174878271811402'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2009/05/blog-post.html' title='Using nUnit AND Mstest (Visual Studio Unit Testing) together in perfect harmony'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-7366350360100497277</id><published>2009-05-26T11:51:00.000-07:00</published><updated>2009-05-26T17:53:21.316-07:00</updated><title type='text'>An easier way to track parameters in unit testing for Visual Studio (mstext.exe)</title><content type='html'>One downside in unit testing is having an easy way view and use the test parameters. Sure you can put them in the code, but its hard to see how it varies from method to method. Ok.. maybe 'hard' isn't it, but 'not as clean as having all test parameters in one spot' I'll say. So I wrote a quick routine to extract the parameters. note: &lt;br /&gt;&lt;br /&gt;I created a method called &lt;span style="font-weight:bold;"&gt;SetPropsToAttributes()&lt;/span&gt; and also &lt;span style="font-weight:bold;"&gt;GetAttributeValue()&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;For &lt;span style="font-weight:bold;"&gt;SetPropsToAttributes&lt;/span&gt;, Pass in an object and based on the TestProperty() attributes, it will find the matching property (not case sensitive) and set its value. So you can pass in an object and any attributes that are named the same as the object's properties, will have the values set to whatever are in the attributes. So all test information is kept then at the top of the method.&lt;br /&gt;&lt;br /&gt;For GetAttributeValue, the idea here is an easier way to get a single value:&lt;br /&gt;If I have this method:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:js"&gt;&lt;br /&gt;[TestMethod]&lt;br /&gt;[TestProperty("UserName","Adam Tuliper")]&lt;br /&gt;[TestProperty("Password","nobodyknows")]&lt;br /&gt;public void TestLogin()&lt;br /&gt;{&lt;br /&gt;   LoginHandler handler = new LoginHandler();&lt;br /&gt;   handler.Login((string)("UserName"), (string)GetAttributeValue("Password"));&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You can see here I easily get the parameters. I don't have to look through code to get test information. Every method has it at the top. This also makes it easy to copy and paste information into a test script for documentation purposes.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;On the helper methods below I use [MethodImpl(MethodImplOptions.NoInlining)] because this is meant for debug code only in your _test program_ (not in the actual bytes being unit tested) which you would have during a unit test. The stack frame tracking and debug information is different (debug information is missing unless you do a release build with the pdbonly advanced option selected - this should work in that scenario but I haven't tried it) depending on options selected) in a release build. When you compile a release build, there are optimizations performed and the compiler may decide to inline the method calls, thus breaking the way this routine finds the method that called it. Read again: this will break in release builds - it is for debug code only, but then again thats the whole purpose of this posting : )&lt;br /&gt;&lt;br /&gt;One more note - Do not call SetPropsToAttributes and GetAttribute from more than one level up.. Ie dont do this: Method1() - &gt; Method2() -&gt; GetAttribute(for memthod1)&lt;br /&gt;as the code only looks up one stack frame on top of GetAttribute to determine the calling method.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So we &lt;br /&gt;1. Create method based&lt;br /&gt;2. Declare TestProperty attributes with our test data. null, int, strings, etc&lt;br /&gt;3. Pass in the object we are going to unit test and values get assigned in the method SetPropsToAttribValues&lt;br /&gt;4. Run test&lt;br /&gt;5. Assert return codes&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:js"&gt;&lt;br /&gt;&lt;br /&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt;/// A unit test method providing a sample way to automatically assign&lt;br /&gt;/// test attributes to Properties in an object&lt;br /&gt;///&amp;lt;/summary&amp;gt;&lt;br /&gt;[TestMethod()]&lt;br /&gt;[TestProperty(&amp;quot;TestProperty1&amp;quot;, &amp;quot;Something&amp;quot;)]&lt;br /&gt;[TestProperty(&amp;quot;TestProperty2&amp;quot;, &amp;quot;SomethingElse&amp;quot;)]&lt;br /&gt;public void SomeUnitTestMethod&lt;br /&gt;{&lt;br /&gt;    SomeCustomObject testObject = new SomeCustomObject();&lt;br /&gt;    //This call will automatically set testObject.TestProperty1 to &amp;quot;Something&amp;quot; for ex.&lt;br /&gt;    SetPropsToAttribValues (testObject);&lt;br /&gt;    int retVal = testObject.SomeMethod();&lt;br /&gt;&lt;br /&gt;    Assert.IsTrue(retVal==0, &amp;quot;Return value was unexpected:&amp;quot; + retVal.ToString());&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt;/// Uses reflection to look at the calling method's TestProperty attributes&lt;br /&gt;/// and will set values on properties matching those attribute names with the attribute values.&lt;br /&gt;/// Property names are not case sensitive for this implementation to help avoid unit test typos.&lt;br /&gt;/// &amp;lt;/summary&amp;gt;&lt;br /&gt;/// &amp;lt;param name=&amp;quot;obj&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;&lt;br /&gt;[MethodImpl(MethodImplOptions.NoInlining)]&lt;br /&gt;private void SetPropsToAttribValues(object obj)&lt;br /&gt;{&lt;br /&gt;    //Get name of attribute. if it exists and value != null set it. &lt;br /&gt;    Type t = GetType();&lt;br /&gt;    Type attributeType = typeof(TestPropertyAttribute);&lt;br /&gt;    //hop up the stack frame to the caller so we can get its attributes&lt;br /&gt;    object[] attributes = new System.Diagnostics.StackFrame(1, false).GetMethod().GetCustomAttributes(attributeType, false);&lt;br /&gt;&lt;br /&gt;    for (int i = 0; i &amp;lt;= attributes.GetUpperBound(0); i++)&lt;br /&gt;    {&lt;br /&gt;        string propertyName = ((TestPropertyAttribute)attributes[i]).Name.ToLower();&lt;br /&gt;&lt;br /&gt;        PropertyInfo[] properties = obj.GetType().GetProperties();&lt;br /&gt;        foreach (PropertyInfo pi in properties)&lt;br /&gt;        {&lt;br /&gt;//Made to be not case sensitive to help avoid test script typos.&lt;br /&gt;            if (pi.Name.ToLower() == propertyName)&lt;br /&gt;            {&lt;br /&gt;                pi.SetValue(obj, ((TestPropertyAttribute)attributes[i]).Value, null);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt;/// Looks up attribute values for a particular method. They are used here for sending in values for the test cases.&lt;br /&gt;/// This reads all [TestProperty] attribute values&lt;br /&gt;/// &amp;lt;/summary&amp;gt;&lt;br /&gt;/// &amp;lt;param name=&amp;quot;attributeName&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;&lt;br /&gt;/// &amp;lt;returns&amp;gt;attribute value as specified in [TestProperty] attribute, throws an exception if not found.&amp;lt;/returns&amp;gt;&lt;br /&gt;[MethodImpl(MethodImplOptions.NoInlining)]&lt;br /&gt;private object GetAttributeValue(string attributeName)&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;    Type t = GetType();&lt;br /&gt;    Type attributeType = typeof(TestPropertyAttribute);&lt;br /&gt;    //hop up the stack frame to the caller so we can get its attributes&lt;br /&gt;    object[] attributes = new System.Diagnostics.StackFrame(1, false).GetMethod().GetCustomAttributes(attributeType, false);&lt;br /&gt;&lt;br /&gt;    for (int i = 0; i &amp;lt;= attributes.GetUpperBound(0); i++)&lt;br /&gt;    {&lt;br /&gt;        if (((TestPropertyAttribute)attributes[i]).Name.ToLower() == attributeName.ToLower())&lt;br /&gt;        {&lt;br /&gt;            return ((TestPropertyAttribute)attributes[i]).Value;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    throw new Exception(&amp;quot;Could not find attribute &amp;quot; + attributeName);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-7366350360100497277?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/7366350360100497277/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2009/05/easier-way-to-track-parameters-in-unit.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/7366350360100497277'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/7366350360100497277'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2009/05/easier-way-to-track-parameters-in-unit.html' title='An easier way to track parameters in unit testing for Visual Studio (mstext.exe)'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-7422261593732807395</id><published>2009-05-18T21:23:00.000-07:00</published><updated>2009-05-22T22:33:07.477-07:00</updated><title type='text'>The Nagle algorithm - speeding up tcp, changing protocols, rewriting your app, or just dealing with it?</title><content type='html'>First - what is the nagle algorithm and its purpose?&lt;br /&gt;&lt;br /&gt;The Nagle algorithm's basic idea is to queue up smaller amounts data and do not send it if there is current sent data waiting to be confirmed. If we are sending a large packet, then there is no effect. The idea is to prevent small packets and the header information on each packet from clogging the network if we can queue some of that data (since we're waiting for a send acknowledgment anyways) and send it once the pending send has been confirmed.&lt;br /&gt;&lt;br /&gt;More details can be found at:&lt;br /&gt;&lt;br /&gt;http://en.wikipedia.org/wiki/Nagle%27s_algorithm&lt;br /&gt;&lt;br /&gt;The magic value here is MSS - Maximum Segment Size and this specifies the maximum size that can be transmitted. Upon establishing &lt;br /&gt;&lt;br /&gt;There's a simple way to test the effects of Nagle and how it compares between using sockets and remoting. Remoting can wrap your data in headers, thus &lt;br /&gt;RFC896&lt;br /&gt;http://www.ietf.org/rfc/rfc0896.txt?number=896&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I find myself at times saying "Nagle is bad in X scenario, RDP for instance where a user expects near real time response", so at times it does make sense to turn it off. &lt;br /&gt;&lt;br /&gt;There is a great article on this subject at:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://msmvps.com/blogs/alunj/archive/2006/05/08/94038.aspx"&gt;http://msmvps.com/blogs/alunj/archive/2006/05/08/94038.aspx&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In it, Alun Jones makes a great point. Basically if you have gains because Nagle is turned off either your application is broke or the protocol is broke. Take RDP for example. A user expects a real time response. Since we are currently in a TCP/IP connected world, TCP/IP is basically a must for a remote connection. Therefore, the protocol is broke (for our required use.. although I hesitate to use the word broke, rather than unfitting)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;A simple test to see the effects can be duplicated by the following scenario.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;1. Use .Net remoting and make a simple method call that takes a string, but does nothing with it. (remoting in Singleton mode so you have one instance of the class responding to requests) &lt;br /&gt;2. Simple  socket call to send a small string (less than 20&lt;br /&gt; bytes) to a method.&lt;br /&gt;&lt;br /&gt; The remoting call is significantly faster (107 compared to&lt;br /&gt; the sockets 58 requests per second in one test)&lt;br /&gt;&lt;br /&gt; Sockets are simple on the receive end (and the send):&lt;br /&gt;&lt;br /&gt; Socket ss = new&lt;br /&gt; Socket(AddressFamily.InterNetwork,SocketType.Stream,&lt;br /&gt; ProtocolType.Tcp);&lt;br /&gt; ss.Bind(EndPoint);&lt;br /&gt; ss.Listen(100); //100 in the backlog connection queue&lt;br /&gt; while(true)&lt;br /&gt; {&lt;br /&gt;         Socket sock = ss.Accept();&lt;br /&gt;         byte[] read = new byte[1024];&lt;br /&gt;         int bytes = sock.Receive(read, 1024, 0);&lt;br /&gt;         //Ideally you would spawn off another thread here to handle .. results are similiar, this is done here for simplicity&lt;br /&gt;         string messagefromclient =  System.Text.Encoding.ASCII.GetString(read,0,bytes);&lt;br /&gt;         sock.Close();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;Lets say in this scenario this is a mission critical authentication application that requires high throughput. The login packet may be extremely small. Having Nagle enabled can slow this down incredibly. Certain applications may say this is acceptable - for instance game development. A small movement on the screen usually equates to a small packet of data to be sent. Waiting for the maximum segment size to be reached before transmitting means data can just be queued up if a current acknowledgment is pending. In the fast paced realm of gaming where near instantaneous response is required, Nagle can slow the game down significantly. In this case it seems Alun Jones would say the protocol is broken, as disabling Nagle yields a good benefit. One could argue here then why even use TCP? Why not just use UDP? UDP after all doesn't concern us with packet size issues. It just sends. Theres no concept of connection, it just goes there. But.. will it arrive? Possibly. Do you know that you receive packets in order? NO!&lt;br /&gt;&lt;br /&gt;You have to write something into your system to handle these issues, that's the tradeoffs with UDP, and mostly I'd say this pertains to games.&lt;br /&gt;&lt;br /&gt;There is an excellent article on this for those that are interested in reading more (including more info on sequencing packets)&lt;br /&gt;http://gafferongames.com/networking-for-game-programmers/udp-vs-tcp/&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;With all this said, if you have to have data integrity, order, and connections, then stay with tcp. If you cannot accept the performance hit, then either switch protocols or accept the performance hit you will take to guarantee your data's order (without writing your own management routines with udp as outlines in the above url)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-7422261593732807395?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/7422261593732807395/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2009/05/nagle-algorithm-speeding-up-tcp.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/7422261593732807395'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/7422261593732807395'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2009/05/nagle-algorithm-speeding-up-tcp.html' title='The Nagle algorithm - speeding up tcp, changing protocols, rewriting your app, or just dealing with it?'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-6408373406305286859</id><published>2009-02-08T19:48:00.000-08:00</published><updated>2009-02-09T18:45:14.772-08:00</updated><title type='text'>Cant use temp tables in stored procs with Sql Reporting Services 2005 Report Wizard</title><content type='html'>You receive something like:&lt;br /&gt;Invalid object name '#Temp'&lt;br /&gt;&lt;br /&gt;The wizard sets "SET FMTONLY ON" before running your procedure - which tells sql server to run the query without processing the results, and just sent over the data format (ie columns, types)&lt;br /&gt;&lt;br /&gt;You can add "SET FMTONLY OFF" to the top of your procedure to bypass the wizard check. &lt;br /&gt;http://msdn.microsoft.com/en-us/library/ms173839.aspx&lt;br /&gt;&lt;br /&gt;After you do the wizard, you can remove this change.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-6408373406305286859?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/6408373406305286859/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2009/02/cant-use-temp-tables-in-stored-procs.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/6408373406305286859'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/6408373406305286859'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2009/02/cant-use-temp-tables-in-stored-procs.html' title='Cant use temp tables in stored procs with Sql Reporting Services 2005 Report Wizard'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-3593856314090597293</id><published>2009-02-08T17:46:00.000-08:00</published><updated>2009-02-08T19:48:50.128-08:00</updated><title type='text'>Select Top X from Grouped Results</title><content type='html'>Every now and then because of a particular design I need to get top X number from grouped results.&lt;br /&gt;&lt;br /&gt;In this particular case, each record has a status history with it and the status changes are tracked in a related history table.&lt;br /&gt;In this case we'll call it &lt;br /&gt;Job&lt;br /&gt;JobStatusHistory&lt;br /&gt;&lt;br /&gt;I want the most recent status from the JobStatusHistory, but there can be many status changes per record. Luckily the solution is easy (there are others including cursor based ways, but this is a fairly elegant solution)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;We can use the little known row_number over(parition by XX) t-sql command&lt;br /&gt;It provides great functionality but you really don't see it too much.&lt;br /&gt;&lt;br /&gt;This gets me all results plus a field named 'rownum' (you can call it anything since I'm just aliasing it here as another field)&lt;br /&gt;&lt;br /&gt;select id,row_number()over(partition by jobid order by createddate desc) rownum&lt;br /&gt;from jobstatushistory&lt;br /&gt;&lt;br /&gt;So having numbered results, we can use this as a where clause to get each result.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;select jobid,newstatus  from(&lt;br /&gt;select jobid,newstatus,row_number()over(partition by jobid order by createddate desc) row_num&lt;br /&gt;from jobstatushistory) t&lt;br /&gt;where row_num=1&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This will number the rows and get only the first one from each group (in this case 'grouped' is ordered by created date, rather than an actual 'group by' clause.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-3593856314090597293?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/3593856314090597293/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2009/02/select-top-x-from-grouped-results.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/3593856314090597293'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/3593856314090597293'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2009/02/select-top-x-from-grouped-results.html' title='Select Top X from Grouped Results'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-2161055625791476454</id><published>2009-02-07T14:32:00.001-08:00</published><updated>2009-02-07T14:33:35.626-08:00</updated><title type='text'>more sql 2k5 items</title><content type='html'>While messing around with authentication options I receieved:&lt;br /&gt;&lt;br /&gt;Server Error in '/Reports' Application.&lt;br /&gt;Object reference not set to an instance of an object.&lt;br /&gt;Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.&lt;br /&gt;&lt;br /&gt;Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.&lt;br /&gt;&lt;br /&gt;Source Error:&lt;br /&gt;&lt;br /&gt;An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.&lt;br /&gt;&lt;br /&gt;Stack Trace:&lt;br /&gt;&lt;br /&gt;[NullReferenceException: Object reference not set to an instance of an object.]&lt;br /&gt;   Microsoft.ReportingServices.UI.GlobalApp.Application_AuthenticateRequest(Object sender, EventArgs e) +73&lt;br /&gt;   System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +79&lt;br /&gt;   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean&amp; completedSynchronously) +176&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Version Information: Microsoft .NET Framework Version:2.0.50727.1433; ASP.NET Version:2.0.50727.1433 &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;To solve this: Change the asp.net configuration to be windows authentication rather than none on the reportmanager virtual directory (asp.net tab - edit configuration and change auth there).&lt;br /&gt;This was my own fault but in case anyone else does the same thing while playing around with authentication options in reporting services this may help : )&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-2161055625791476454?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/2161055625791476454/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2009/02/more-sql-2k5-items.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/2161055625791476454'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/2161055625791476454'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2009/02/more-sql-2k5-items.html' title='more sql 2k5 items'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-7917687619579578469</id><published>2009-02-07T14:29:00.000-08:00</published><updated>2009-02-07T14:31:37.374-08:00</updated><title type='text'>Sql Reporting Services 2005 - The current action cannot be completed because the user data source credentials that are required to execute this report</title><content type='html'>Received: The current action cannot be completed because the user data source credentials that are required to execute this report are not stored in the report server database. (rsInvalidDataSourceCredentialSetting)&lt;br /&gt;&lt;br /&gt;This occured when using a report with an expression based connect string to connect to sql server. &lt;br /&gt;The report data source is embedded and set to "No Credentials"&lt;br /&gt;It works locally on my Vista machine/IIS 7 but on Windows 2003 R2 IIS 6 it does not.&lt;br /&gt;So as per Microsoft on:&lt;br /&gt;http://msdn.microsoft.com/en-us/library/ms160330.aspx&lt;br /&gt;&lt;br /&gt;You can configure a data source connection to use no credentials. Microsoft recommends that you always use credentials to access a data sources; using no credentials is not advised. However, you may choose to run a report with no credentials in the following cases:&lt;br /&gt;&lt;br /&gt;    * The remote data source does not require credentials.&lt;br /&gt;    * The credentials are passed in the connection string (recommended only for secure connections).&lt;br /&gt;    * The report is a subreport that uses the credentials of the parent report.&lt;br /&gt;&lt;br /&gt;Under these conditions, the report server connects to a remote data source using the unattended execution account that you must define in advance. Because the report server does not connect to a remote server using its service credentials, you must specify an account that the report server can use to make the connection. For more information about creating this account, see Configuring the Unattended Execution Account.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So go into the reporting services config tool and set an execution account, this worked for me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-7917687619579578469?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/7917687619579578469/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2009/02/sql-reporting-services-2005-current.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/7917687619579578469'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/7917687619579578469'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2009/02/sql-reporting-services-2005-current.html' title='Sql Reporting Services 2005 - The current action cannot be completed because the user data source credentials that are required to execute this report'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-4950277681667210575</id><published>2009-01-31T00:13:00.000-08:00</published><updated>2009-02-02T21:57:00.056-08:00</updated><title type='text'>Sql Reporting Services 2005 - The request failed with HTTP status 401: Unauthorized.</title><content type='html'>When calling a render method for a report ala:&lt;br /&gt;&lt;br /&gt;result = ws.Render(report, format, historyid, devinfo, parameters, credentials, showhide, out encoding, out mimetype, out reporthistoryparams,&lt;br /&gt;out warnings, out streamid);&lt;br /&gt;&lt;br /&gt;you receive:&lt;br /&gt;&lt;br /&gt;The request failed with HTTP status 401: Unauthorized.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;[WebException: The request failed with HTTP status 401: Unauthorized.]&lt;br /&gt;   System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall) +551137&lt;br /&gt;   System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters) +204&lt;br /&gt;   TestReportingServices.localhost.ReportingService.Render(String Report, String Format, String HistoryID, String DeviceInfo, ParameterValue[] Parameters, DataSourceCredentials[] Credentials, String ShowHideToggle, String&amp; Encoding, String&amp; MimeType, ParameterValue[]&amp; ParametersUsed, Warning[]&amp; Warnings, String[]&amp; StreamIds) in c:\Projects\BidTrackerReporting\TestReportingServices\Web References\localhost\Reference.cs:1426&lt;br /&gt;   TestReportingServices._Default.btnGenerateReport_Click(Object sender, EventArgs e) in c:\Projects\BidTrackerReporting\TestReportingServices\Default.aspx.cs:80&lt;br /&gt;   System.Web.UI.WebControls.Button.OnClick(EventArgs e) +105&lt;br /&gt;   System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +107&lt;br /&gt;   System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +7&lt;br /&gt;   System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +11&lt;br /&gt;   System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +33&lt;br /&gt;   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1746&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Line 1424:        [return: System.Xml.Serialization.XmlElementAttribute("Result", DataType="base64Binary")]&lt;br /&gt;Line 1425:        public byte[] Render(string Report, string Format, string HistoryID, string DeviceInfo, ParameterValue[] Parameters, DataSourceCredentials[] Credentials, string ShowHideToggle, out string Encoding, out string MimeType, out ParameterValue[] ParametersUsed, out Warning[] Warnings, out string[] StreamIds) {&lt;br /&gt;Line 1426:            object[] results = this.Invoke("Render", new object[] {&lt;br /&gt;Line 1427:                        Report,&lt;br /&gt;Line 1428:                        Format,&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The wrong (or none) credentials are specified to connect to the PHYSICAL files on your system (not the database). If using a console application (or windows form) this may work ok for you, but switching to asp.net it may fail. Your current credentials will be passed over in the interactive console or windows form application so you may not have a problem there, but in asp.net will be running under the identity of either the app pool, network service, or IUSR_MachineName and thus won't have enough permissions. Thankfully, the solution is easy though. I've seen all sorts of articles for using custom permissions, but it's straight forward, just add new network credentials to the proxy class that is generated for the webservice&lt;br /&gt;/reportserver/reportservice.asmx&lt;br /&gt;&lt;br /&gt;just add this to an instance of your proxy class (of course filling in your details:&lt;br /&gt;ws.Credentials = new System.Net.NetworkCredential("your login", "your password", "your domain");&lt;br /&gt;&lt;br /&gt;Now, there is another way around this. In IIS (I'll use IIS 7 here since that is what is on my box) you can just enable permissions for a particular user on the files. In one case, you can make it generic, and add permissions for the IUSR account for read access to the reportserver folder. &lt;br /&gt;Set these permissions on C:\Program Files\Microsoft SQL Server\MSSQL.4\Reporting Services\ReportServer   (or whatever folder it is on your system)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Then in IIS, enable anonymous access for the folder.&lt;br /&gt;I tried setting "physical path credentials" in IIS 7 as well, then the application wouldn't have to pass them in, however then you still have the ability for users to view /reportserver, but it didn't work as would be expected - ie access still denied.&lt;br /&gt;&lt;br /&gt;so as for allowing all IUSR - I DONT RECOMMEND THIS. &lt;but you can if you really want to&gt;&lt;br /&gt;&lt;br /&gt;Why?&lt;br /&gt;&lt;br /&gt;1. if you do not disable the reportserver for outside access then ANYONE can view at least some details about your reports by simply navigating to https://yourserver/reportserver (although they may not be able to run your reports if you require prompting for credentials or dont store any credendtials and expect them to be passed in as part of the app)&lt;br /&gt;2. Why not just include the account in the code your application uses to access the reports?&lt;br /&gt;3. Who wants the risk when dealing with reports?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;but if you really want to try this and enable it only for local access (this may be just fine for your environment if you are running this system on a separate network that a webserver in a dmz accesses and the report server is not accessible to the outside world. Although if the web server is compromised then an attacker could access the report server. As of now in Vista's IIS 7 UI, you cannot set the ip restriction - they left the UI element for it out. If you want to set this in Vista, you need to install IIS 7 Admin Pack. You MUST FIRST INSTALL SP1 for Vista otherwise you can cause the admin console to fail. There's a nice blog about the pack at:&lt;br /&gt;http://blogs.msdn.com/carlosag/archive/2008/03/24/IISAdminPackRequestFiltering.aspx&lt;br /&gt;The module in question is IpRestrictionModule&lt;br /&gt;for the admin pack see:&lt;br /&gt;http://www.iis.net/downloads&lt;br /&gt;http://www.iis.net/downloads/default.aspx?tabid=34&amp;g=6&amp;i=1682&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If you want to limit to a particular address in IIS see:&lt;br /&gt;--------------------------------&lt;br /&gt;http://technet.microsoft.com/en-us/library/cc730889.aspx&lt;br /&gt;--------------------------------&lt;br /&gt;To configure an IPv4 address restriction for the management service &lt;br /&gt;Open IIS Manager. For information about opening IIS Manager, see IIS 7.0: Open IIS Manager.&lt;br /&gt;&lt;br /&gt;In the Connections pane, click the server node in the tree.&lt;br /&gt;&lt;br /&gt;In Features View, double-click Management Service.&lt;br /&gt;&lt;br /&gt;On the Management Service page, in the Actions pane, click Stop to stop the management service.&lt;br /&gt;&lt;br /&gt;Select the Enable remote connections box.&lt;br /&gt;&lt;br /&gt;Under IPv4 Address Restrictions, use one of the following procedures:&lt;br /&gt;&lt;br /&gt;Click Allow to allow an IPv4 address or range of IPv4 addresses to connect to the management service.&lt;br /&gt;&lt;br /&gt;Click Deny to deny an IPv4 address or range of IPv4 addresses from connecting to the management service.&lt;br /&gt;&lt;br /&gt;In the Add Allow Connection Rule dialog box or Add Deny Connection Rule dialog box, use one of the following procedures, and then click OK:&lt;br /&gt;&lt;br /&gt;To allow or deny a specific IP address, click Specific IPv4 address, and then type the IPv4 address in the box.&lt;br /&gt;&lt;br /&gt;To allow or deny a range of IP addresses, click IPv4 address range, type an IPv4 address in the box, and then type a subnet mask in the Subnet mask box.&lt;br /&gt;&lt;br /&gt;In the Actions pane, click Apply and then click Start.&lt;br /&gt;&lt;br /&gt;---------------------------------------------&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now for the better solution, try the following code. &lt;br /&gt;This was just from some local testing, but should work:&lt;br /&gt;&lt;br /&gt;byte[] result;&lt;br /&gt;string report = "/SomeCustomReportFolder/SomeReport";&lt;br /&gt;localhost.DataSourceCredentials[] credentials = null;&lt;br /&gt;string showHide = null;&lt;br /&gt;string encoding="";&lt;br /&gt;string mimeType="";&lt;br /&gt;string format = "PDF";&lt;br /&gt;string historyId = null;&lt;br /&gt;string devinfo = "";&lt;br /&gt;localhost.Warning[] warnings = null;&lt;br /&gt;localhost.ParameterValue[] reportHistoryParams = null;&lt;br /&gt;string[] streamId = null;&lt;br /&gt;localhost.SessionHeader sh = new localhost.SessionHeader();&lt;br /&gt;&lt;br /&gt;localhost.ReportingService ws = new TestReportingServices.localhost.ReportingService();&lt;br /&gt;ws.SessionHeaderValue = sh;&lt;br /&gt;ws.Credentials = new System.Net.NetworkCredential("your login", "your password", "your domain");&lt;br /&gt;&lt;br /&gt;localhost.ParameterValue[] parameters =  { new TestReportingServices.localhost.ParameterValue() };&lt;br /&gt;parameters[0].Name = "parameter name"; //Case SENSITIVE!!!&lt;br /&gt;parameters[0].Value = "parameter value";&lt;br /&gt;result = ws.Render(report, format, historyid, devinfo, parameters, credentials, showhide, out encoding, out mimetype, out reporthistoryparams,&lt;br /&gt;out warnings, out streamid);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;enjoy : )&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-4950277681667210575?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/4950277681667210575/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2009/01/sql-reporting-services-2005-request.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/4950277681667210575'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/4950277681667210575'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2009/01/sql-reporting-services-2005-request.html' title='Sql Reporting Services 2005 - The request failed with HTTP status 401: Unauthorized.'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-2813128730945708695</id><published>2009-01-27T18:17:00.000-08:00</published><updated>2009-01-27T21:13:24.299-08:00</updated><title type='text'>Fixing Sql Reporting Services for FireFox</title><content type='html'>Sql Reporting Services has an issue with firefox in which reports will show about one inch tall in the report viewer. There is an easy fix for this, but it seems to depend on the version of firefox.&lt;br /&gt;It seems to be the support of attributes on IFrame in firefox.&lt;br /&gt;I'm running on 3.05 and the following works for me:&lt;br /&gt;&lt;br /&gt;Load&lt;br /&gt;C:\Program Files\Microsoft SQL Server\MSSQL.3\Reporting Services\ReportServer\Pages\reportviewer.aspx&lt;br /&gt;&lt;br /&gt;make sure this is in the body tag (prob is by default):&lt;br /&gt;&lt;br /&gt;&amp;lt;body style="margin: 0px; overflow: auto"&amp;gt;&lt;br /&gt;&lt;br /&gt;and the report viewer line should have this added to it: style="display:table;"&lt;br /&gt;so:&lt;br /&gt;&amp;lt;RS:ReportViewerHost style="display:table;"  ID="ReportViewerControl" runat="server" /&amp;gt;&lt;br /&gt;&lt;br /&gt;Some say add one of the following to the ReportingServices.css, however that did not work for me. The above fix did however.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;.DocMapAndReportFrame&lt;br /&gt;{   &lt;br /&gt;    min-height: 660px;&lt;br /&gt;    min-width: 1280px;&lt;br /&gt;}&lt;br /&gt;.MenuBarBkGnd&lt;br /&gt;{&lt;br /&gt;   min-width:1000px;&lt;br /&gt;}&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-2813128730945708695?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/2813128730945708695/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2009/01/fixing-sql-reporting-services-for.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/2813128730945708695'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/2813128730945708695'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2009/01/fixing-sql-reporting-services-for.html' title='Fixing Sql Reporting Services for FireFox'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-6014102536044546443</id><published>2009-01-25T02:46:00.001-08:00</published><updated>2009-01-25T02:53:24.842-08:00</updated><title type='text'>Making sure you don't process page_load code when doing ajax</title><content type='html'>When you perform an async call using ajax, you will cause page_load to fire.&lt;br /&gt;There are two ways around this I use.&lt;br /&gt;&lt;br /&gt;During ajax, we are having a postback, so Page.IsPostBack is true, and also ScriptManager.IsInAsyncPostBack is true as well. These two items generally point to ajax.&lt;br /&gt;if (!Page.IsPostBack &amp;amp;&amp;amp; !ScriptManager.IsInAsyncPostBack)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If you want to be certain - then you can name your controls with a particular prefix, for example "ajax" so a button could be ajaxLoadDynamicData.&lt;br /&gt;&lt;br /&gt;In your Page_Load:&lt;br /&gt;&lt;br /&gt;Control ctl = PostBackInformation.GetPostBackControl(this.Page);&lt;br /&gt;if ((ctl != null) &amp;amp;&amp;amp; (ctl.ID.IndexOf("ajax", 0, StringComparison.InvariantCultureIgnoreCase) &gt; -1))&lt;br /&gt;{&lt;br /&gt;return;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;PostBackInformation.GetPostBackControl is not built in - I don't recall where I got it or customized it from (there are several references to it on the net)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;public static System.Web.UI.Control GetPostBackControl(System.Web.UI.Page page)&lt;br /&gt;{&lt;br /&gt;Control control = null;&lt;br /&gt;string ctrlName = page.Request.Params["__EVENTTARGET"];&lt;br /&gt;if (ctrlName != null &amp;amp;&amp;amp; ctrlName != String.Empty)&lt;br /&gt;{&lt;br /&gt;control = page.FindControl(ctrlName);&lt;br /&gt;}&lt;br /&gt;// if __EVENTTARGET is null, the control is a button type and we need to&lt;br /&gt;// iterate over the form collection to find it&lt;br /&gt;else&lt;br /&gt;{&lt;br /&gt;string ctrlStr = String.Empty;&lt;br /&gt;Control c = null;&lt;br /&gt;foreach (string ctl in page.Request.Form)&lt;br /&gt;{&lt;br /&gt;// handle ImageButton controls ...&lt;br /&gt;if (ctl.EndsWith(".x") ctl.EndsWith(".y"))&lt;br /&gt;{&lt;br /&gt;ctrlStr = ctl.Substring(0, ctl.Length - 2);&lt;br /&gt;c = page.FindControl(ctrlStr);&lt;br /&gt;}&lt;br /&gt;else&lt;br /&gt;{&lt;br /&gt;c = page.FindControl(ctl);&lt;br /&gt;}&lt;br /&gt;if (c is System.Web.UI.WebControls.Button&lt;br /&gt;c is System.Web.UI.WebControls.ImageButton)&lt;br /&gt;{&lt;br /&gt;control = c;&lt;br /&gt;break;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;return control;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;so depending on your scenario you can detect when doing a postback from an ajax (or any) control and ignore processing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-6014102536044546443?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/6014102536044546443/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2009/01/makign-sure-you-dont-process-pageload.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/6014102536044546443'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/6014102536044546443'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2009/01/makign-sure-you-dont-process-pageload.html' title='Making sure you don&apos;t process page_load code when doing ajax'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-8577578098825337623</id><published>2009-01-24T00:38:00.000-08:00</published><updated>2009-01-24T00:40:28.174-08:00</updated><title type='text'>Generating 'Wait' Images</title><content type='html'>Ever want a neat image on your page to display during some wait operation (ie ajax)?&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_iMjR6GifR0g/SXrT2ZOYd2I/AAAAAAAAAGQ/sH6C1x-op64/s1600-h/progress.gif"&gt;&lt;img style="cursor: pointer; width: 32px; height: 32px;" src="http://2.bp.blogspot.com/_iMjR6GifR0g/SXrT2ZOYd2I/AAAAAAAAAGQ/sH6C1x-op64/s400/progress.gif" alt="" id="BLOGGER_PHOTO_ID_5294777243365046114" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Go to: &lt;br /&gt;http://www.ajaxload.info&lt;br /&gt;&lt;br /&gt;and you can generate one for free. nice!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-8577578098825337623?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/8577578098825337623/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2009/01/generating-wait-images.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/8577578098825337623'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/8577578098825337623'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2009/01/generating-wait-images.html' title='Generating &apos;Wait&apos; Images'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_iMjR6GifR0g/SXrT2ZOYd2I/AAAAAAAAAGQ/sH6C1x-op64/s72-c/progress.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-6438717546770186011</id><published>2009-01-22T22:36:00.000-08:00</published><updated>2009-01-22T23:11:46.790-08:00</updated><title type='text'>Enabling POP3/IMAP in Exchange Server 2007</title><content type='html'>There are plenty of articles on the net for this, but these are my notes, mostly for my own reference.. and if someone else runs into the same issues I do.&lt;br /&gt;&lt;br /&gt;Scenario: Exchange 2007 currently only used via OWA (outlook web access). Users outside of the network want to use the full functionality of Exchange.&lt;br /&gt;&lt;br /&gt;&lt;img src="file:///C:/Users/Adam/AppData/Local/Temp/moz-screenshot.jpg" alt="" /&gt;&lt;img src="file:///C:/Users/Adam/AppData/Local/Temp/moz-screenshot-1.jpg" alt="" /&gt;&lt;br /&gt;&lt;br /&gt;error: Exchange 2007 POP3 "Connection not valid in this state"&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;1. Start the microsoft exchange pop3 and imap service. set the service state to automatic. This can be done in the exchange shell, or just load it up in services.msc and set the service there. Start them both.&lt;br /&gt;Make sure the ports are set (should be by default) in the Exchange Management Console&lt;br /&gt;server configuration - client access - pop3 and imap4&lt;br /&gt;&lt;br /&gt;2. Make sure IMap and/or Pop3 its set on the user's account. In Exhange System Manager, you can set a user's avaialble access (OWA/IMAP/POP3, etc)&lt;br /&gt;3. Test it out via a telnet session. As of this point - it will fail since by default plain text passwords is not allowed. you must use ssl,tls.&lt;br /&gt;The error you will receive when you try a telnet session is: "Command is not valid in this state"&lt;span id="ctl00_MainContentPlaceholder_ctl01_ctl00_lblEntry"&gt;&lt;span style="color: rgb(51, 51, 51);font-size:10;"  lang="EN"&gt;&lt;span style="font-family:Calibri;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;So: enable plain text and test through telnet.&lt;br /&gt;&lt;br /&gt;from an exchange command shell run:  get-PopSettings&lt;br /&gt;&lt;br /&gt;UnencryptedOrTLSBindings  SSLBindings   LoginType     X509CertificateName&lt;br /&gt;------------------------  -----------   ---------     -------------------&lt;br /&gt;{0000:0000:0000:0000:0... {0000:0000... SecureLogin   lois&lt;br /&gt;&lt;br /&gt;Note the LoginType us SecureLogin. In this simple configuration we will allow plain text login.&lt;br /&gt;Run this command in the Exchange Shell:&lt;br /&gt;Set-PopSettings -LoginType PlainTextLogin&lt;br /&gt;If you don't do this, you will&lt;br /&gt;Restart the exchange pop3 service. You can do the same for imap - set the login and restart the service.&lt;br /&gt;&lt;br /&gt;Then try something like this (for pop3):&lt;br /&gt;telnet localhost 110&lt;br /&gt;&lt;br /&gt;type these commands (replace with your info)&lt;br /&gt;user test&lt;br /&gt;pass sometestpwd&lt;br /&gt;stat&lt;br /&gt;list&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;+OK QPOP (version 2.53) at myserver.local.com  starting.&lt;br /&gt;user test&lt;br /&gt;+OK Password required for test.&lt;br /&gt;pass sometestpwd&lt;br /&gt;+OK testhas 2 messages (784 octets).&lt;br /&gt;stat&lt;br /&gt;+OK 2 784&lt;br /&gt;list&lt;br /&gt;+OK 2 messages (784 octets)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;ok - good. pop3 is working.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;4. enable firewall port 110 to allow remote clients in and test remotely via a setup in outlook.&lt;br /&gt;&lt;br /&gt;No problem so far.. it is all working ok. I then try to use ssl, tls, secure password authentication (spa) and even with ports open it fails. I did get a message about the cert on the server and accepted it:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_iMjR6GifR0g/SXlthUorhpI/AAAAAAAAAGI/uA_9otCRK_M/s1600-h/security.jpg"&gt;&lt;img style="cursor: pointer; width: 400px; height: 329px;" src="http://4.bp.blogspot.com/_iMjR6GifR0g/SXlthUorhpI/AAAAAAAAAGI/uA_9otCRK_M/s400/security.jpg" alt="" id="BLOGGER_PHOTO_ID_5294383256193173138" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;After that I could not make a valid connection. I am still investigating that one.&lt;br /&gt;Similiar errors receives are:&lt;br /&gt;Log onto incoming mail server (IMAP): General authentication failed. None of the authentication methods supported by your IMAP server (if any) are supported on this computer.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-6438717546770186011?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/6438717546770186011/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2009/01/enabling-pop3imap-in-exchange-server.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/6438717546770186011'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/6438717546770186011'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2009/01/enabling-pop3imap-in-exchange-server.html' title='Enabling POP3/IMAP in Exchange Server 2007'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_iMjR6GifR0g/SXlthUorhpI/AAAAAAAAAGI/uA_9otCRK_M/s72-c/security.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-1995466286239005556</id><published>2009-01-19T23:34:00.000-08:00</published><updated>2009-01-26T21:40:25.706-08:00</updated><title type='text'>More issues with Sql Reporting Services - The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel</title><content type='html'>Problem: Installed on a new server, and cannot go to:&lt;br /&gt;&lt;br /&gt;&lt;a href="https://localhost/reports"&gt;https://localhost/reports&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I receive: The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.&lt;br /&gt;&lt;br /&gt;Odd, as ssl is ok (and the root ca authority which is the server itself has been added as a trusted root on the system).&lt;br /&gt;&lt;br /&gt;This is interesting in my case, the web service identity wasn't set and it wouldn't allow me to set it to the "ReportServer" app pool, I received an error&lt;br /&gt;&lt;br /&gt;ReportServicesConfigUI.WMIProvider.WMIProviderException: A virtual directory must first be created before performing this operation.&lt;br /&gt;at ReportServicesConfigUI.WMIProvider.RSReportServerAdmin.SetWebServiceIdentity(String applicationPool)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I tried to apply default settings and received:&lt;br /&gt;&lt;br /&gt;System.Runtime.InteropServices.COMException (0x80004005) at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo) at System.Management.ManagementObject.InvokeMethod(String methodName, ManagementBaseObject inParameters, InvokeMethodOptions options) at ReportServicesConfigUI.WMIProvider.RSReportServerAdmin.ResetVirtualDirectoryMappings()&lt;br /&gt;&lt;br /&gt;awesome.&lt;br /&gt;&lt;br /&gt;Since this is a shared server, I tried to create a new virtual directory so I could use a specific virtual dir and app pool I'd create. Upon giving a name to create, the config tool crashed.&lt;br /&gt;&lt;br /&gt;most awesome.&lt;br /&gt;&lt;br /&gt;Upon loading the tool and trying to set web service identity again, it let me do it for the Report Server, but failed for the Report Manager with:&lt;br /&gt;&lt;br /&gt;ReportServicesConfigUI.WMIProvider.WMIProviderException: A virtual directory must first be created before performing this operation.&lt;br /&gt;at ReportServicesConfigUI.WMIProvider.RSReportManagerAdmin.SetReportManagerIdentity(String applicationPool)&lt;br /&gt;&lt;br /&gt;yes, a virtual directory indeed exists and somehow it doesn't recognize it.&lt;br /&gt;&lt;br /&gt;ok.. lets go back a bit. Im not sure when sp2 was installed on this machine and I have seen issues with sp2 having to be installed again, but thats usually a different error along the lines of:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Sql errorystem.Data.SqlClient.SqlException: Could not find stored procedure 'GetDBVersion'. at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;So I just deleted the virtual directories from IIS for ReportServer and Reports, recreated them in the config tool, and chi was restored to the universe.&lt;br /&gt;&lt;br /&gt;installed the certificate to:&lt;br /&gt;&lt;br /&gt;Enterprise Trust\Local Computer and verified it was trusted root authority.&lt;br /&gt;&lt;br /&gt;same issue.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Turning of ssl for that folder and trying with &lt;a href="http://localhost/reports"&gt;http://localhost/reports&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;same issue.&lt;br /&gt;&lt;br /&gt;In Reporting services configuration manager -&gt; Report server virtual directory -&gt; Certificate name, nothing is specified (plus thats the /ReportServer url)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Based on some readings, I reset IIS since some people had an issue unchecking ssl until they restarted IIS. No go for me.&lt;br /&gt;&lt;br /&gt;I checked everything with the certificate. The server's certificate is from Exchange 2007 - IE auto generated when it was installed. I checked in trusted root certification authorities and the server's root ca certificate was in there.&lt;br /&gt;I checked in IIS - the certificate was OK, not expired and showing up as OK as well.&lt;br /&gt;&lt;br /&gt;since I was trying to connect to localhost/reports I used the system name:&lt;br /&gt;&lt;a href="http://lois/reports"&gt;http://lois/reports&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;same problem.&lt;br /&gt;&lt;br /&gt;so at this point, ssl is off from the sql server reporting services configuration tool, and I've unchecked it from the virtual directory in IIS.&lt;br /&gt;&lt;br /&gt;So whats the solution?&lt;br /&gt;In the file notepad d:\Program Files\Microsoft SQL Server\MSSQL.2\Reporting Services\ReportManager\RSWebApplication.config&lt;br /&gt;there are two items which need addressing&lt;br /&gt;&lt;br /&gt;1. ReportServerUrl, which in my case was blank and ReportServerVirtualDirectory which was set to Reports&lt;reportservervirtualdirectory&gt;&lt;br /&gt;&lt;br /&gt;According to MS, they are mutually exclusive, IE you can only set one or the other. So I removed the virtual directory entry and set the report server url, and saved it and voila.. it worked:&lt;br /&gt;&lt;br /&gt;&amp;lt;reportserverurl&amp;gt;http://lois/reportserver&amp;lt;/reportserverurl&amp;gt;&lt;br /&gt;&amp;lt;reportservervirtualdirectory&amp;gt;&amp;lt;/reportservervirtualdirectory&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;another note: if you have generated your own certificate, the system you are deploying from won't be able to deploy to the target server as well. You will receive the same error in addition (in visual studio) viewing the extended error information you may see:&lt;br /&gt;"The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel. "&lt;br /&gt;"The remote certificate is invalid according to the validation procedure. (System)"&lt;br /&gt;&lt;br /&gt;So, navigate from your system to the report server. View the certificate and import it into the trusted root certification authorities, and then on the certificate path tab (right click on the document and choose properties) check to make sure there are no Xs on the certificate issuer. If there is - import it from there into the same store - trsuted root certification authorities.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;OH but wait!&lt;br /&gt;I can see all the report definitions, but when I attempt to run them I receive:&lt;br /&gt;The request failed with HTTP status 401: Unauthorized.&lt;br /&gt;&lt;br /&gt;hmm. I tried all different auth options, and removing ssl.&lt;br /&gt;&lt;br /&gt;nothing.&lt;br /&gt;If I turned off integrated auth and turned on anonymous access, I'd receive&lt;br /&gt;The permissions granted to user 'ABBSATT\reportuser' are insufficient for performing this operation.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;now.. if I used the url to go to the report server using ssl directly, it worked just fine. That was the clue I wasn't using the correct url in the rswebapplication.config&lt;br /&gt;&lt;br /&gt;So, I went into the reporting services config tool, and did the "Apply Default Settings" on each so I could start from scratch.&lt;br /&gt;&lt;br /&gt;Again (as expected) I was back to:&lt;br /&gt;The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.&lt;br /&gt;&lt;br /&gt;I went into rswebapplication.config and changed the url I modified above to https://......&lt;br /&gt;instead of http, and voila. it worked. all good... in all scenarios.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/reportservervirtualdirectory&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-1995466286239005556?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/1995466286239005556/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2009/01/more-issues-with-sql-reporting-services.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/1995466286239005556'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/1995466286239005556'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2009/01/more-issues-with-sql-reporting-services.html' title='More issues with Sql Reporting Services - The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5716364009216068026.post-2266480068917625810</id><published>2009-01-19T23:25:00.001-08:00</published><updated>2009-01-19T23:34:04.124-08:00</updated><title type='text'>Network provider issues and Sql Server Reporting Services</title><content type='html'>I installed reporting services on my new laptop.&lt;br /&gt;I tried running it, and it hung for a long time and came back with an error:&lt;br /&gt;&lt;br /&gt;Logon failed. (rsLogonFailed)Could not load file or assembly 'BCMLogon, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. Failed to grant minimum permission requests. (Exception from HRESULT: 0x80131417)Required permissions cannot be acquired.&lt;br /&gt;&lt;br /&gt;hmm. why is a library made by broadcom being an issue just connecting to sql reporting services on a local machine. I changed some settings in IIS for authentication to allow everything same as the actual report server which I could get in to configure items, just not run a report.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Finally the light went off - this library is:&lt;br /&gt;"BcmLogon: Provides credential information (user name, password, domain) used by wireless management software for login to wireless networks. Optionally enables wireless login at startup for SSO environments.Dell Wireless WLAN Card Logon Provider"&lt;br /&gt;&lt;br /&gt;As such inthe system its a network provider. A quick search of the registry for BCMLogon shows:&lt;br /&gt;&lt;br /&gt;[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\NetworkProvider]&lt;br /&gt;[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\NetworkProvider\HwOrder]"ProviderOrder"="LanmanWorkstation,RDPNP,webclient,BCMLogon"&lt;br /&gt;[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\NetworkProvider\Order]"ProviderOrder"="LanmanWorkstation,RDPNP,webclient,BCMLogon"&lt;br /&gt;&lt;br /&gt;Hey.. its last in the chain here (and you can verify by going into your network connections, advanced menu, and then advanced settings, and then provider order.&lt;br /&gt;Dell Wireless WLAN Card Logon Provider is indeed the last one.&lt;br /&gt;&lt;br /&gt;now in my case, I dont need it.. so the fix is simple. I renamed the dll in c:\windows\system32. I can still acess my wireless network just fine.&lt;br /&gt;&lt;br /&gt;I did try configuring this assembly, permissions were ok on the file itself, and it should be full trust, so not sure where is was breaking down, but the fix worked for me.. for now and its late anyways : )&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5716364009216068026-2266480068917625810?l=completedevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://completedevelopment.blogspot.com/feeds/2266480068917625810/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://completedevelopment.blogspot.com/2009/01/network-provider-issues-and-sql-server.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/2266480068917625810'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5716364009216068026/posts/default/2266480068917625810'/><link rel='alternate' type='text/html' href='http://completedevelopment.blogspot.com/2009/01/network-provider-issues-and-sql-server.html' title='Network provider issues and Sql Server Reporting Services'/><author><name>Adam Tuliper</name><uri>http://www.blogger.com/profile/10069537457575128626</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry></feed>
