Thoughts from Dan Miser
Sunday, 01 December 2013
Trying to follow the directions to host your own Nuget server, I ran into a couple small problems when trying to deploy it to a Virtual Application within an Azure WebSite. I was able to successfully deploy this inside the Virtual Application using my previously posted directions. But I still found these issues:

1. The URL was actually requiring a second nuget appended to the end (i.e. http://www.mydomain.com/nuget/nuget/).
2. When accessing the required URL above, I received this error:
This collection already contains an address with scheme http. There can be at most one address per scheme in this collection.
If your service is being hosted in IIS you can fix the problem by setting 'system.serviceModel/serviceHostingEnvironment/multipleSiteBindingsEnabled' to true
or specifying 'system.serviceModel/serviceHostingEnvironment/baseAddressPrefixFilters'.

The solution was to update the web.config to add this attribute to the element that was already there.
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true"/>
Sunday, 01 December 2013 21:51:33 (GMT Standard Time, UTC+00:00)      Comments [0] -
.NET | ASP.NET
Saturday, 23 November 2013
Azure has been churning out features faster than anything I can ever remember coming out of Microsoft. I finally moved to Azure with my production apps this weekend. It was a pretty painless move, as far as data center moves go. One of the biggest road blocks that I hit was trying to create virtual applications for each of my apps inside one Azure Web Site. I wanted to go this way to get the benefits of having one DNS entry, coupled with an SSL certificate, and eventually wildcard subdomains. It seemed the smart way to go, given that each app is isolated and I've been running that way on my own IIS server for a couple years (or more) now.

The key to getting things right is to select your Azure Web Site in the portal, and go to Configure. Then, at the bottom of the page you can add your virtual applications. The placeholder text says "PHYSICAL PATH RELATIVE TO SITE ROOT". Don't listen to that. Instead, make your virtual applications live underneath site\wwwroot.

If you do that, you can then download the Publish Profile Settings from your dashboard and update the <DeployIisAppPath> element to look like this:
<DeployIisAppPath>MySite/app1</DeployIisAppPath>
Now when you deploy, the files will land on the server in the right directory.

I couldn't find a way to get the deploy to put the files in the site\app1 directory on the server. DeployIisAppPath and RemoteSitePhysicalPath could not get me up to that level in this setup. If you know of a better way, I'd love to hear about it!

Bonus: If you're a command line junkie like me, you'll want to read how to publish an Azure site from the command line.
Saturday, 23 November 2013 23:40:46 (GMT Standard Time, UTC+00:00)      Comments [1] -
.NET | ASP.NET | ASP.NET MVC
Saturday, 10 March 2012
There is no way I can list everything I learned with MonoTouch over the last couple of months. I'll summarize my experience by saying I'm a very happy customer. There were bumps and bruises along the way, but between the mailing list and the support crew at Xamarin, I heartily recommend investigating MonoTouch if you're a .NET developer that wants to get to the iOS AppStore quickly. I had to take several detours along the way (converted my existing app from Lightspeed to EF4 CodeFirst, converted to use POCOs, had support obligations, and wrote a sync engine to communicate over ServiceStack, but in the end, things lined up pretty well.

Some of the highlights:

• I had to write code to essentially mimic the context loading that EF would do for you. This included fixing up object references as well as reading and writing from the SQLite database. Not horribly difficult, but it was something I'd rather I didn't have to do.
• I encountered a couple of problems executing various LINQ statements when running on the device. A quick test case, and the devs at Xamarin had me with either workarounds or fresh bits to solve my problems.
• Be sure to embrace threading when making web calls - especially on startup. You have 15 seconds to have your app launched on the device, or the device will think it is hung and kill the app.
• Deploying to the app store has been written about extensively as a complex and intricate process. It turns out, there's good reason for that. After I got through an error due to linking my release build to ServiceStack.Text.dll, the resulting upload to the app store was failing verification. For some reason, the application name of RouteBoostiPhone.app was not being accepted. I changed the name to RouteBoost.app and it sailed right through. I have no idea exactly why this was required, but there you have it.
• MonoTouch.Dialog is a very nice framework for building a line of business app. Be sure to check it out.

When I look back on the road I travelled to get my app to the app store, I'm impressed with how much of the business logic I was able to carry over. The time savings in being able to bring my business logic across as POCOs that have been extensively tested in production over many years was the real reason I went with MonoTouch to begin with. I most definitely do not regret that decision.

Note: I was not compensated or asked to write this post. I am just a happy paying customer of a product that saved me time, and I wanted to share my experience.

Saturday, 10 March 2012 01:48:03 (GMT Standard Time, UTC+00:00)      Comments [0] -
.NET | iPhone
Wednesday, 15 February 2012
I had a class that looked like this:

public class CollectionDetail {
public int Id { get; set; }
...
public MachineField MachineField { get; set; }
}


I would then later write LINQ code that would end up retrieving these objects. The problem was MachineField was always set to null. I banged my head on this for a long time looking at everything I could think of. Finally, after looking at the CollectionDetail class one more time, I noticed that other Foreign Key objects were marked with virtual, and I remembered that I removed virtual while I was trying to test whether or not the object's lazy load behavior. All of the documentation clearly states that you need to mark this virtual. Once I added the virtual keyword back, everything worked exactly as it should have.

Wednesday, 15 February 2012 00:55:59 (GMT Standard Time, UTC+00:00)      Comments [0] -
.NET | EntityFramework
Sunday, 22 January 2012
I found the class ActionSheetDatePicker from the book Developing C# Apps for iPhone and iPad using MonoTouch iOS Apps Development for .NET Developers. It was a very nice and clean implementation that would allow for having an ActionSheet pop up with a UIDatePicker in an iOS application.

It did lack 2 things, though:

1. The ability to specify a starting default date in the UIDatePicker
2. The ability to get cleanly launched from a UITextField component (i.e. effectively replace the default keyboard of a text field with this date picker). The original code would leave the default keyboard up when getting called from a UITextField component.

I fixed those things, and you can find the results in this gist.

Sunday, 22 January 2012 18:13:42 (GMT Standard Time, UTC+00:00)      Comments [0] -
.NET | iPhone
Thursday, 08 December 2011
My company's core applications are written in ASP.NET MVC, and have been well received. But the nature of what those applications can do in limited/non-existent connectivity areas is causing enough problems that I need a native iPhone solution. (HTML 5 offline storage is not enough. I need full access to the brains of calculation engines that are in my business logic on the server, and I wouldn't relish moving that logic to JavaScript. Besides, I found a real nice thermal receipt printer that will work via SDK with a native app!)

I came across MonoTouch, and I really like how it will enable reuse of my hard work over the years. The main obstacle for me was how to get the data out to my iPhone client. I wasn't exactly thrilled with the idea of shoe-horning WCF access from the iPhone, and working with WCF at my day job is a configuration nightmare. REST would be good, but I wasn't happy with the options out there - until I found ServiceStack. I don't know why this thing doesn't get more publicity. It is everything I want: small, fast, actively developed, easy to configure, JSON, REST, DTOs, and works easily with MonoTouch. Well done, guys.

The first snag I hit getting some demo code out there was that if you want to have the client code exist on MonoTouch, be sure to add references to the assemblies found in the MonoTouch-v2.20.zip file on github. I'm curious why this is still labelled as 2.20, and why those assemblies are still dated from June 9, 2011, but for now, things are moving along to convert my ASP.NET MVC application to use services, and expose those services for use on my iPhone client.

Thursday, 08 December 2011 21:27:12 (GMT Standard Time, UTC+00:00)      Comments [0] -
.NET | iPhone
Saturday, 15 October 2011
I've had a web application written using iUI for a couple of years now. It's been stable and rock solid, and I really appreciate the leg up that it gave me. However, this weekend I converted away from iUI to jQueryMobile. I have another application in production already using jQueryMobile, and it is absolutely an amazing library.

The reasons I went with this move were:
• iOS 5 had substantial changes to Safari and my existing application is broken in many places. Instead of spending time debugging and fixing something 2 years old, I figured I'd take the time to port to jQueryMobile.
• I've had to leave iUI at version 0.31 for this entire 2 year period. When they started development on the 0.4 version, they changed form submissions to break if you had multiple form fields with the same name. I absolutely had to have this capability in order to support ASP.NET MVC list binding. I reported the issue in the forums, and it didn't get much attention. Sure, it's open source, but if I have to chase down bug fixing in a framework I'm not intimately familiar with, it's a negative.
• There is no easy way with the released version of iUI to do things like jQuery calls, hook events into the page create/show and hide/destroy. Sure, there are code modifications you can find on the web, but it's a forking nightmare and tough to maintain (is this for 0.31, 0.4, or 0.5? does it require other extensions or modifications? etc.).
• From a non-technical perspective, the roadmap of iUI has been all over the place. I can't remember for sure, but I think it was originally slated for moving 0.4 in to release status in like June of 2009. It's been pushed out over and over again, trimmed in scope, and there just doesn't seem to be traction or consensus to move the product forward. In contrast, jQueryMobile is looking to have a 1.0 release in the next few weeks with constant releases over the past few months.

Saturday, 15 October 2011 22:26:06 (GMT Daylight Time, UTC+01:00)      Comments [0] -
.NET | ASP.NET MVC | iPhone
Thursday, 29 September 2011
At work here, we use generated files with partial classes to get us through the tedium of creating mundane classes. It works well enough, but one of my biggest complaints about this is that if you then need to do a Find in Files, you get hundreds, or maybe thousands, of extra hits when searching for something that would be found inside those generated files.

Today I came across the free tool Ultra Find in the Extensions gallery. It does exactly what I want, namely, lets me focus on the search results that aren't in the generated files.

Thanks, Logan. Very useful!

Thursday, 29 September 2011 19:30:45 (GMT Daylight Time, UTC+01:00)      Comments [1] -
.NET
Thursday, 01 September 2011
While creating a view model for an MVC 3 application, I annotated a property with the DataType.EmailAddress attribute. My thinking was that it would validate whether or not the contents of the property was in a valid email format. The attribute does not perform validation, however. This StackOverflow article discusses some ways to add that functionality.

Thursday, 01 September 2011 03:31:51 (GMT Daylight Time, UTC+01:00)      Comments [0] -
.NET | ASP.NET MVC
Friday, 22 July 2011
The conversion is finally on. I've had a lot of praise for LightSpeed over the years. The guys writing it are wicked smart, and Ivan is a rockstar on the support forums. They've solved a lot of bugs for me while I've been a customer, but the time has come to move on.

I've become quite proficient with LINQ, and use it all over the place in my code. Having to drop down and execute loops and run suboptimal queries because I have to execute an intermediate ToList() just to get around projection and grouping errors has taken its toll on me.

I truly wish the guys at Mindscape continued success, but the time has come to move on to the company that provides a MSSQL LINQ provider that is completely fleshed out.

Friday, 22 July 2011 01:39:06 (GMT Daylight Time, UTC+01:00)      Comments [0] -
.NET | LINQ
Sunday, 17 July 2011
I've been ussing CC.NET for probably the last 5 years with good success. At work, we recently migrated to TFS 2010 (installation and configuration are brutal, but it's sort of nice when it all works). I figured I'd take this time to look around and see what I've been missing on the continuous integration scene for my personal projects. The 2 leading contenders were TeamCity and Bamboo. I went with TeamCity since I use ReSharper, and think the JetBrains guys are pretty top-notch.

Installation was drop-dead simple. Configuring was pretty straight-forward, but I had an assist from StackOverflow, which led me to this amazing article/series by Troy Hunt. After following Troy's instructions, and slightly adjusting for the obvious version differences, I had things up and running, with a completed build inside 15 minutes.

I also configured the Build Triggering step because I want the build to fire off each time I checkin. I've got a few things to take care of (notifications of broken builds, code coverage, etc.), but it looks like this is a much easier application to configure than CC.NET.

Sunday, 17 July 2011 02:36:26 (GMT Daylight Time, UTC+01:00)      Comments [1] -
.NET | ALT.NET | ASP.NET MVC
Tuesday, 22 February 2011
The Web Platform Installer (WPI) is really nice when it works. But when it doesn't, it's a battle to the death to get things to work. Case in point: I was trying to install php on my Windows 2008 Server through WPI, but it would go on forever during the FastCGI install step. I looked at logs and the Event Viewer, and searched google. A lot of people reported a similar problem, but there was no definitive recipe to get past the problem.

In the end, I just clicked on the link for FastCGI in the installation details window of WPI, and installed that piece manually. It went through without a hitch. After a restart (which the FastCGI installer required), I installed php from WPI, and it installed the 4 remaining pieces without a hitch, and it did so quickly. So just a note that if WPI starts acting up, just install the problematic piece manually and then let WPI continue.

Tuesday, 22 February 2011 04:04:52 (GMT Standard Time, UTC+00:00)      Comments [1] -
.NET | ASP.NET
Wednesday, 02 February 2011

First things first: .NET Reflector is, and always has been, an amazing piece of technology. Any .NET developer that has worked for any length of time has benefited from the original vision of Lutz Roeder. Secondly, I don't blame him in the least bit for selling to RedGate to profit on his effort and talent. He more than earned it.

The issue is not the 35. I've spent more for worse tools. But when I've done that, it's almost always been to support the effort of a one-man shop working his butt off. It is not going to happen in order to have some corporate entity try to recoup losses on a bad business decision. They knew all along that Reflector didn't align with the tools that they sell. Taking away the free version simply shows that RedGate management is clueless. As for me, I'll put100 towards the next free/open reflector to come along instead of rewarding RedGate with a sale.

Wednesday, 02 February 2011 23:09:12 (GMT Standard Time, UTC+00:00)      Comments [3] -
.NET
Saturday, 15 January 2011
Rather than another "me too" post on the release of ASP.NET MVC 3, which Hanselman, Haack, and Guthrie have covered in-depth, I thought I'd post the good news that a couple of bugs that have bothered me are fixed in this version.

1. There was a problem when using auto-detecting view engines when compiling under release mode. Basically, if you hit the site with your desktop browser first, and then come in with the mobile phone, you would still be presented the desktop version. This is now fixed.
2. I posted about a problem with binding with the RC2 release. This also appears to be fixed.
Throw in the new scaffolding support, and 2011 is shaping up to be a great year for MVC.
Saturday, 15 January 2011 07:25:35 (GMT Standard Time, UTC+00:00)      Comments [0] -
.NET | ASP.NET MVC
Monday, 03 January 2011
I recently moved away from shared hosting, and went to a virtual private server in order to scale a site out better. Unfortunately, this meant that I needed to take on more administration of the server to do things that are done for me in a shared hosting environment. One feature that I have come to rely on is one click publishing from VS.NET 2010. In order to make this work, you need to have WebDeploy set up properly.

I found the steps from this page to be very helpful. Another good guide can be found here.

Be careful if you install Web Deploy via the Web Platform Installer. For some reason, when I did this, the Management Service Delegation feature was not installed. I ended up uninstalling and then installing straight from the official site, and the feature was available.

I initially had some settings wrong, and was getting back HTTP 401 and 550 errors. The log files didn't provide much help, but you can add tracing to help diagnose the cause of most issues.

Monday, 03 January 2011 16:12:24 (GMT Standard Time, UTC+00:00)      Comments [0] -
.NET | ASP.NET MVC
Monday, 13 December 2010
I updated my web sites to ASP.NET MVC 3 RC2, and started receiving exceptions when model binding. If you want the short version, visit this forum post for the answer. While my errors weren't caused by the same issue that was originally reported in that thread, the fix does work. To sum up even further, just add this line of code in your Global.asax Application_Start method:



The longer story is that I have a pretty involved multi-step (think "wizard"), deep-level object graph built up over many pages, so I immediately feared that I was unknowingly exploiting some loophole that just got fixed for RC2. I built a test case, so in the interest of not having to build that test case up from scratch again, it looked like this:
Model


public class Foo
{
private List<Bar> _bars;
private List<Baz> _bazs;

public Foo()
{
_bars = new List<Bar>();
_bazs = new List<Baz>();
}

public List<Bar> Bars
{
get { return _bars; }
set { _bars = value; }
}

public List<Baz> Bazs
{
get { return _bazs; }
set { _bazs = value; }
}
}

public class Bar
{
public int Amount { get; set; }
}

public class Baz
{
public int Value { get; set; }
}


Controller


public ActionResult Index()
{
var foo = new Foo();
foo.Bars.Add(new Bar { Amount = 4});
foo.Bars.Add(new Bar { Amount = 23 });
foo.Bars.Add(new Bar { Amount = 30 });
foo.Bazs.Add(new Baz { Value = 100 });
foo.Bazs.Add(new Baz { Value = 200 });
TempData["foo"] = foo;
return View(foo);
}

[HttpPost]
public  ActionResult Index(IList<Bar> bars, IList<Baz> bazs)
{
Foo foo = (Foo) TempData["foo"];
foo.Bars.Clear();
foo.Bazs.Clear();
TempData["foo"] = foo;
return RedirectToAction("Summary");
}

public ActionResult Summary()
{
Foo foo = (Foo)TempData["foo"];
return View(foo);
}


View


<% using(Html.BeginForm()) { %>
<%
int barid = 0;
foreach (var item in Model.Bars){%>

<%= Html.Hidden("Bars.index", barid) %>
Bar:<%= Html.TextBox("Bars[" + barid +"].Amount", item.Amount) %>
<%  barid++;
}%>

<%
int bazid = 0;
foreach (var item in Model.Bazs)
{%>
<br />
<%=Html.Hidden("Bazs.index", bazid)%>
Baz: <%=Html.TextBox("Bazs[" + bazid + "].Value", item.Value)%>
<%  bazid++;
}%>
<p />
<input type="submit" value="Next" />
<% } %>


I would receive the following call stack when trying to submit the form:


The parameters dictionary contains an invalid entry for parameter 'bazs' for method
'System.Web.Mvc.ActionResult Index(System.Collections.Generic.IList1[MvcApplicationRC2.Models.Bar], System.Collections.Generic.IList1[MvcApplicationRC2.Models.Baz])'
in 'MvcApplicationRC2.Controllers.HomeController'. The dictionary contains a value of type 'System.Collections.Generic.List1[MvcApplicationRC2.Models.Bar]',
but the parameter requires a value of type 'System.Collections.Generic.IList1[MvcApplicationRC2.Models.Baz]'.
Parameter name: parameters
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.

Exception Details: System.ArgumentException: The parameters dictionary contains an invalid entry for parameter 'bazs' for method
'System.Web.Mvc.ActionResult Index(System.Collections.Generic.IList1[MvcApplicationRC2.Models.Bar], System.Collections.Generic.IList1[MvcApplicationRC2.Models.Baz])'
in 'MvcApplicationRC2.Controllers.HomeController'. The dictionary contains a value of type 'System.Collections.Generic.List1[MvcApplicationRC2.Models.Bar]',
but the parameter requires a value of type 'System.Collections.Generic.IList1[MvcApplicationRC2.Models.Baz]'.
Parameter name: parameters

Source Error:

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.

Stack Trace:

[ArgumentException: The parameters dictionary contains an invalid entry for parameter 'bazs' for method 'System.Web.Mvc.ActionResult
Index(System.Collections.Generic.IList1[MvcApplicationRC2.Models.Bar], System.Collections.Generic.IList1[MvcApplicationRC2.Models.Baz])' in
'MvcApplicationRC2.Controllers.HomeController'. The dictionary contains a value of type 'System.Collections.Generic.List1[MvcApplicationRC2.Models.Bar]',
but the parameter requires a value of type 'System.Collections.Generic.IList1[MvcApplicationRC2.Models.Baz]'.

Parameter name: parameters]
System.Web.Mvc.ActionDescriptor.ExtractParameterFromDictionary(ParameterInfo parameterInfo, IDictionary2 parameters, MethodInfo methodInfo) +484514
System.Web.Mvc.<>c__DisplayClass1.<Execute>b__0(ParameterInfo parameterInfo) +18

System.Linq.WhereSelectArrayIterator2.MoveNext() +85
System.Linq.Buffer1..ctor(IEnumerable1 source) +325
System.Linq.Enumerable.ToArray(IEnumerable1 source) +78
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary2 parameters) +133

System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary2 parameters) +27
System.Web.Mvc.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12() +55

System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func1 continuation) +263
System.Web.Mvc.<>c__DisplayClass17.<InvokeActionMethodWithFilters>b__14() +19

System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList1 filters, ActionDescriptor actionDescriptor, IDictionary2 parameters) +191
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +343

System.Web.Mvc.Controller.ExecuteCore() +116
System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +97
System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +10

System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__5() +37
System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +21
System.Web.Mvc.Async.<>c__DisplayClass81.<BeginSynchronous>b__7(IAsyncResult _) +12

System.Web.Mvc.Async.WrappedAsyncResult1.End() +62
System.Web.Mvc.<>c__DisplayClasse.<EndProcessRequest>b__d() +50
System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) +7

System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +60
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9

System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8841105
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184

Monday, 13 December 2010 02:29:59 (GMT Standard Time, UTC+00:00)      Comments [2] -
.NET | ASP.NET MVC
Wednesday, 10 November 2010
With the near-release of ASP.NET MVC 3, I've been looking at the new Razor view engine. It's quite nicely done and removes the constant "context switching" between code and layout.

In my web site, I used Scott Hanselman's auto-detecting view engine, and it has served me extremely well. However, with the relentless march of technology releases, a couple things should be pointed out:

• If you want to use Razor on the mobile side, you just need to inherit his original class from RazorViewEngine instead of WebFormViewEngine. (Obviously you should probably do this in a new class, or else the original class name of MobileCapabeWebFormViewEngine will not exactly match up to what the class actually does).
• The original Mobile Device Browser File project has disbanded. Very sad news, as this was a nice project that kept on top of new smart phones as they were released. It looks like 51 degrees has stepped up to give us an alternative. I opened up an issue to request providing this as a NuGet package. I'll definitely sign up to take this task on if it gains traction, and they want the help.
Wednesday, 10 November 2010 02:04:33 (GMT Standard Time, UTC+00:00)      Comments [0] -
.NET | ASP.NET MVC
Friday, 15 October 2010
Given a method like this, with the following LINQ to SQL statement in it:

public void DisplayReport(UserStatusEnum? userStatus)
...
from user in DBContext.Users
where userStatus == null ? true : userStatus.Value == user.Status
select user


I end up with the error "Nullable object must have a value". Matt Warren (one of the original developers on the LINQ to SQL team, and a wicked smart guy), came up with the idea to use target="_blank">object.Equals(userStatus, user.Status), but that doesn't work for me at all in the case where userStatus is NULL. What worked for me was to do this:


from user in DBContext.Users
where userStatus == null || userStatus == user.Status
select user


The thing is, as one commenter in the linked thread mentioned, LINQ to SQL should be a unifying syntax. We shouldn't have to distinguish between NULL and values just because the underlying provider makes a distinction between the two. I think this is a huge hole, but alas, one that will most likely never be plugged since LINQ to SQL is getting deprecated. Time to check what happens in EF4...

Friday, 15 October 2010 18:41:07 (GMT Daylight Time, UTC+01:00)      Comments [0] -
.NET | LINQ
Tuesday, 12 October 2010
There are many reasons WCF will toss the generic "The remote server returned an error: NotFound" error, along with a meaningless call stack. The easiest way to identify what specifically is causing you pain is to enable tracing on the WCF service. To do this, add this in your web.config after your <system.serviceModel> element:

<system.diagnostics>
<sources>
<source name="System.ServiceModel" switchValue="Information, ActivityTracing">
<listeners>
initializeData= "c:\dev\log\WcfTrace.svclog" />
</listeners>
</source>
</sources>
</system.diagnostics>


After you run your application and error out, just double click on the c:\dev\log\WcfTrace.svclog file. This will bring up the Microsoft Service Trace Viewer. It's a really nice tool that highlights errors in red, so just double-click on red items and you'll eventually get to the root exception which should give you all of the information you need to fix things up.

For the record, the error I was getting that started all of this was due to trying assign an invalid value to an enum. Live and learn.

Tuesday, 12 October 2010 20:05:27 (GMT Daylight Time, UTC+01:00)      Comments [0] -
.NET
Wednesday, 24 February 2010
I use list binding in my ASP.NET MVC applications in several places. When it works, it is truly magnificent. When it doesn't, it's just maddening. Here's a quick heads up for those of you that use list binding in MVC. You would expect the following 2 lines to render the same HTML, but they don't. To get list binding to work, you need the HTML to read something like this (I'm just listing the attributes in question here):


<input name="Results[0].Score" />


The old TextBox helper works fine, since you're assigning the name attribute:


Html.TextBox("Results["+id+"].Score", Model.Score)


This code, however:


Html.TextBoxFor(r => r.Score, new { name = "Results[" + id + "].Score" })


produces the following output, which means the Score property won't get bound properly.


<input name="Score" />


The problem is that in the TextBoxFor code, the name attribute is ignored. To be more precise, the custom name is added, but the attribute is then replaced by the name derived from the model.

Wednesday, 24 February 2010 04:12:13 (GMT Standard Time, UTC+00:00)      Comments [0] -
.NET | ALT.NET | ASP.NET MVC
Tuesday, 19 January 2010
I just updated my ASP.NET MVC 1.0 application to use ASP.NET MVC 2 RC. It was a pretty painless process. Be sure to follow the Release Notes on the download page, and many applications will be ready to go. Here are some extra things that might help get you unstuck:
• If you're using the ASP.NET MVC Futures (Microsoft.Web.Mvc) assembly, be sure to download the new one that works with ASP.NET MVC 2.
• If you're using the Telerik ASP.NET MVC components, be sure to download version BETA 2009.3.1218 or later.
• Way, way, way back in the ASP.NET MVC 1.0 beta days, they had a very nice mechanism to update lists of items by tying UI fields to index numbers, so you could use primary key identifiers to help keep track of what fields were modified where. In the 1.0 RC release, Microsoft changed how it worked to do things sequentially instead. I was using the IndexModelBinder found in that thread with great success ever since then. However, Microsoft added back in the index support to ASP.NET MVC 2 RC. This means that you will have to delete the old IndexModelBinder since it won't compile anymore. Thankfully, I didn't have to change a line of my code. Nice job of code compatibility!!
Tuesday, 19 January 2010 02:52:39 (GMT Standard Time, UTC+00:00)      Comments [0] -
.NET | ASP.NET MVC
Tuesday, 05 January 2010
Consider this code fragment:
var list =
from tx in Transactions
group tx by new {tx.TransactionType, tx.ClientTypeID};

foreach (var item in list)
{
Console.WriteLine(item.Key.TransactionType);
Console.WriteLine(item.Sum(tx => tx.Amount));
foreach (var item2 in item)
Console.WriteLine(item2.TransactionID);
}


After executing the query, we now have an IGrouping<AnonymousType, Transaction> that lets us run through all of the grouped objects, while still having access to the original objects in the inner loop. We can accomplish the exact same thing with this alternative LINQ statement, but the first version seems cleaner to me:

var list =
from tx in Transactions
group tx by new {tx.TransactionType, tx.ClientTypeID} into g
select g;

Tuesday, 05 January 2010 16:30:01 (GMT Standard Time, UTC+00:00)      Comments [0] -
.NET | LINQ
Sunday, 08 November 2009
Telerik just released an extremely impressive library of components (Grid, Menu, TabStrip, and MenuBar), written for MVC. They are truly first-class, from the architecture, to the development experience, to the finished screens that your user sees. They released them as open-source, and even better, these controls are written from the ground up to support ASP.NET MVC.

Be sure to check out this awesome write up on how to Use the grid in a CRUD scenario. Very nicely done.

I'm not a fan of the whole "Edit/Delete" action column. I'd much rather just have a link on the column to take me to the detail screen. Here's the way I solved that:


<% Html.Telerik().Grid(Model)
.Name("Grid")
.PrefixUrlParameters(false)
.Columns(columns =>
{
columns.Add(o => o.CollectionDate).Template(c => { %>
<%= Html.ActionLink(c.CollectionDate.ToShortDateString(), "View", new { Id = c.Id })%> <%
}).Width(40);
})
.Scrollable()
.Sortable()
.Pageable()
.Filterable()
.Render();
%>

Sunday, 08 November 2009 03:00:21 (GMT Standard Time, UTC+00:00)      Comments [0] -
.NET | ALT.NET | ASP.NET MVC
Friday, 16 October 2009
Given a collection of players that were constructed like this:

{
Player favre = new Player { Id = 1, Name = "Favre", Team = new Team { Id = 1, Name = "Vikings" } };
Player peterson = new Player { Id = 2, Name = "Peterson", Team = new Team { Id = 1, Name = "Vikings" } };
Player rodgers = new Player { Id = 3, Name = "Rodgers", Team = new Team { Id = 2, Name = "Packers" } };
Player driver = new Player { Id = 4, Name = "Driver", Team = new Team { Id = 2, Name = "Packers" } };

List<Player> players = new List<Player> {favre, peterson, rodgers, driver};
return players;
}


And the following LINQ query:


var query =
group p by p.Team into g
select g;


We will see the following output:


Vikings
Vikings
Packers
Packers


The reason this is happening is that we created new Team objects for each and every Player, and when LINQ tries to group, it does so based on object equality. The solution to this is to override the Equals() and GetHashCode() methods in the Team class. After doing that, the LINQ query will be able to group the objects up properly and just display each team name once. Resharper has a nice code generation template to create solid implementations of these methods (press Alt+Ins to bring up the code generation menu).

The example here is obviously contrived. We could create each team object once, and then use the same instance during the property assignment, and if we did that, things would work just fine. However, I ran into a more generalized version of this problem when using WCF and a lot of custom code generation. The underlying lesson is still the same: LINQ and GroupBy need to have object equality defined properly in order to make things work as you would expect.

Friday, 16 October 2009 19:14:18 (GMT Daylight Time, UTC+01:00)      Comments [2] -
.NET | LINQ
Sunday, 31 May 2009
Given a set up like this (where ExpenseSummaryData returns some arbitrary HTML fragment) :

<%using (Ajax.BeginForm("ExpenseSummaryData", new AjaxOptions { UpdateTargetId = "result" })) { %>
<label for="startDate">Start Date:</label>
<%= Html.TextBox("startDate") %>
<br />
<label for="endDate">End Date:</label>
<%= Html.TextBox("endDate")%>
<br />
<input type="submit"/>
<br />
<span id="result"/>
<% } %>


If that is all your page does, you will notice that you get taken to a new page when pressing Submit. The data on the new page is the HTML fragment returned by the AJAX call, but that's all it contains (e.g. no master page), and it's clearly not replacing the result span.

The reason for this is that I forgot to add the following lines to the <head> section in the original page:


<script src='<%=ResolveUrl("~/Content/js/MicrosoftAjax.debug.js")%>' type="text/javascript"></script>
<script src='<%=ResolveUrl("~/Content/js/MicrosoftMvcAjax.debug.js")%>' type="text/javascript"></script>


After adding those declarations in, the content in the span tag is properly updated and it looks like a real AJAX call.

Sunday, 31 May 2009 17:38:24 (GMT Daylight Time, UTC+01:00)      Comments [0] -
.NET | ASP.NET MVC
Saturday, 25 April 2009
I've been on Facebook for a while, and I just added Twitter to the mix. I'm trying to keep communications on those sites much more informal and fairly non-technical. If you want to follow me, search for dmiser@wi.rr.com on Facebook or danmiser on Twitter. Hope to see you over there.
Saturday, 25 April 2009 18:08:10 (GMT Daylight Time, UTC+01:00)      Comments [1] -
.NET
Wednesday, 22 April 2009
Are you looking for a strong developer/architect with a serious passion for all things technical and a unique blend of experience? If so, feel free to email me. My main focus over the past couple of years has been on things ALT.NET-ish (e.g. ASP.NET MVC, NHibernate, Spring.NET, etc.) while I have delved into a variety of other technologies as well (e.g. Mindscape LightSpeed, LINQ, Dynamic Data, Delphi, etc.). If you know of an opening - contract or full-time - please keep me in mind. I'd prefer to remain in the Milwaukee area, but occasional travel wouldn't be the end of the world.

Until the next technical post here, take care and thanks in advance.

Wednesday, 22 April 2009 19:29:54 (GMT Daylight Time, UTC+01:00)      Comments [0] -
.NET | ALT.NET | Delphi
Friday, 13 March 2009

The first time you load an assembly of Quartz.NET jobs, it populates the database with the current trigger information (cron vs. simple, timings, etc.) that it finds in the configuration file. It appears that this information does not get updated once it's in the database. So if you want to make a change to set the trigger time to be every minute instead of the original version of "run every day at 2am", you will be waiting for a loooong time to see that trigger fire (unless you start at 1:59am :)).

Since I'm using Migrator.NET to control my database schema, I can easily drop the tables and recreate them. This isn't a big deal because once I have things tested, I won't need to change the trigger information, but it did trip me up for a bit so I thought I'd share.

Friday, 13 March 2009 04:47:18 (GMT Standard Time, UTC+00:00)      Comments [2] -
.NET | ALT.NET
Thursday, 12 March 2009
I came across this exception today when inserting multiple objects through an NHibernate SessionScope:

NHibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: 0, of class: Foo.Entity.Bar
at NHibernate.Impl.SessionImpl.DoSave(Object obj, Object id, IEntityPersister persister, Boolean useIdentityColumn, CascadingAction cascadeAction, Object anything)
at NHibernate.Impl.SessionImpl.SaveWithGeneratedIdentifier(Object obj, CascadingAction action, Object anything)
at NHibernate.Impl.SessionImpl.Save(Object obj)


I didn't see much out there on this, but Geoff Lane picked up on it pretty quickly. It turns out that my Bar.hbm.xml mapping file had set the id generator incorrectly to "generated", which was a problem because it was actually a MSSQL IDENTITY field. The mapping should have looked like this:


<id name="Id">  <generator class="native" /></id>

Luckily for me, I had run my tests by trying to insert 2 entities inside the session so the error bubbled up right away.

Thursday, 12 March 2009 02:06:02 (GMT Standard Time, UTC+00:00)      Comments [0] -
.NET | ALT.NET
Tuesday, 10 March 2009

Yesterday, I had to upgrade from Spring.NET 1.1 to Spring.NET 1.2 in order to use Quartz.NET. After doing that, I started to get InvalidCastException errors in my unit tests that told me I couldn't convert an int to a Nullable<int>. Things like this were broken:


void TestMe(int? id)
{
// do testing here
}

// and elsewhere, we call it like this
TestMe(42);


Very strange. It turns out that this is a known (and fixed) issue due to using Nullable types through AOP. I grabbed the latest nightly build and all of the tests passed again.

However, when running, I found a breaking change in the post-1.2.0 code that I needed to correct, namely:

Overriding the SessionFactoryObjectName in web.config no longer uses Spring.Data.NHibernate.Support.OpenSessionInViewModule.SessionFactoryObjectName as the key. Now, you need to use Spring.Data.NHibernate.Support.SessionScope.SessionFactoryObjectName. e.g.

<add key="Spring.Data.NHibernate.Support.SessionScope.SessionFactoryObjectName"
value="NHibernateSessionFactory" /> 

Now everything is upgraded and working again.

Tuesday, 10 March 2009 19:02:30 (GMT Standard Time, UTC+00:00)      Comments [0] -
.NET | ALT.NET
Thursday, 02 October 2008

I'll be out in L.A. for PDC 10/25-10/30. If you're going to be there, too, drop me an email!

Thursday, 02 October 2008 16:22:41 (GMT Daylight Time, UTC+01:00)      Comments [0] -
.NET
Tuesday, 15 April 2008

If you want to add Membership Provider features to your WebHost4Life application, I've found that you can't use the aspnet_regsql wizard UI. Instead, use the following code at the command prompt:




Replace NNN with your assigned address, and obviously replace the other elements of the above connection string, too.

Tuesday, 15 April 2008 22:12:01 (GMT Daylight Time, UTC+01:00)      Comments [0] -
.NET | ASP.NET
Tuesday, 25 March 2008

Problem: I have written my own membership provider to store and validate user information. Further, I have a web page that allows a user to come and sign up with a username, password, and a whole host of other client-related data. When the user submits that data, I would like to have them logged in.

Solution: Since I'm using Forms authentication for the ASP.NET website, it appears that the following code-snippet does what I want:

if (Membership.ValidateUser(u.UserName, u.Password))

Tuesday, 25 March 2008 20:24:17 (GMT Standard Time, UTC+00:00)      Comments [0] -
.NET | ASP.NET
Monday, 17 March 2008

Nikhil Kothari wrote a brilliant blog post titled Ajax with the ASP.NET MVC Framework. In that post, he built a demonstration TaskList application that used Ajax and the ASP.NET MVC framework that Microsoft is working on. Microsoft is doing a good job in releasing more frequent updates to this framework, but that means that there will be pain when moving from one release to the next. The ASP.NET MVC Preview 2 release was no exception to this rule. There were a list of documented, tedious and manual steps that one needed to follow to get their old code running with preview 2: update web.config, change the route description, update assembly dependencies, etc.. There were also other items that were not so well-documented:  add ProjectTypeGuids to the csproj file, methods that fell out of the preview 2 release (e.g. ViewFactory.CreateView), etc.

I updated Nikhil's code, and some basic testing shows me that it's working with the preview 2 bits. Download the updated code here. Please leave a comment or send me an email if you see any errors that need to be corrected.

Monday, 17 March 2008 18:21:14 (GMT Standard Time, UTC+00:00)      Comments [0] -
.NET | ALT.NET
Friday, 07 March 2008

ASP.NET MVC Preview 2 was released yesterday. I've had a chance to install and play with it, and I hate to report that I am underwhelmed. My thinking leads me to believe that MS rushed this release out the door just to be able to say they shipped something at MIX. While there has been good progress made on several issues (e.g. medium-trust support, public methods are callable by default, and route setup is improved). However, I find several other things lacking, referenced from ScottGu:

1. Source code is not released. Sure, it might be coming "soon", but why not have everything coordinated and ready to go? Hitting an arbitrary deadline of "ship while at MIX" is less important to me than having answers to questions like these.
2. Dynamic Data (scaffolding) will not work with Preview 2. It is almost always inexcusable to take functionality and features away. The ability to scaffold is one of the coolest things in Rails. Having something similar in ASP.NET was a welcome treat. Now it's gone. Again, I'm sure there is something that will be released "soon", but why not have everything ready to go? I hate not only playing catch up years later, but having a taste of it, only to have it yanked a few weeks later.
3. The "choose your unit testing framework" feature that was hyped up ships with only MSTest enabled. I understand that MS is working to enlist support from the various unit testing groups to add their tool to the list, but it seems disingenuous to post mocked up screen shots with test frameworks in a combo box that were never developed.
4. Others have pointed out some more detailed issues that need solving to help with testability (e.g. see here and here).

I look forward to seeing these issues addressed ASAP because I absolutely LOVE the promise that the MVC bits hold.

Friday, 07 March 2008 19:30:33 (GMT Standard Time, UTC+00:00)      Comments [0] -
.NET | ALT.NET | ASP.NET
Thursday, 06 March 2008

All in all, I was very pleased with the inaugural meeting of the Milwaukee ALT.NET group. We had a turnout of 10 people, which exceeded my expectation in quantity, and the quality was quite good, too. We talked about general architecture topics for about 45 minutes, and then Todd Penland led the group in discussion on persistence and the Unit of Work pattern. We talked about various alternatives to building this yourself (e.g. NHibernate), and talked about the pros and cons of this approach (i.e. requiring a topological sort to deal with database changes properly (something near and dear to my heart from when I was writing code for MIDAS/DataSnap and BDP), handling object graphs, requiring a MarkDirty() call in the property setters, etc.). It was a very engaging discussion. Thanks to everyone who showed up, and to SpiderLogic for providing the refreshments.

Here are the details for next month:

When: Wednesday, April 9, 2008 @ 7pm
Where: 10000 Innovation Drive, Suite 260 (SpiderLogic office)
What: Dan Piessens (who is on the advisory panel for Unity and EntLib 4.0) will cover Unity and EntLib 4.0

I'm looking forward to it, and hope you are, too. If you're planning on being there, please send me an email to dmiser@distribucon.com, or leave a comment here. That way I can plan the food and refreshments accordingly. Feel free to drop me a line on topics you'd like to see covered, too.

Updated to change the date to April 9th. This date change will allow us to hopefully get more exposure thanks to Scott Isaacs and the WI .NET User Group. Thanks, Scott!

Thursday, 06 March 2008 16:35:55 (GMT Standard Time, UTC+00:00)      Comments [1] -
.NET | ALT.NET
Tuesday, 26 February 2008

A co-worker of mine, Brian Kapellusch, is working on a web framework to give us a garden path for ASP.NET applications. The code that he's writing (and the code to use it) is trés elegant. One of the underpinnings of this framework is his use of the ObjectDataSource class (ODS). I am making heavy use of NHibernate and Spring.NET in this application as well. My understanding of the ODS told me that if I wanted to control how the source object was created, that I simply needed to handle the ObejctCreating event and assign the desired object instance in that event to e.ObjectInstance (see here for some more usage examples).

However, it turns out that is not enough to fully control when an object gets created. If you set the TypeName property to a concrete class, ODS will also create a new object behind the scenes - even if you have handled the ObjectCreating event. This becomes very problematic when using an IoC container to automatically build up and inject properties into your class.

The bottom line is this: If you see one version of your object that has things built up properly (because the IoC container was used properly), and one version that has null properties (because, in essence, ODS called "new MyClass()" for you, which doesn't let the IoC container do it's job), you should change the TypeName to point to the interface type instead of the concrete class type. Much thanks to Brian for this one.

Tuesday, 26 February 2008 00:36:54 (GMT Standard Time, UTC+00:00)      Comments [1] -
.NET | ALT.NET
Tuesday, 05 February 2008
I'm using NHibernate a lot more lately, and it's been working great. One of the downsides, though, is the fact that you need to build up the mapping files by hand. Well, no more. I stumbled upon the open source project, active-record-gen, on Google Code. One of the templates that it provides is one that will generate NHibernate mapping files for tables in an MSSQL database. I tried this on a couple of databases and it works rather well.

A few small suggestions:

• Implement a better pluralization/singularization strategy by using Inflector.NET.
• Work with more databases than just MSSQL.
• Allow for the connection string to be built up with more options. Right now, it requires SSPI integration, and attached databases don't work as well as they should. See here for more details.
Tuesday, 05 February 2008 13:57:18 (GMT Standard Time, UTC+00:00)      Comments [0] -
.NET | ALT.NET
Monday, 04 February 2008

This link explains the unit testing tools available in VS.NET 2008 Professional. My take after reading that section is that Microsoft doesn't get it. Here is my list of observations about this section. Feel free to leave a comment to tell me where I'm wrong.

• I feel like this is nothing more than an upsell to get me to go and buy VS.NET TeamSystem. Sorry, that's not going to happen. TeamSystem is way too expensive (both initially and in setup/maintenance time for a TFS server). Besides, we have an existing development infrastructure setup since we use multiple (non-MS) languages/platforms here.
• It looks like MS wants to ignore the thriving and long-standing community of open source unit testing tools. I'm willing to bet that NUnit (and MbUnit, etc.) has more code using it than Microsoft.VisualStudio.TestTools.UnitTesting. Yet, if I want to use the integrated Test menu in VS.NET, I need to rewrite my unit test code to use near-identical attributes for my unit tests (e.g. [TestMethod()] vs. [Test]).
• Code coverage is not available in VS.NET Pro. I guess code coverage isn't something that developers should be doing - well, unless they shell out tons of money to get it done. Thankfully, there are free alternatives, with cheap upgrades to the latest version.
• I want to easily run and debug my unit tests. I know Resharper can do this, but I haven't installed that in VS.NET 2008 due to the number of issues I had with it. (Yes, I know an EAP is coming out soon, but I also have CodeRush and Refactor, which work fine with 2008.) I like TestDriven.net,  but I'd like to be sure that it doesn't go away.
• The documentation is too cluttered. If you're going to give me a list of what's included and what's not included in the Pro version, then why not just separate the documentation to make it easier for me to see what capabilities I have (and what I don't).

In short, it's disappointing that MS has chosen to force people to one specific way of writing unit tests that is against industry norms. ASP.NET has shown me that they do understand the provider model, so why not use it here to allow me to run and debug my unit tests using whatever tools I want.

Monday, 04 February 2008 17:01:31 (GMT Standard Time, UTC+00:00)      Comments [5] -
.NET
Friday, 01 February 2008

I would like to take it upon myself to announce the formation of the Milwaukee chapter of the ALT.NET UserGroup. It will meet the first Wednesday of every month, with the first meeting to take place on 3/5/08 @ 7pm at 10000 Innovation Drive, Milwaukee, WI. Pizza and drinks will be served, and the event will be free to attend. Thanks to SpiderLogic for sponsoring the first meeting.

This group will cover agile development tools and techniques with .NET, best practices for architecture and coding, emerging technologies, and anything else the group decides to cover. For more backstory on ALT.NET, read this post. The use group will be a very participant-driven group. I will not look to lead this group in any significant way, other than to call this group to order, and get people involved in sustaining it. I've learned from other user groups that if a group is too dependent upon one person, it is a matter of time before it fails.

For the first meeting's agenda, I propose we get some volunteers to take on some minimum responsibilities and then break into an OpenSpaces format, where technical topics will be presented by anyone who wants to present. I don't want this to be yet another 1-way presentation medium for 1-2 hour topics, so be prepared to be engaged, discuss, and share (bring your laptop to showcase code and/or slides). I'll take a swipe at talking about ASP.NET MVC this first meeting. If you have something you want to see covered, or especially if you want to cover something, post a comment, and we'll get it on the agenda.

Please pass this notice around to anyone you think will be interested! If you plan on attending, I would appreciate either a comment on this blog or email to dmiser@distribucon.com, just so we can gauge how much food and drink to have on hand. I am really excited about this, and look forward to seeing everyone there!!

Friday, 01 February 2008 21:46:14 (GMT Standard Time, UTC+00:00)      Comments [4] -
.NET | ALT.NET
Tuesday, 29 January 2008

I have a .NET application that generates an XML file via serialization (through XmlTextWriter) and submits the data via https. Recently, they changed something on their end to only accept an upper cased UTF-8 encoding, like this:


<?xml version="1.0" encoding="UTF-8"?>


Unfortunately, using the .NET classes mentioned above, it generates the encoding string in lower case. I could find one mention of this on google, and they said to have the other company change (not an option here), or override XmlTextWriter. I went with that approach, making heavy use of Reflector along the way. I started by looking at the WriteStartDocument method, but realized that the private StartDocument is the thing that generates the output. It also gets called by the overloaded WriteStartDocument, so I'd need to override that method, too. However, in the private StartDocument method, it uses a bunch of private variables and generates output via another private method, InternalWriteProcessingInstructions. Ugly. At this point I realize that XmlTextWriter is not a class made for inheriting.

Back to Reflector, and I notice that the Encoding.WebName is the property used to write out the encoding string. I now create a descendant class of UTF8Encoding. The class is listed below. Now I just call XmlTextWriter, passing in UpperCaseUTF8Encoding.UpperCaseUTF8 for the Encoding type, and everything works perfectly.

    public class UpperCaseUTF8Encoding : UTF8Encoding
{
public override string WebName
{
get { return base.WebName.ToUpper(); }
}

public static UpperCaseUTF8Encoding UpperCaseUTF8
{
get
{
if (upperCaseUtf8Encoding == null)
upperCaseUtf8Encoding = new UpperCaseUTF8Encoding();
return upperCaseUtf8Encoding;
}
}

private static UpperCaseUTF8Encoding upperCaseUtf8Encoding = null;
}
Thursday, 24 January 2008

I had a need to move some VB.NET code to C# today. We're still not at the point where we can just mix and match languages within an assembly, and in this case, it would be more work than I wanted to separate things out. I looked around the net, and the best code converter that I found (read: it successfully converted everything I threw at it, where others failed) was this one.

Thursday, 24 January 2008 15:36:42 (GMT Standard Time, UTC+00:00)      Comments [3] -
.NET
Friday, 11 January 2008

To be sure, this is an incomplete list, but it is a good start. Here's what I don't like about LINQ to SQL:

• It only works with MSSQL. Yes, this point has been beaten to death, but it is entirely justified. Third party solutions don't cut it. LINQ to SQL intentionally seeks to exclude a sizeable population because of this hair-brained decision.
• No way to easily specify adhoc LINQ queries. This doesn't count. I know the benefits of design-time queries, but I should also be allowed to shoot myself to get the added flexibility if I so choose. Building up expression trees is not a viable option for every day development.
• The constant labeling of LINQ to SQL as an OR/M. That label considerably overstates what this technology does. One to one mapping between a table and a class is not really OR/M. It seems like they want to force you to change your database by writing stored procs and views to make your object model better.
• There is no automated way to easily pick up changes to the database schema.
• There is no easy way to preserve changes to the generated code. e.g. I change the name of the automatically generated class from collection_details to CollectionDetails, but I evolve the schema of the table. When I re-add the table, I need to set all of the custom properties again. I know I shouldn't change generated code, but see the next point.
• Speaking of collection_details, it would be much better if the underlying class generator had some options to clean up legacy table names (e.g. remove underscores, camel case resulting table and column names).
• No many-to-many support. In short, when you have an junction table (aka associative table or cross-reference table), you will need to write code like this: User.UserPermissions[0].Permission vs. User.Permissions[0]. Until we see LINQ to Entity (if ever), we do have this, but you can't use the new entity in a LINQ query.
• There is no built-in solution to using LINQ across tiers. I don't want to expose my LINQ classes (see the point above about the tight coupling between database and objects) as I may want to change my database, and I don't want that cascading to all of the places that use it. There is also no diffgram, so even if I did it, I would have to write my own change tracking and resolving support. I went to an OpenSpaces meeting on this very topic during CodeMash, and the consensus was not flattering.

In short, it seems like this part of LINQ was released way before it was ready. But it does demo well...

Friday, 11 January 2008 18:23:26 (GMT Standard Time, UTC+00:00)      Comments [5] -
.NET | LINQ
Sunday, 30 December 2007

I have been reading Dustin Campbell's series, The 12 Days of Refactor! X-mas, with interest. He's a very good writer, and has broken down a bunch of Developer Express features into easy to digest chunks of information.

The episode I linked to above touched on the XML Literal support that shipped with VB in Visual Studio 2008. The one sentence summary of this technology is that it lets the VB compiler translate raw XML in the source code into strongly-typed code using XML classes under the hood. It's a very nice idea, and I encourage you to look at the links to learn a little more about it.

While the VB team thought this was a good idea and added the feature, Anders and the C# team believed that it was superfluous to add such a thing to the C# side. I haven't really made up my mind which group I side with yet. However, Anders is benevolent , so he gave us the little-documented PasteXmlAsLinq addin that will take XML on the clipboard and paste it into a file in C# syntax building the XML up using classes like XElement.

In a default install of VS2008, open C:\Program Files\Microsoft Visual Studio 9.0\Samples\1033\CSharpSamples.zip and extract the LinqSamples\PasteXmlAsLinq files. There is a Readme.html file in there that tells you how to build, install and use the addin.

While this isn't the same as VB's support for XML Literals, it does make things easier to work with.

Sunday, 30 December 2007 23:02:25 (GMT Standard Time, UTC+00:00)      Comments [1] -
.NET | LINQ | XML
Monday, 10 December 2007

At the risk of another "Me, too!" post, I thought I'd highlight several links that I have found to be helpful, and for a value-added bonus, talk about why this release matters to me. Back in the day (oh boy, does that make me sound old!), I learned how to program for the Internet by using straight HTML and Delphi to create CGI and ISAPI extensions. In order to do this, you needed to be quite aware of how the actual protocols worked, and what to do to make things behave as you'd expect. I stayed with web development up until I was using COM objects (again, written in Delphi) from an ASP page. After that, I wasn't into the web development scene much on a full-time basis.

ASP.NET 1.0 and 2.0 came along, and I found them to be quite daunting. It seemed as if it was framework built upon framework, layered with add-ins to do what I thought used to be simple things.

It appears to me that there has been a resurgence to move away from the barrage of constant abstractions, and to instead embrace the simplicity of the web (see the popularity of REST, Rails, and the buzz around ASP.NET MVC for some examples of this).

So for me, the reason I am excited is that not only can I once again utilize my knowledge about how the web works, but I can use it in new ways that will make my applications even better (e.g. TDD, scaffolding, etc.). At any rate, here's the set of links that I think matter for ASP.NET MVC:

Monday, 10 December 2007 20:40:56 (GMT Standard Time, UTC+00:00)      Comments [0] -
.NET | ASP.NET
Friday, 07 December 2007

I wanted to attend CodeMash last year, but waiting until the last minute worked against me. This year I made sure to commit to the event early, so I just signed up and got my hotel reservations sorted out. The sessions look to be pretty deep for a smaller conference, and I'm excited about going there to talk shop.

If you'll be going, drop me a line via comment here, and we'll be sure to sit down and have a beverage or 2. If you're in the Milwaukee/Madison area, and want to chat ALT.NET, it might be a good place to formally plan and launch the Milwaukee meetup.

Hope to see you there!

Tuesday, 27 November 2007

If you see an error like the following:

MSB6006: "NCover.Console.exe" exited with code 1. in build.proj(93, 3)

be sure to check that you are using the correct version of CoverLib.dll. In older versions of NCover (e.g. 1.5.8), by default, this dll should be registered every time the NCover task is run. I haven't found that to be true, though. I had an older version of NCover installed somewhere else on the build machine, and I kept on having my build fail because version 1.5.8 of NCover.Console.exe was loading version 1.5.5 of CoverLib.dll.

By manually registering the correct version of CoverLib.dll, I got the build working again.

Tuesday, 27 November 2007 04:21:48 (GMT Standard Time, UTC+00:00)      Comments [0] -
.NET
Friday, 09 November 2007

Here is my quick and dirty laundry list of issues that I've been having with MSBuild over the past few days.

• You can't detect which target is being executed, therefore conditional execution of tasks cannot be driven by targets. Instead, you need to start a crazy chain of adding targets and updating properties and adding the new target to DependsOnTargets for the original target. No wonder the build file becomes unwieldy so quickly.
• It is very unintuitive and cumbersome to update property values. If I want to set a property one way in one case, and another way in a different case, it is not easy. Besides, the syntax for the CreateProperty task is way more complex than it needs to be to simply update a property.
• Brutal gymnastics are required to get around customizing build properties outside of the confines of the Configuration mechanism for a given project. For example, let's say I want to change the DocumentationFile parameter used in csc.exe, or change the NoWarn directive. If you're calling an MSBuild task on your solution, you need to specify those command-line parameters as /p: parameters from the command-line or track what you want to do and add the actual command-line parameters to the Properties attribute. It should be as simple as overriding the default build properties that exist in the csproj file, but that doesn't work.
• It lacks a way to list descriptive tags for all defined targets (c.f. "nant -projecthelp").

Apparently, I'm not the only one who sees this as a problem. I think Martin's idea of using a lightweight/script language to control the build is the way to go. Granted, I'm coming to this conclusion 4 years after he is, but the point is still valid today. I'd like to have more language elements in my build process to deal with branch, loop and flow so I can react better than I can with an XML file.

My bottom line: MSBuild may be a good tool for VS.NET to use because it can tightly control the format, but it is not a generic solution for controlling a medium-to-big size build process.

Friday, 09 November 2007 16:45:29 (GMT Standard Time, UTC+00:00)      Comments [2] -
.NET
Thursday, 08 November 2007

I've had some conversations with people about the label of ALT.NET. They are of the opinion that it causes controversy by setting up the "elitist" vs. "everyone else" mentality. This is not a new observations (see here and here, e.g.).

I'd like to propose that the divisiveness of the ALT.NET moniker be abolished as quickly as possible. To that end, my proposal for the name is Pragmatic.NET. It's both a state of mind and an homage to the Pragmatic Programmer series that touches on several of the topics important to this group.

Discuss...

Thursday, 08 November 2007 17:54:09 (GMT Standard Time, UTC+00:00)      Comments [2] -
.NET

I'm more than a little disappointed that I missed the ALT.NET conference in Austin, but I'm extremely happy that it looks like the movement has crystallized and gained enough momentum to be a legitimate option for .NET developers. Steve Kronsnoble made an analogy to the Agile Manifesto, where it took a bunch of informal participants and related ideas and turned them into industry standards. Hopefully, when looking back on this event years from now, people will be able to identify this as the genesis of  .NET.

I really like the idea of ALT.NET, and it maps to discussions I've had with many developers about trying to find a "Garden Path" of .NET development. Some percentage of .NET developers will use whatever Microsoft tells them to without question. That's fine, but that's not how I think. I like to grab the best technology no matter where I find it (Open Source, other languages, etc.) . I want to talk about things like NHibernate, Spring.NET, Subsonic, the new ASP.MVC framework, Domain Driven Design, Test Driven Design, Unit Testing, and on and on. To me, that's the excitement of ALT.NET.

To do my part, I'd like to start a discussion on where and when to hold a local Milwaukee version of this OpenSpace conference. If you're passionate about .NET development and want to help shape this new movement in the Milwaukee area, please leave a comment so we can find a way to move the ball forward.

Thursday, 08 November 2007 16:02:04 (GMT Standard Time, UTC+00:00)      Comments [5] -
.NET
Tuesday, 06 November 2007
I've been working more with data-binding and the ObjectBindingSource component that I wrote about here. Here is some stripped-down sample code to help investigate more data-binding concepts.
class Customer {
int Id;
BindingList Orders;
}

class Order {
int OrderNumber;
Product ProductInfo;
}

class Product {
string Vendor;
Product Self;
}
Assume that we want individual GUI components for the Customer object, and a grid to display the associated orders, with the related Product information displayed along with the Order. Here are some quick pseudo-code tips to get things wired up properly.
• CustomerObjectBindingSource.DataSource = typeof(Customer)
• CustomerObjectBindingSource.BindableProperties.Add("Orders"). (If you don't do this, the detail ObjectBindingSource won't work later on.)
• OrdersObjectBindingSource.DataSource = CustomerObjectBindingSource and OrdersObjectBindingSource.DataMember = "Orders"
• DataGridView.DataSource = OrdersObjectBindingSource
• Modify the DataGridView column for Product by setting:
• column.DataSource = ProductsBindingSource
• column.DisplayMember = "Name"
• column.ValueMember = Self
• **IMPORTANT** - Use the same object references everywhere for the product objects (i.e. in the DataGridView column and where you access them in your code). In the sample, I use the productBindingSource component for both the lookup in the grid and the way to lookup individual Product instances. Another alternative that I tested is to use a singleton class for the collection. If you don't do this, you will get the dreaded "DataGridViewComboBoxCell value is not valid" error when the grid tries to populate the Product value.

Tuesday, 06 November 2007 05:26:17 (GMT Standard Time, UTC+00:00)      Comments [0] -
.NET
Sunday, 28 October 2007

Subtitle: How to force .NET Grids to respect Object-Oriented designs

Microsoft clearly intended the DataGridView to be used with databases and primitives. With the company inventing .NET making it difficult to write GUIs with a proper domain model, it's no wonder that the majority of .NET code out there is littered with data-access metaphors.

Take the following code (yes, I know there are fields here, but it takes less space):


public class County{    public County() {}    public string name;    public double taxRate;}
public class CountyTax{    public CountyTax() {}    public County County;    public double Amount;}

There is no way out of the box to get a DataGridView to display and edit the CountyTax object's County and Amount fields. I'd like to have a combo box to display a list of county names, select one, and then enter an amount. Later, I can calculate the tax by multiplying the TaxRate for the selected county and the Amount I entered. In other words, I want to employ good domain design principles.

Here are a couple of solutions, depending on whether or not you want to add extra code to each grid, and use reflection or get some design-time support in a fairly encapsulated solution with faster-than-reflection performance.

I haven't had a chance to check out Orcas, but I can only hope that Microsoft has finally seen the light and will treat object-oriented developers to a fully functioning grid.

Sunday, 28 October 2007 03:59:37 (GMT Standard Time, UTC+00:00)      Comments [1] -
.NET
Friday, 12 October 2007
Here is the target that I used to generate an FxCop report and integrate it seamlessly into the CC.NET web dashboard.

<FxCop
TargetAssemblies="$(TargetAssembly)" RuleLibraries="@(FxCopRuleAssemblies)" AnalysisReportFileName="FxCop.xml" FailOnError="False" ApplyOutXsl="False" OutputXslFilename="Vendor\FxCop\Xml\FxCopReport.xsl" Verbose="False" IncludeSummaryReport="True" WorkingDirectory="$(MSBuildProjectDirectory)"
ToolPath="$(MSBuildProjectDirectory)\Vendor\FxCop"/>  The key here is to be sure that ApplyOutXsl is set to False. If it's set to True, then the output will not get logged into the CC.NET log, which means when the dashboard tries to find it, it won't be there. The other thing of note here is that I have all of my third-party tools, like FxCop, Sandcastle, Enterprise Library, etc. in a Vendor subdirectory of my project. By doing this, I can pick up the one Vendor folder and get another project up to speed quickly (through copying or Subversion externals). Friday, 12 October 2007 16:48:36 (GMT Daylight Time, UTC+01:00) Comments [0] - .NET Thursday, 11 October 2007 When customizing the appearance of the CC.NET Web Dashboard, you often need to modify the file c:\Program Files\CruiseControl.NET\webdashboard\dashboard.config. However, you won't see the changes you make there reflected back in the browser until that file is reloaded. The easiest way to reload dashboard.config is to quickly modify web.config (add a space and delete it), and save. This forces IIS to reload the web application, which in turn causes dashboard.config to give up it's new settings. This is especially useful in a hosted environment where you don't have access to administration-level tools. An alternative would be to just bounce the entire web server by stopping and starting the service, but that's not always feasible nor practical. Thursday, 11 October 2007 18:58:27 (GMT Daylight Time, UTC+01:00) Comments [0] - .NET Wednesday, 10 October 2007 When you need to extract more information from the MSBuild script, you can use the following syntax:  msbuild /v:diag build.proj  There are other verbosity options available, too. Very handy when you need to easily find out what's going on behind the scenes. Wednesday, 10 October 2007 18:36:46 (GMT Daylight Time, UTC+01:00) Comments [0] - .NET Tuesday, 09 October 2007 I'm working a lot on agile .NET project setup right now. One of the standards in this arena is CruiseControl.Net. We also use Subversion and MSBuild, which means we need to use MSBuild Tasks to use the custom Subversion tasks. The documentation for MSBuildTasks is, well, "Open Sourcey". For the Subversion tasks, not all tasks have example MSBuild fragments. In addition, the descriptions of most properties or classes are just one sentence circular summaries. For example, if you need to commit just one file inside the MSBuild script, you would use the SvnCommit task. You might do this as part of a depoyment process where you set version numbers on files before creating an installer. This is the snippet that I finally settled on to update just that one file: <ItemGroup> <CodeFiles Include="Properties\AssemblyInfo.cs" /></ItemGroup><!-- Later on, inside a Target, use this --><SvnCommit Targets="@(CodeFiles)" Message="$(CCNetLabel)"   Password="pwd"   UserName="user" />

The reason for this is that SvnCommit descends from SvnClient, which is too generalized of a base class. For example, the SvnCommit.RepositoryPath property does not work as one might expect. Specifically, in my case, when I specified the RepositoryPath attribute in the msbuild file, I received the following error. It turns out that you should just not specify the RepositoryPath attribute at all (see the documentation for "svn help commit" to see that a URL is not passed in on the command-line, but rather, svn figures out the URL from the working copy).
    svn: 'svn://x.y.z/project/trunk' is a URL, but URLs cannot be commit targets

Also, SvnCommit.LocalPath should not be used. It ends up generating a command-line similar to the following, which ends up committing everything in the LocalPath and down. Remember, all I wanted was to update one specific file, so it turns out that the LocalPath attribute is getting in the way here.


svn.exe commit "full\path\to\my\working\directory" 
  "Properties\AssemblyInfo.cs" --username user --password pwd 
  --message "1.8.1.2" --non-ineractive --no-auth-cache


To sum up:

• Don't specify the RepositoryPath attribute in an SvnCommit task
• Don't specify the LocalPath attribute in an SvnCommit task
• Specify a ToolPath entry that points to the folder that holds svn.exe if it's not in the default location (c:\Program Files\Subversion\)
• Setting the Verbose attribute does not work because it is defined as a nullable boolean

Edited on 10/10/2007 for clarity due to comments made by Steve Trefethen. Thanks, Steve!

Tuesday, 09 October 2007 20:46:22 (GMT Daylight Time, UTC+01:00)      Comments [0] -
.NET
Wednesday, 22 August 2007
I was getting a strange problem at a client's site recently where on occasion, an ASP.NET application that called a web service would throw different exceptions. The fact that I could claim "It works on my machine" meant little consolation. Stranger still, when debugging the application, it would blow up at different spots. When it finally blew up on a call to Response.Redirect, the client suddenly remembered some code that he used in a similar situation before. The theory was that there is some kind of misconfiguration in the servers somewhere, so this should not be needed, but this work-around has since been added and no additional errors have been reported.



// svc is a WebService that you would use in your ASP.NET applicationsvc.Proxy = new System.Net.WebProxy("127.0.0.1");((System.Net.WebProxy)svc.Proxy).BypassList = new string[] { "NameOfLocalMachine" };

Wednesday, 22 August 2007 19:02:12 (GMT Daylight Time, UTC+01:00)      Comments [0] -
.NET | ASP.NET
Friday, 15 June 2007
If you've come across this error when starting up an application, be sure to check the format of your app.config file. It turns out that this exception is of the type System.Configuration.ConfigurationErrorsException.

The real problem was that I had ended up generating a malformed config file (see the schema in c:\Program Files\Microsoft Visual Studio 8\Xml\Schemas\DotNetConfig.xsd) by putting configSections after appSettings. Once I put the configSections element back to the top of the config file, everything was fine again.

Friday, 15 June 2007 04:48:41 (GMT Daylight Time, UTC+01:00)      Comments [1] -
.NET
Wednesday, 13 June 2007
I recently created a Windows Service using .NET, and in order to install the service, you need to execute this command:
installutil myservice.exe

However, when I did this, I received a System.BadImageFormatException. It turns out that my PATH settings were still pointing to the 1.1 .NET framework tools. Changing the PATH to point to .NET 2.0 (c:\Windows\Microsoft.Net\Framework\v2.0.50727) fixed the problem and the service can now register successfully.

Wednesday, 13 June 2007 16:06:38 (GMT Daylight Time, UTC+01:00)      Comments [1] -
.NET
Tuesday, 29 May 2007
I hate when we lose functionality in applications. I'm writing a pretty classic ASP.NET application right now. One assembly is the Data Access Layer, and I try to write enough unit tests to actually show that things stand a chance of working (both now and in the future). Also, I occasionally like to work at home, disconnected from work's servers (database and other). That means that I have MSSQL installed on my laptop, which has local copies of the databases that I would need. I also have my web.config checked into source control so others on the team can do a simple checkout and have the web site working with a simple build of the MSBuild script. Given that setup, how would one go about being a responsible unit tester? It seems that what I want is a way to set a default connection string in the main config file, and allow a user.config to (optionally) exist. If it did exist, it could override the settings that were in the main config file to point to a new database.

There is a new attribute, configSource, that looks promising because it can be used to redirect .NET from looking at the app.config (or web.config) and instead make it look at an arbitrary generic user.config file for its content. The problem with this approach is that it requires every machine to have this user.config file in the same place. What I want is more like what the old file attribute of appSettings provided. Unfortunately, the new tools in ASP.NET 2.0 get the connection string information from the connectionStrings section, so using the appSettings approach is out-dated.

For now, I'll use configSource, but it is a pain to have to tell each memeber of the dev team that they need to create their very own user.config file and place it in a certain directory, since this usage means that you wouldn't want to check user.config into your source control system.

Take a look at J.D. Meier's paper, How To Reference Web Services and Databases During Development, for some concrete samples on how this looks.

Tuesday, 29 May 2007 18:54:59 (GMT Daylight Time, UTC+01:00)      Comments [1] -
Thursday, 17 May 2007
I've been spending a lot of time on .NET 3.0 lately. One of the areas that is a lot of fun for me to dig into is WPF, since it's such a departure from my usual data/service/remoting pigeon-hole. I know a lot of people hate grids as a metaphor, but when I saw this free WPF grid demo, I knew grids would be with us for yet another generation of user interfaces. Long live the grid!!
Thursday, 17 May 2007 14:59:02 (GMT Daylight Time, UTC+01:00)      Comments [2] -
.NET
Thursday, 22 March 2007
The following application shows a subtle difference in dealing with enums using Enum class methods and when using reflection. In this sample, I am looking to find the number of elements in the enum. Enum.GetValues and Enum.GetNames are not implemented in the .NET Compact Framework, so I cannot use those methods.

By using reflection, I figured I would gain the upper hand and take control of my enum woes. Unfortunately, calling GetFields on an enum type adds an extra entry named "value__" to the returned list. After browsing through the decompilation of Enum, I found that value__ is just a special instance field used by the enum to hold the value of the selected member. I also noticed that the actual enum members are really marked as static. So, to get around this problem, all you need to do is call GetFields with the BindingFlags set to only retrieve the public, static fields (see the code example below).


using System;using System.Reflection; namespace EnumReflection{    class Program    {        enum Test        {            One,            Two,            Three        }         static void Main(string[] args)        {            Type enumType = typeof(Test);             //The following prints 3, but we can't use this method in .NET CF            Console.WriteLine(Enum.GetValues(enumType).Length);             FieldInfo[] infos;            infos = enumType.GetFields();             //The following prints 4! There is an extra, unrelated Int32 entry named "value__"             //at the zeroth element of the info array.            Console.WriteLine(infos.Length);             //The following prints the 3 enum elements. The value__ field is removed by             //specifying we only want the public, static fields.            infos = enumType.GetFields(BindingFlags.Public | BindingFlags.Static);            foreach (FieldInfo fi in infos)            {                Console.WriteLine(fi.Name);            }        }    }}
Thursday, 22 March 2007 16:16:48 (GMT Standard Time, UTC+00:00)      Comments [0] -
.NET | Compact Framework
Thursday, 15 March 2007
I needed to implement a dialog that could be used to stop from displaying over and over again. We've all seen countless variations on this theme. I also didn't want to go to the extent of using hooks to accomplish this.

I came across the SHMessageBoxCheck function, and it appears to give me what I need. Granted, it is far from perfect, but it works for me. I used the declaration from PInvoke.net, but I received a PInvokeStackImbalance exception from MDA. I modified the DllImport to use PreserveSig to true, and the error is gone. I did update the wiki to mention this finding, so hopefully others will be able to verify.

All in all, this function works well. But, by trying to be lazy and use a pre-existing solution, it definitely took longer than it would have had I written my own custom dialog. I'm sure that won't be the last time that happens.

Thursday, 15 March 2007 14:49:05 (GMT Standard Time, UTC+00:00)      Comments [1] -
.NET
Thursday, 08 March 2007
I read Scott Hanselman's well-written article HOW TO: Debug into a .NET XmlSerializer Generated Assembly. I can add a few more little (and most likely obvious) things to his article:
• This still works in .NET 2.0.
• If you just do an Add New Item to add a new Application Configuration File to your project in VS, you can just paste the debugging flags in, and the config file will get deployed to the application directory automatically.
• You can just Step Into (F11) the call to x.Serialize, and you will be taken into the proper generated file. You may want to open the file manually as Scott mentioned, but I find it to be faster to press F11, and then go to the place in the file I want to debug.

In the end, we ended up writing our own serialization for .NET CF due to one too many bugs.

Thursday, 08 March 2007 20:26:21 (GMT Standard Time, UTC+00:00)      Comments [0] -
.NET | XML
Wednesday, 21 February 2007
A while back, I wrote about how to use the Data Access Application Block (DAAB) in the Compact Framework. While this code works just fine, it turns out that Enterprise Library 3.0 will support this natively. I really like the TableExists method that they added, too.

Wednesday, 21 February 2007 23:23:26 (GMT Standard Time, UTC+00:00)      Comments [0] -
.NET | ADO.NET | Compact Framework
Monday, 19 February 2007
The following code assigns DateTime.MaxValue to a parameter. When trying to run this code against the Northwind databse, it will produce the error, "An overflow occurred while converting to datetime".



SqlCeConnection conn = new SqlCeConnection(connStr);conn.Open();SqlCeCommand cmd = new SqlCeCommand("select * from employees where [Hire Date] < @paramDate", conn); SqlCeParameter paramDate = cmd.CreateParameter();paramDate.ParameterName = "@paramDate";paramDate.DbType = DbType.DateTime;paramDate.Value = DateTime.MaxValue;cmd.Parameters.Add(paramDate); SqlCeDataAdapter da = new SqlCeDataAdapter(cmd);DataTable tbl = new DataTable();da.Fill(tbl);dataGridView1.DataSource = tbl; conn.Close();


Note that this fails when using MSSQL Compact Edition (MSSQLCE) under a standard WinForm application and a Pocket PPC platform. The same code against a standard desktop MSSQL version will work fine.

The workaround is simple. Just get away from the MaxValue. Of course, this is a workaround, so it's not perfect, but it certainly works for my needs.



Monday, 19 February 2007 15:37:16 (GMT Standard Time, UTC+00:00)      Comments [0] -
Thursday, 08 February 2007
I was banging through some quick and dirty sample applications today, in preparation for a talk on LINQ tonight. One of my old LINQ to SQL demos shows how to use the external xml mapping file. I also blogged about this before. Today, I kept getting the following error whenever I would run with an external xml mapping file:
The type 'Order' is not an entity.

I was using the following command line to generate the xml mapping file:

SqlMetal /server:(local) /database:Northwind /map:Northwind.xml /code:Northwind.cs /pluralize

Looking at the resulting xml file, I finally noticed this section:


<Table Name="Orders">
<Type Name=".Order">


Notice the leading dot before the type name attribute. That's the problem. So I went back and added the /namespace switch to the sqlMetal command line, and now all is well with the world again. Granted, this problem is the result of me doing demo work, and not production work, but it's still a little bit irritating. Then again, I'm still running the May 2006 CTP on VS2005, so for all I know, MS has already fixed all of this with a subsequent release of a build in Orcas.

Thursday, 08 February 2007 19:23:16 (GMT Standard Time, UTC+00:00)      Comments [0] -
.NET | LINQ
Wednesday, 31 January 2007
I had a requirement to make a list of objects be displayed in some kind of a grid metaphor. I've used the DataGridView before, and even written some blog entries on extending it (check out the cool Search feature on my blog for more information). However, all of my grid usage had been limited to database-related use.

What I needed was a way to easily get filtering and sorting working for the list of objects. I found 2 links that helped me out a ton. The first one is Building a Drop-Down Filter List for a DataGridView Column Header Cell. This article is incredibly well-written and talks about the different interfaces you need to implement, and provides a sample, too. For the sorting, I used Brian Noyes' BindingListView class from Chapter 9 of his excellent book, Data Binding with Windows Forms 2.0.

When stitching these 2 pieces together, I noticed several things:

• The DataGridViewAutoFilterColumnHeaderCell.UpdateFilter method was adding square brackets around the property names for some reason. I can't tell why this was being done, but my guess is it had to do with spaces in database column names. Since I'm not using it for that purpose, I removed the brackets. The other approach would have been to adjust the BindingList.UpdateFilter method to deal with the brackets, so I may revisit this in the future.
• The BindingListView.UpdateFilter needed some minor modifications. I added a precondition guard check to make sure m_FilterString is not null. It looks like the DataGridViewAutoFilterColumnHeaderCell class will call back to the BindingListView class more frequently than Brian had anticipated.
• I adjusted the setter of the IBindingListView.Filter property to remove the filter if it gets set to String.Empty or null.
string IBindingListView.Filter{    get    {        return m_FilterString;    }    set    {        if (string.IsNullOrEmpty(value))            ((IBindingListView)this).RemoveFilter();        else        {            m_FilterString = value;            m_Filtered = true;            UpdateFilter();        }    }}

• You need to build up your collection of objects using BindingListView
• You must use a BindingSource to link between your collection and the DataGridView by setting dataGridView1.DataSource = myBindingSource.

By doing all of this, I got things working the way I wanted. Now it's time to tackle the next task of getting child objects bound properly in a DataGridView.

Wednesday, 31 January 2007 20:48:22 (GMT Standard Time, UTC+00:00)      Comments [1] -
.NET
Wednesday, 24 January 2007
I came across EViL last week when looking into simplifying validation of domain objects. This open-source project is done very well. Dave Donaldson introduced EViL last month.

In a nutshell, it's a library that provides attribute-based enforcement of business rules on your entity objects. It comes with a bunch of pre-defined attributes to handle common scenarios (e.g. a field is required, a field should have a maximum length, a field should match a certain regex, etc.). It also easily allows for adding new, custom rules.

The thing I like best about this project is that it doesn't force you into descending your classes from some super class. You can do that if you want, but it will also work if you want to leave your classes alone. All in all, I would highly recommend looking into using EViL in your .NET applications.

Wednesday, 24 January 2007 20:57:44 (GMT Standard Time, UTC+00:00)      Comments [1] -
.NET
Friday, 19 January 2007
MSSQLCE has a built-in limitation that it will not work when used inside an ASP.NET application. According to the MSDN documentation for SqlCeConnection, this is due to the fact that the code wasn't written with this scenario in mind. I have seen tools be used outside of the intended use many times over my career, so I understand where the team was coming from. I am even more impressed that they put a simple check in place to allow you to effectively say "I know what I'm doing better than you do, so let me do it anyways".

In order to enable this behavior, simply add one line of code to your application:


AppDomain.CurrentDomain.SetData("SQLServerCompactEditionUnderWebHosting", true);


Steve Lasker has a good write up of this, too. The bottom line is this isn't recommended, so be sure to fully understand the implications before blindly enabling this parameter.

Friday, 19 January 2007 20:52:02 (GMT Standard Time, UTC+00:00)      Comments [0] -
.NET
Tuesday, 16 January 2007
I just went through the very lengthy process of moving from MSSQLCE beta to MSSQLCE release. The good news is that after I was done, all of my code still worked, so at least I have that going for me.

The biggest time sink for me was uninstalling applications. Uninstalling the patch from VS2005 Pro was not all that straight-forward. First, I had to re-download and burn the ISO image since I couldn't find my original DVD. I then noticed that I had another entry in my Add/Remove Programs called "Microsoft Visual Studio 2005 Permier Partner Edition - ENU" that had the VS.NET SP1 Beta applied to it. I had no idea how this program got installed, and that took quite a bit of spelunking to figure out. I came across a blog entry from Heath Stewart that explained how to look into the patch database to figure out which MS patches were applied to which products. After installing that, it needed a Windows Installer Patch (msp) file, but I couldn't find that. I ended up searching my system, and got the VS.NET msp file and opened it in Heath's utility. From there, I got the GUID of the Premier Partner Edition, and searched my registry. In the end, it turned out to be MSSQL 2005 Developer Edition that installed that program. I finally located that DVD, pointed the uninstaller to the right msi file, and I was able to uninstall the patch. However, after completing all of this, I couldn't install the MSSQL Server 2005 Compact Edition Tools for VS 2005 SP1. I received the same error as I did last time (see the above link for details), but I couldn't solve it by doing a Repair on VS.NET, and I couldn't dig anything up in Filemon or Regmon to find out why it was failing so I ended up completely uninstalling and reinstalling VS.NET. Not exactly very user-friendly.

Installing the release of MSSQLCE is very similar to the post I made earlier on how to install MSSQLCE. The difference is the links to the new files, which can be found here:

Tuesday, 16 January 2007 16:45:46 (GMT Standard Time, UTC+00:00)      Comments [0] -
.NET | Compact Framework
Thursday, 11 January 2007
In Delphi, if you want an array of integers, indexed by an enumeration, you simply do this:

type
TSuit = (Clubs, Spades, Hearts, Diamonds);
var
CardCount: array[TSuit] of integer;
...
CardCount[Clubs] := 13;


In .NET, however, you can not specify an enumerated type as the indexer into an array, so a line by line conversion to C# will not work. Instead, you need to create an entirely new helper class to make the calling code more readable (i.e. without putting casting code in all of the uses of the indexer). Furthermore, you can't use the code below in a Compact Framework (CF) application, because Enum.GetValues() and Enum.GetNames() aren't implemented in the CF libraries.



class Program{    static void Main(string[] args)    {        CardCounter cc = new CardCounter();        cc[Suit.Clubs] = 13;    }} public enum Suit {Clubs, Spades, Hearts, Diamonds}; public class CardCounter{    private static int enumCount = Enum.GetValues(typeof(Suit)).Length;    private int[] counts = new int[enumCount];     public int this[Suit suit]    {        get { return counts[(int)suit]; }        set { counts[(int)suit] = value; }    }}

Thursday, 11 January 2007 14:47:32 (GMT Standard Time, UTC+00:00)      Comments [0] -
.NET
Wednesday, 10 January 2007
XML serialization is handy, but it does lack some power. For example, if you have class inheritance, and you want a property of the child class to have a different name than the one given to it by the parent, you will get an error at run-time when trying to serialize the object: "Member 'Derived.Name' hides inherited member 'Base.Name', but has different custom attributes.".

Assume you have a class structure like this:

public abstract class Base{    private int id;    private string name;     [XmlElement("id")]    public int Id    {        get { return id; }        set { id = value; }    }     [XmlElement("name")]    public virtual string Name    {        get { return name; }        set { name = value; }    }} public class Derived : Base{    [XmlElement("newName")]    public override string Name    {        get { return base.Name; }        set { base.Name = value; }    }} 

 To see the error, call it like this:

static void Main(string[] args)

{    Derived d = new Derived();    d.Id = 23;    d.Name = "Dan";    string xml = GetXMLFromObject(d);    Console.WriteLine(xml);}

Wednesday, 10 January 2007 17:57:12 (GMT Standard Time, UTC+00:00)      Comments [1] -
.NET | XML
Tuesday, 09 January 2007
Some times, it is better to have a minimal format for your XML file. When using XmlSerializer, it likes to add the standard XML namespaces to the generated XML file. If you want those gone, use code like this:
public static string GetXMLFromObject(object obj){    XmlSerializer xs = new XmlSerializer(obj.GetType());     // Set up chain of writers    StringBuilder sb = new StringBuilder();    using (XmlTextWriter writer = new XmlTextWriter(new StringWriter(sb)))    {        writer.Formatting = Formatting.Indented;         // Remove standard namespace attributes        XmlSerializerNamespaces xsn = new XmlSerializerNamespaces();        xsn.Add(string.Empty, string.Empty);        xs.Serialize(writer, obj, xsn);    }     return sb.ToString();}

The key is to create an XmlSerializerNameSpaces object, populate it with empty strings, and then pass it to the XmlSerizliazer. The result is a more compact XML file. Note that this works, despite the comment in the documentation explicitly saying that it isn't supported.

You can also use this class to add your own custom namespaces. This could be useful to prefix certain elements with a certain namespace.

Tuesday, 09 January 2007 15:52:45 (GMT Standard Time, UTC+00:00)      Comments [0] -
.NET | XML
Monday, 08 January 2007
While the XmlIgnore/Specified pattern to control serialization is very useful, it could be overkill for simpler serialization scenarios.

When you create an object with a bool field, that field is initialized and defaulted to the value of false. Under normal conditions, this value will get serialized every time. However, what if we only care about capturing that value when the value is true? It turns out that we can use DefaultValueAttribute. The first thing that may stand out to you is that this attribute lives in the System.ComponentModel namespace, and not in an XML namespace. The online help also mentions that this is used for visual designers and code generators. XmlSerializer also uses this attribute to decide whether or not to stream the value during serialization, since it's really a form of a code generator (more on that in a later post). If the value of the field or property matches the value that you specify in the DefaultValueAttribute, then that property will not be streamed.

Using an XmlAttributeAttribute, you can specify that a certain property will be expressed as an XML attribute instead of an XML element. To demonstrate both of these concepts, see the following code:

public class Url{    [XmlAttribute("address")]    public string Address;
[XmlAttribute("primary"), DefaultValue(false)]    public bool Primary;
public Url()    {    }}
static void Main(string[] args){    Url u = new Url();    u.Address = "http://testing/";    string xml = GetXMLFromObject(u);    Console.WriteLine(xml);}

This produces roughly the following output (XML namespace information is stripped here. I will show how to do this in code with a future post). Notice that the Primary attribute is not generated because it matches the DefaultValue.

<?xml version="1.0" encoding="utf-16"?><Url address="http://testing/" />

Monday, 08 January 2007 15:09:43 (GMT Standard Time, UTC+00:00)      Comments [0] -
.NET | XML
Friday, 05 January 2007
David Hervieux posted a link to some Serialization FAQs in a comment to my last post. This material is good, and actually forced me to go back through what I wanted to cover, since I didn't want to just add posts that duplicate what can be found easily on the web. I'll still move forward with a few items in XML serialization that I think are unique.

The XMLIgnore attribute is used to tell the XmlSerializer that this field is transient, and should not be (de)serialized. The most typical use for this would be to mark calculated fields with this attribute. This is an easy customization that helps your serialization process, but it leaves a bit to be desired. It's an "all or nothing" approach, where the property is either streamed or not.

This MSDN article hints at what to do to get more fine-grained control of this aspect of serialization. Basically, you create a public boolean field or property named propertyNameSpecified for the property you want to control. The XmlSerializer uses this convention to determine whether or not to include the associated property for serialization. Since this new Specified field will be eligible for serialization, be sure to mark it with the XmlIgnore attribute to prevent it from being serialized.

A very simple code listing showing how this all fits together:

    public class Player    {        private int number;        private string name;
[XmlElement("jerseyNumber")]        public int Number        {            get { return number; }
// You could add more logic here to only set NumberSpecified based on some criteria            set { number = value; NumberSpecified = true; }        }
[XmlElement("playerName")]        public string Name        {            get { return name; }            set { name = value; }        }
[XmlIgnore]        public bool NumberSpecified;    }
The downsides to using this techniques are: 
• It requires another field, and some custom logic to make this work.
• It requires that the Specified field be marked as public, exposing it to consumers of the library. There is no real reason why the XmlSerializer couldn't use reflection to get at a non-public member.
• If you use a property, it must be a full read-write property. A read-only property could very well suffice here, and make your code easier to maintain.

• Friday, 05 January 2007 19:37:20 (GMT Standard Time, UTC+00:00)      Comments [2] -
.NET | XML
Wednesday, 27 December 2006
Serializing between .NET objects and XML files, and vice versa, is extremely easy, yet flexible and powerful. I'll be blogging a few entries about this topic in the days to come. This entry will set the stage, showing the basics of XML serialization.

Assume you have a (stripped down) class definition like this:

public class Player

{

[XmlElement("jerseyNumber")]

public int Number { get; set; }

[XmlElement("playerName")]

public string Name { get; set; }

}

And you wanted to read/write an XML file that looked like this:

<Player>

<jerseyNumber>23</jerseyNumber>

<playerName>Dan</playerName>

</Player>

The key to making this happen is the XmlSerializer class. This is the class that will convert between public properties and XML elements. You can also decorate your class with simple attributes to coerce your class into generating custom XML (i.e. XML attributes, hide or rename elements, etc.).

Here are a couple of helper methods, and a sample that uses them to show you how all of this comes together.

static string GetXMLFromObject(object obj)

{

XmlSerializer ser = new XmlSerializer(obj.GetType());

StringBuilder sb = new StringBuilder();

using (XmlTextWriter writer = new XmlTextWriter(new StringWriter(sb)))

{

writer.Formatting = Formatting.Indented;

ser.Serialize(writer, obj);

return sb.ToString();

}

}

static object CreateObjectFromXML(string xml, Type xmlType)

{

XmlSerializer ser = new XmlSerializer(xmlType);

object obj = null;

{

}

return obj;

}

static void Main(string[] args)

{

Player p = new Player();

p.Number = 23;

p.Name = "Dan";

string xml = GetXMLFromObject(p);

Console.WriteLine(xml);

Console.WriteLine();

Player q = (Player)CreateObjectFromXML(xml, typeof(Player));

Console.WriteLine(q.Number + " --> " + q.Name);

}

Other references:
XML Serialization in the .NET Framework

Wednesday, 27 December 2006 17:05:11 (GMT Standard Time, UTC+00:00)      Comments [1] -
.NET | XML
Wednesday, 13 December 2006
I just finished reading this book by Jimmy Nilsson, and I have a mixed review of it. The general consensus (e.g. see here and here) out there is that this book is one of the most fantastic books out there on how to architect systems using C#. I do agree that the book is well-written, with a very unique insight into the thoughts and decisions to make along the way in designing a robust application from an OO viewpoint. It got me thinking about how I view TDD and architecture from a domain model perspective.

The negative for this book outweighs the benefits, in my opinion. The fact that there is no sample/reference application leaves the reader frustrated. If the design techniques can't even be proven in a simple application that was discussed over 450 pages, how can one have faith to apply the techniques in their own production applications? I searched on the book's forum, but the general attitude there is "If you need a sample, you can't understand all the decisions made to create your own application". My reply to that is "Hogwash". As mentioned earlier, 450 pages were used to talk about why certain architectural decisions were made.

All in all, I would skip this book until the major deficiency of no sample application is fixed.

Wednesday, 13 December 2006 16:42:00 (GMT Standard Time, UTC+00:00)      Comments [0] -
.NET
Tuesday, 12 December 2006
When John Kaster of CodeGear (formerly Borland) came to Milwaukee last year, he showed a demo of some software running on a Pocket PC (PPC). The cool part was he was working on the actual PPC device itself but broadcasting the PPC screen to the overhead projector through his laptop.

I checked with him this week as I'm doing more work in this area now, and he told me that the free tool to get this done is called ActiveSync Remote Display. It is part of the Windows Mobile Developer Power Toys, available from Microsoft. I also tested it this week, and I can report that it still works with Active Sync 4.2.

Tuesday, 12 December 2006 14:36:00 (GMT Standard Time, UTC+00:00)      Comments [0] -
.NET | Compact Framework
Friday, 08 December 2006
Rory Blyth has a couple of good videos on MSDN TV, showing how to use MSSQL Mobile Edition on a CF device. They are older, so they don't cover all the new nomenclature (and probably newer features), but there are a couple of good tips and tricks in there, and it contains good coverage of Remote Data Access, a technology that will help synchronize data to/from MSSQL Compact Edition.

Friday, 08 December 2006 15:56:00 (GMT Standard Time, UTC+00:00)      Comments [0] -
.NET | Compact Framework
Thursday, 07 December 2006
Here's my experience getting this combination of tools to work properly. At times, it was extremely frustrating, and other times it was confusing. MS has not helped much what with obsolete, out-dated, mis-named, and near impossible to find products. Hopefully the RTM version will have everything stitched together nicely so all you have to do is double click a setup file. It would be even better to have log information easily and readily available for the installs. If you want to develop with these technologies, give these steps a try. I don't claim that they are authoritatve or complete, but I documented as much as I could capture.

1. ActiveSync Setup 4.2 - required for several other installs later on.
2. Windows Mobile 5.0 PPC SDK - adds new platform targets and emulators to support PPC development with WM 5.0. There is also a Windows Mobile 5.0 SDK for Smartphone download available if you prefer that instead.
3. VS.NET 2005 SP1 Beta - I couldn't get to this page from the MS site anywhere, but I was able to find a link to take me to the download location. I can't swear that this is entirely required, as I installed the other tools without it on one PC, and it seemed to work OK.
4. Microsoft SQL Server 2005 Everywhere Edition Tools for Visual Studio 2005 Service Pack 1 Beta - This install specifically states that VS.NET SP1 Beta is required. As you can see from the title, it also mentions SqlServer Everywhere, but ignore that inconsistency. The MSSQL team has renamed the product to SQL Server Compact Edition. This naming problem is supposed to be fixed by the time MS releases MSSQL Compact Edition.

I also ran into a problem when uninstalling this application. I would get the following error when trying to reinstall it:


The upgrade patch cannot be installed by the Windows Installer service
because the program to be upgraded may be missing, or the upgrade path
may update a different version of the program. Verify that the program
to be upgraded exists on your computer and that you have the correct


I finally did a Repair install on VS.NET, and I was able to install the tools again.

However, even with all of that, I would recommend installing this because it allows for things like Server Explorer to be used on SDF files.

5. Microsoft SQL Server 2005 Compact Edition RC1 - This installs MSSQL Compact Edition. Note that there are numerous naming changes throughout the web (Mobile, Everywhere, Compact), but Compact Edition is going to be the final answer - allegedly.
6. Windows Mobile 5.0 SDK for Pocket PC - This install will give you some more power within the IDE, e.g. it will bring up the Data Configuration Wizard to generate DataSets when adding an SDF to your project. It also installs the latest version of Northwind.sdf for you to play with. By default, it gets installed to C:\Program Files\Microsoft Visual Studio 8\SmartDevices\SDK\SQL Server\Mobile\v3.0\northwind.sdf.
7. (Semi-optional) SQL Server 2005 Compact Edition Books Online Community Technology Preview (CTP) - Reference information is always good, right?

• You can manage an SDF file from your desktop machine, by using Server Explorer within VS.NET, or by selecting SQL Server Mobile as the Database Type in SQL Server Management Studio. On the PPC device, you can use QueryAnalyzer (located at /Program Files/SQL Mobile/EN/isqlw30.exe), or open the sdf file on the PPC device.
• To deploy an SDF to the PPC, just add it to your solution and it will get deployed to the PPC device automatically.

Good luck, and I hope this helps someone through the corn field maze that is CF and MSSQL CE installation.

Thursday, 07 December 2006 14:59:00 (GMT Standard Time, UTC+00:00)      Comments [0] -
.NET | Compact Framework
Saturday, 02 December 2006
CopyAsHTML is a VS.NET 2005 add-in that will take source code from VS.NET, and copy the pretty-printed version as compliant HTML code. It also works with things like XML.

The quote on their web site has proven to be true for me so far:
"If Visual Studio can highlight it, CSAH can copy it, and your source should look the same in your browser as it does in your editor."

Saturday, 02 December 2006 22:44:00 (GMT Standard Time, UTC+00:00)      Comments [1] -
.NET
Thursday, 14 September 2006
As a follow up from my post yesterday, I have some work-arounds to get me past the problem. I still don't have the ultimate answer for why Math.Log(0.0) throws an exception only when called from COM interop, but I can at least move forward again.

I started out by changing the actual code in Lucene to simply avoid the Math.Log(0.0) statement. However, I started to worry about forking the code. I don't want that kind of maintenance headache as new versions of Lucene continue to come out. I was able to work things out so that I could descend a couple of classes, override some methods, and plug these into my API layer, and everything worked fine.

The one problem left was the arithmetic overflow that I got later on in the Lucene code. I was talking with Chris Bensen, and he recalled running into something similar before and sent this link to MSDN on _controlfp documentation. I implemented the following code in .NET in the constructor of my API layer, and the overflow error went away, but of course, I end up getting NaN results due to the new FPU masking behavior. I'll have to test thoroughly to make sure that this doesn't impact calculations further down the line.


[DllImport("msvcrt.dll")] private static extern int _controlfp(int IN_New, int IN_Mask); // this imports the call
private const int _MCW_EM = 0x0008001f;
private const int _EM_INVALID = 0x00000010;

public LuceneAPI()
{
// Add this code to squelch arithmetic overflow/underflow exceptions spawned from the FPU.
_controlfp(_MCW_EM, _EM_INVALID);
}


I still would like to find out the technical details for why I need to do any of this, but at least I have things running.

Thursday, 14 September 2006 16:58:00 (GMT Daylight Time, UTC+01:00)      Comments [2] -
.NET
Tuesday, 12 September 2006
When creating .NET classes that will be accessible via COM Interop, you need to be sure to add a default constructor to the class. If you don't, regasm will end up generating the tlb without the CanCreate flag for that class, and therefore, when registering the tlb, those classes will not be registered.

Yes, this makes sense, and yes, this is covered in MSDN, but I thought I'd mention it here, as it recently tripped me up for a little while.

Tuesday, 12 September 2006 21:35:00 (GMT Daylight Time, UTC+01:00)      Comments [0] -
.NET
Wednesday, 30 August 2006
I've been tasked with adding text searching through documents to our application. Since we need to support multiple databases, I didn't want to use the native DBMS indexing options. Looking around, I came across Lucene.Net. It is an open source port of the Java version of Lucene, which is a lightning fast search engine over indexes of documents. The list of features is rather extensive, but my favorite feature would be the advanced search capabilities, including proximity search. There is also a very impressive open source project based on Lucene.Net called SeekAFile which adds functionality over Lucene.Net, and works extremely well, too.

I wanted to centralize the index storage of Lucene.Net, though, since it would be possible to have multiple app servers located in different physical locations, and allowing access from one machine to another could prove problematic. This meant that storing the index to the central database. I found a source code sample that would do this on a Firebird database. I have now converted that to work with MSSQL and Oracle, and it works very well. Yes, it's a bit slower than using the native file system directory provided with Lucene.Net, but it solves the problem we set out to solve.

Wednesday, 30 August 2006 16:22:00 (GMT Daylight Time, UTC+01:00)      Comments [8] -
.NET
Wednesday, 02 August 2006
After writing a .NET application that used the DataGridView, I noticed that there was no ColumnType drop down to allow the user to easily edit a date/time field. At first, I came across a really good write up on MSDN on how to accomplish this. However, it was written in VB, so I couldn't use it as-is inside my C# application (yes, I could have turned it into an assembly, but then I wouldn't get the chance to learn how things work!). After converting the code to C#, I found that essentially the same thing is now in the core .NET documentation. The main guts of creating a custom column means you need to implement the IDataGridViewEditingControl interface.

Other references:

Wednesday, 02 August 2006 03:36:00 (GMT Daylight Time, UTC+01:00)      Comments [2] -
.NET
Tuesday, 28 February 2006
When writing server-side sinks, it's important to remember that order matters when declaring your sinks. For example, consider the following block in a config file:

<serverProviders>
<provider type="LoggingSink.ServerSinkLoggerProvider, LoggingSink" />
<formatter ref="binary" typeFilterLevel="Full" />
</serverProviders>


The problem here is that if ServerSinkLoggerProvider is a class that implements IServerChannelSink, the requestMsg parameter will be null in the ProcessMessage method. If you reverse the ordering of the 2 lines (i.e. put the formatter first), everything works fine.

This is by design, and due to the chaining of sinks that occurs in .NET Remoting. In the first case, the formatter has not yet deserialized the message, so we can't easily get to the IMessage that was passed to us. In the second case, the formatter takes care of the deserialization first, and can then pass the IMessage to the DispatchChannelSinks for further processing and investigation. The overview of .NET Remoting layers from MSDN is lacking a lot of detail, but hints at what causes the differences. Once I went back to Ingo Rammer's book, the technical reason for this behavior became obvious.

Tuesday, 28 February 2006 15:02:00 (GMT Standard Time, UTC+00:00)      Comments [0] -
.NET
Saturday, 05 March 2005
I went to the Deeper in .NET training session today. It was a free event put on by the Wisconsin .NET User Group. The lineup of speakers was sensational: Scott Guthrie, Rob Howard, Rocky Lhotka, Jason Beres, and Chris Mayo. No offense to the other speakers, but I went solely to hear Rocky speak. He wrote the book Expert C# Business Objects, and it is a very well-done book. If you're doing .NET, you should definitely pick up a copy and maybe even read it. (Thanks for the pointer to this book, Mark!)

Rocky did not disappoint the packed crowd, and delivered an exceptional talk about Distributed Application Architecture in .NET. His main focus seemed to stem from one of his more recent blog entries where he advocates sensible (and sparring) use of tiers, but heavy reliance on layers. It was a very entertaining and well-reasoned talk. Ah, but who knows, maybe I just think this because I've been advocating the same idea for many years.

Saturday, 05 March 2005 22:47:00 (GMT Standard Time, UTC+00:00)      Comments [1] -
.NET
Monday, 25 October 2004
I love it when things just work the way they should. I've been developing a new product that relies heavily on a pluggable architecture using COM. During development, I started thinking that it would be nice to test out how well a C# component would work inside the architecture. As you can tell from the first line of this entry, it worked rather well. I plan on detailing a write-up of the details, but the short story is: it just works.

It's always refreshing to find technology that makes your life easier, instead of making the waters muddy and more difficult.

Monday, 25 October 2004 15:23:00 (GMT Daylight Time, UTC+01:00)      Comments [0] -
.NET
Friday, 06 August 2004
Whiteboard with Anders Hejlsberg is a must-watch video from an informal presentation he gave at TechEd 2004. The conciseness, clarity and depth of knowledge is impressive. He covers a range of topics and talks about design decisions that were made to help us understand why something is or isn't part of C#. All I can say is I want to be like Anders when I grow up. Hmmm. Probably too late. :)
Friday, 06 August 2004 16:16:00 (GMT Daylight Time, UTC+01:00)      Comments [1] -
.NET
Tuesday, 06 July 2004
In order to find out all of the columns that have been changed in a DataSet, you need to resort to code similar to the following. I sure liked the way MIDAS/DataSnap handled this better. A simple call to NewValue, and off you go. Another thing to keep in mind, DataRowVersion.Proposed is only valid between BeginEdit()/EndEdit() calls, so you are forced to write code like this instead:

if (!dataSet1.HasChanges())
return;

DataSet ds = dataSet1.GetChanges();
foreach (DataTable tbl in ds.Tables)
{
foreach (DataRow dr in tbl.Rows)
{
for (int i=0; i < tbl.Columns.Count; i++)
{
if (dr[i, DataRowVersion.Current] != null && !dr[i, DataRowVersion.Current].Equals(dr[i, DataRowVersion.Original]))
textBox1.AppendText(tbl.TableName + "." + tbl.Columns[i].ColumnName + " changed (" + dr[i, DataRowVersion.Original] + " -> " + dr[i, DataRowVersion.Current] + ")" + Environment.NewLine);
}
}
}

Tuesday, 06 July 2004 20:04:00 (GMT Daylight Time, UTC+01:00)      Comments [2] -
.NET
Tuesday, 08 June 2004
Andreas Hausladen came up with a way to get D8 apps to run under Mono. For more information, check out this file from SourceForge.
Tuesday, 08 June 2004 15:23:00 (GMT Daylight Time, UTC+01:00)      Comments [0] -
.NET
Monday, 15 March 2004
Scott Nonnenberg published some details on How to write custom visualizers for Whidbey. This seems like a very powerful capability for debugging.
Monday, 15 March 2004 16:44:00 (GMT Standard Time, UTC+00:00)      Comments [1] -
.NET
Categories
 .NET ADO.NET ALT.NET ASP.NET ASP.NET MVC Biking Compact Framework dasBlog DataSnap Delphi EntityFramework iPhone LINQ Macintosh Vista XML
Archive
 < 2017 December >
SunMonTueWedThuFriSat
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456
Blogroll

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.