Comments, how-to's, examples, tools, techniques and other material regarding .NET and related technologies.
Saturday, April 04, 2009
"Configuration system failed to initialize"
If you see a ConfigurationErrorsException along with the information "Configuration system failed to initialize" in your QuickWatch window then in all likelihood your app.config (or web.config) file is not correct.
In my case I simply forgot to surround the membership provider section with <system.web></system.web>. Once I added those it worked like a breeze.
Also, in case your custom provider cannot be found, make sure you have added the proper assembly name to the 'type' attribute for the <add> element of your provider in the <providers> section.
And yes, you can test custom providers without having to deploy to or run in a web server. Just ensure your app.config file contains the bare minimum by copying some content from web.config and you should be fine. For my scenario it was sufficient to copy the config section for NHibernate, the hibernate configuration, and the declaration for my custom membership provider.
Labels:
Presentation Layer
,
Technology
,
Tools
Friday, April 03, 2009
Membership Provider Implementation using NHibernate
ASP.NET allows selectively replacing provider implementations with your own custom implementation, e.g. when you want to store membership information in a database other than aspnetdb.mdf. There are more details provided on MSDN. Microsoft provides one such example implementation for ODBC in C# here. For VB.NET a sample membership provider implementation can be found here.
While the provider concept is essentially nothing more than Microsoft's flavor of service trays, it is not a surprise that by default Microsoft has a preference for their own products, in particular Microsoft SQL Server. And as long as you don't have a good reason to get into the details of a custom implementation it probably is a good choice to go with what comes out of the box.
However, I (and my customers) would like a little more flexibility.
Since I'm also experimenting with Fluent NHibernate I am attempting to implement a custom membership provider for ASP.NET based on NHibernate. The idea is that I could use in-memory databases for testing and SQL Server or PostgreSQL for production without having to change a single line of code. All I would need is changing four lines in web.config.
So goes the theory. Let's see whether practice proves it right. So far the code looks much simpler than the ODBC sample implementation and yet easier to read and understand. I'll keep you posted.
Labels:
Business Logic Layer
,
Technology
Saturday, March 28, 2009
csUnit 2.6 Released
csUnit 2.6 has been released and is available for download. More information is available here.
The major points of interest are:
- csUnit is now based on .NET 3.5 SP 1
- Parameterized testing moved out of experimental
- Basic support for Microsoft unit testing.
- Several bug fixes.
- csUnit (no surprise!)
- NUnit 2.4.7 (.NET 2.0)
- Microsoft Unit Testing (basic support)
Labels:
Tools
Friday, March 20, 2009
"Failed to create a service in configuration file"
You may encounter this error message when you try to add a WCF base service to your web service project.
The additional text of this error message is:
A child element named 'service' with same key already exists at the same configuration scope. Collection elements must be unique within the same configuration scope (e.g. the same application.config file). Duplicate key value: 'FooProject.BarService'.
The cause for this error message might be that you added a service to your project with the same name previously, then deleted it again. The remnants of that deleted service prevent the new service with the same name to be created.
To resolve the problem do this:
- In the web.config file locate the XML node
within the node . For instance in the above example locate the node that describes the 'BarService'. Delete that node but leave in the file. - In the same file locate the node
with an attribute 'behaviorConfiguration' and an attribute value of 'BarService'. This node also contains the endpoints for the service. Remove this node. - Try again, and this time it should work.
Labels:
Technology
Thursday, March 19, 2009
Updating Silverlight User Interface From Timer
Updating a Silverlight based user interface from a timer may not work as expected. The reason is that the timer thread is different from the user interface thread. Only the user interface thread can update a Silverlight based user interface. So for instance the following code will not work in a Silverlight application:
// _statusMessage is a System.Windows.Controls.TextBlock object
// _statusMessageTime is a System.Threading.Timer object
private void DisplayStatusMessage(string message) {
_statusMessage.Text = message;
_statusMessageTimer = new Timer(ResetStatusMessageCallback,
/* params left out for brevity */);
}
private void ResetStatusMessageCallback(object stateInfo) {
_statusMessage.Text = "";
}When the timer fires the callback is executed on a thread different to the user interface thread. The UI will not update. In my installation the Silverlight interface would then simply disappear! To fix this you need a way to execute the actual update on the user interface thread. One way is to use the Dispatcher object (Namespace: System.Windows.Threading) of the XAML page. Then the code of the callback implementation looks as follows: private void ResetStatusMessageCallback(object stateInfo) {
Dispatcher.BeginInvoke(() => {
_statusMessage.Text = "";
});
}Another solution would be to use the DispatcherTimer. I spare you the details but you can check here for an example.
Labels:
Performance Engineering
,
Technology
Monday, March 16, 2009
ClassInitialize Method Can Be 'static'
A few days ago I wrote about adding support for MS Unit Testing to csUnit (see here). Since I am also using ReSharper it sometimes suggests declaring methods as 'static' when the code of the method doesn't access any instance variables.
So just now it happened that a method marked with the 'ClassInitializeAttribute' was marked as static as well. When executing the set of tests in this class the method with the 'ClassInitializeAttribute' wasn't executed at all because apparently csUnit wasn't picking it up.
So I went and checked the csUnit code and found that the equivalent FixtureSetupAttribute was found only for non-static methods as well. So at least that was consistent.
Giving it a second thought I decided that it definitely makes sense to allow the FixtureSetupAttribute (and consequentially the 'ClassInitializeAttribute') to be on static methods as well. However, that isn't quite that straight forward the way the scanners in csUnit are implemented. So I'll have to do some refactoring before support for static fixture setup methods becomes available in trunk (let alone in a future release).
So that would bring the list of supported MS Unit Testing attributes to the following:
- TestClassAttribute
- TestMethodAttribute
- ExpectedExceptionAttribute
- ClassInitializeAttribute
Labels:
Tools
Sunday, March 15, 2009
Implicit Typing Can Make TDD Harder
Starting with C# 3.0 the language supports the concept of implicit typing at the method level using 'var'. While on one hand this new keyword has its benefits such the possibility to change return types of methods without having to change the type of all local variables that the return value is assign to, there is also a draw back of this new language feature.
If you are using strict TDD, you write your tests to drive your design. That means it is not uncommon that a new method on a class doesn't exist yet, though you can write your test including assertions on the return type. Example:
public class Result { public long Status { get; set; } } public class Foo { }Given this starting point you may want to write the following unit test to ensure that class Foo requires a method 'Result NewMethod()':
[TestMethod] public void TestNewMethod() { var foo = new Foo(); var result = foo.NewMethod(); Assert.AreEqual(0, result.Status); }As you type you will notice that when you have typed the dot after 'result' you will not be offered the member list of Result. It's not possible to implicitly type the variable 'result' since the method 'NewMethod()' doesn't exist yet. As a result writing tests in a TDD approach is slowed down when using 'var' instead of explicit types. Here is another view you may take: Writing tests for 'NewMethod()' should include all specifications, including the type of the return value. If you agree with that view you may want to avoid using 'var' in your unit tests. This certainly doesn't apply to people who create their unit tests after the method has been added to the class. I personally wouldn't call this test-first development, let alone test-driven development (or test-driven design as some people argue). Bottom line it depends on where you are coming from. 'var' might not always be the best choice even if it is a new 'cool' feature in C# 3.0.
Labels:
TDD
Saturday, March 14, 2009
Passing Serialized Exceptions as Service Faults
One way to pass errors from methods back to a caller is using Exceptions. Unfortunately that doesn't work with services since a caller might be anything and so you shouldn't assume that the client understands the .NET platform (and in particular WCF) as well.
Therefore in a service oriented world operations return faults. When implementing a service with WCF you could use the FaultContract() on your service operation. In addition you can also use the ExceptionShielding Attribute on your service implementation.
However, ExceptionShielding along with includeExceptionDetailInFaults in the service configuration covers unknown and unhandled exceptions only. Other exceptions are mapped to faults, and that's where your responsibility comes in.
Whatever you return to a caller, provide as little information about what happened as possible. For instance you may log an exception to a log file on the server hosting the service and attach a case id to it. Then return that case id as part of the service fault. To get more details about a fault this case id can be used to locate the detailed information in the log file.
One thing you definitely shouldn't do is passing the entire exception including call stack in a textual or serialized format to the caller. You don't want to add that additional security risk.
The reason you don't want to include too much information in the fault is that an attacker might be able to use the details for future attacks. You don't want to present that information on a SilverPlatter. So for instance you could use the following class for representing faults:
using System.Runtime.Serialization;
namespace AgileTraxx.Services {
[DataContract]
public class ServiceResult {
public ServiceResult(string message, long incidentId) {
Message = message;
IncidentId = incidentId;
}
[DataMember]
public string Message { get; set; }
[DataMember]
public long IncidentId { get; set; }
}
}This class would just take the incident id plus a message. The message could contain information about how to contact support and to note down the incident id.
As you can see there is a lot to consider when designing a service interface, including security related factors.
Labels:
Technology
Sunday, March 08, 2009
Service Reference for method returning void and out parameter
The title is quite lengthy but I couldn't find a better one. In essence I'd like to make describe a little catch you might experience when generating a service reference within Visual Studio 2008 (it might apply to other versions as well).
Suppose you have a service implemented in WCF (Windows Communication Foundation). The services exposes an operation as follows:
void UpdateItem(ItemData data, out ServiceFault fault);
(Yes, I know that faults should be handled differently but if you want to support Silverlight there are not too many alternatives at present since we are running inside a browser. I wrote about this before so won't go into details here.)
Note that the class ServiceFault is a very simple class. The details are not relevant here.
The point I want to make here is this. When you create a service reference to the service that provides the above the operation Visual Studio will generate the signature in the service client as follows:
public ServiceFault UpdateItem(ItemData data);
You will notice that the return value has change from void to ServiceFault, and that the new operation takes only one parameter and has no out parameter. While generally it is probably a smart assumption that for a void operation the first (or only) out parameter is turned into the return value you may not want this in all cases. For some users this behavior might even be surprising. It might make sense to argue that this is a violation of the principle of least surprise.
In my particular case I wanted the signature to be consistent with other signatures from other operations in the same service. So I changed the service interface to:
long UpdateItem(ItemData data, out ServiceFault fault);
The implementation always returns 0 as a result. And now, when I update the service reference I get the expected matching signature generated, and all signatures for the operations within my service are now consistent.
On second thought, though, I might actually try a different approach. What if the return value becomes of type ServiceResult? And if I actually have to return some values these can always become an out paramter. I'll give that thought a try and keep you posted.
Thursday, March 05, 2009
Domain Objects with Validation in Fluent NHibernate
Here is an issue that took me quite some time to figure out how to resolve it.
I am experimenting with Fluent NHibernate. My starting point was that I wanted the code of my domain classes squeaky clean: Not a single hint that they may become persistent. Why? I wanted to have the domain free from anything that has nothing to do with the domain.
At the same time I wanted the domain model to contain the validation code. Ok, I know the way I implemented validation is not necessarily in line with the usual approach in NHibernate. But let's have a look at my domain class:
internal class WorkItem {
public WorkItem () {
}
public virtual long Id {
get {
return _id;
}
set {
_id = value;
}
}
public virtual string Title {
get {
return _title;
}
set {
_title = Validation.EnsureNonEmptyString(value, "Title");
}
}
private long _id;
private string _title = "";
}
I left most of it out. For now let's look at just the id and the title since those two demonstrate sufficiently the issue.
What you will notice is that the setter for the title contains validation code ("Validation.EnsureNonEmptyString(...)").
The problem starts when you query for one or more WorkItem's. Then NHibernate will use the property setters to initialize the instance of WorkItem. For strings the default value is null (nothing in VB.NET). With the given code, however, the validation will throw an exception since that is what it is designed to do. It doesn't care whether the setter is called by NHibernate or anything else.
So next I tried to figure out what alternatives I would have for validation and I found NHibernate.Validator. Although a step in the right direction I didn't like that the client code for the domain objects would have to explicitly call the validation. Alternatively the validation would have to be invoke via the event call backs from NHibernate. In both cases the domain class would only work properly if something else would collaborate. I didn't like that concept and started to look for an alternative.
And there is a quite simple solution to this: Change the configuration for NHibernate so that it doesn't use the properties to initialize the domain objects. This configuration change can be done via Fluent NHibernate as follows:
_hibernateConfig = new Configuration();
AutoPersistenceModel persistenceModel =
AutoPersistenceModel
.MapEntitiesFromAssemblyOf()
.Where(TypeIsIncluded)
.ForTypesThatDeriveFrom(
map => map
.DefaultAccess
.AsCamelCaseField(Prefix.Underscore));
persistenceModel.Configure(_hibernateConfig);
Depending on your naming conventions you may want to use a different access strategy or a different Prefix value. In my case it was Camel Casing with an underscore as a prefix.
After I finally found this solution I was able to keep the domain classes squeaky clean and at the same time stay with using the Fluent NHibernate interface and avoiding exception during the initialization of instances of domain classes.
Of course I'm not sure whether this is the only and/or best option. If you have other options that are even better, please drop me a note. I'm always keen to learn more!
Labels:
Data Access Layer
,
Tools
Tuesday, March 03, 2009
Executing MS Unit Tests in csUnit
I have made a little progress on the MS Unit Test support in csUnit. So far I managed to create support for:
- TestClass
- TestMethod
- ExpectedException
Labels:
TDD
Monday, March 02, 2009
Another Tool for Silverlight Unit Testing
Just came across another unit testing tool for Silverlight. It's called SilverUnit. I haven't tried it out but I certainly will have a closer look. It will be interesting to see how this compares to Jeff Wilcox's approach and how it integrates with established unit testing tools.
I'll keep you posted.
Labels:
TDD
,
Technology
Sunday, March 01, 2009
csUnit migrated to .NET 3.5 and VS 2008
Finally I have found some time again to do a few things on csUnit. Actually the main driver was that I tried out the unit testing features that come out of the box with Visual Studio 2008 and I found them a little bit too cumbersome for my taste.
I'm sure there are scenarios, teams, and people who are looking exactly for what VS's unit testing provides, including the ability to look at old test runs. But overall it felt a little bit too heavy.
One example. A test fails. The result's view lists all tests and you can click on the one that failed. But it doesn't bring you straight to the failed test. That was my expectation. Instead it brings you to a page with the result details of that test. And only there you find a link to the actual implementation of the test. Conceptually that's probably what MSFT wanted. For me it felt like being slowed down.
So now I've moved csUnit to .NET 3.5 and migrated the solution and all projects within it to VS 2008. And I'm looking into making it possible for csUnit to run tests implemented using MSFT's unit testing framework. Let's see how that goes. One difficulty I already discovered: Counting assertions. I don't have a good solution for that yet but if you do, please let me know!
Labels:
TDD
Saturday, February 28, 2009
Designing Service Interfaces For Silverlight Clients
When designing a service interfaces based on WCF you might be considering indicating service errors via service faults. By and large that might be a good choice but in the case of Silverlight clients consuming that service you may want to read Eugene's blog first.
Eugene describes very detailed the technical background for why a Silverlight client running in a web browser may not be able to see the fault with all details. He also provide a few suggestions for how to get around that limitation - which is not Silverlight's fault! - including code examples.
In some cases have a separate set of services for Silverlight client's might be an option worth exploring as well. That way you can give service clients, which are not hampered by browser's 'filtering', the best possible experience.
Labels:
Business Logic Layer
,
Technology
Saturday, February 14, 2009
Parser Error Message: Could not load type 'Global'
If you get an error as follows:
"Parser Error Message: Could not load type 'Global'"
then you may be able to fix this issue by doing the following:
- Open the file containing your class Global typically located in the file Global.asax.cs,
- Note the namespace for that file
- Open the file Global.asax
- Locate the line that contains the element "... Application Codebehind=..."
- In that line ensure that the element "Inherits=..." includes the namespace for your Global class, e.g. MyWebSite.Global, (Inherits="MyWebSite.Global"). Replace MyWebSite with the namespace noted in step 2
- Recompile and redeploys.
- The error should be gone.
Labels:
Technology
Tuesday, January 13, 2009
Unit Testing for Silverlight
Looking for instructions for Unit Testing for Silverlight 2? Jeff Wilcox posted an excellent tutorial in March 2008 here. Since then he's also updated his testing framework. In addition he has posted required changes to make the tutorial work with the final release of Silverlight 2. Although the latter post refers to RC0 of the testing framework the information still applies to the December 2008 binaries.
The December 2008 release of the binaries of Jeff's unit testing framework can be downloaded from here. The project's homepage is here.
Labels:
TDD
,
Technology
Tuesday, June 24, 2008
Watch Out: Window.ObjectKind is UPPER CASE!
Using Windows2.CreateToolWindow2() to create a VisualStudio addin tool window?
If you do, then maybe you want to check how often it is called during the life cycle of your addin. And if you notice that you create it twice, you may want to avoid that by checking the collection EnvDTE80.Windows. If your tool window is already contained you don't want to create a second instance of your tool window.
There is a possible surprise, though.
Windows2.CreateToolWindow2() expects as the fifth parameter a guid. The online documentation (see here) says it is the "GuidPosition". This is a little misleading since it doesn't really refer to a position. In reality it is the type of the tool window, e.g. the Solution Explorer.
Now, when you create the boiler plate code you may just use the example given there. If you do, then change the content of the variable guidpos given in the code to all upper case. So the important bit is the following change:
string guidpos = "{426E8D27-3D33-4fc8-B3E9-9883AADC679F}";
string guidpos = "{426E8D27-3D33-4FC8-B3E9-9883AADC679F}";
=====
I've highlighted the important bit with red color, bold, and a larger font. In addition I have underlined it. I think you got the idea.
Why is this change important? Assume you iterate over the collection as follows:
foreach(Window2 toolWin in toolWins) {
string toolWinKind = toolWin.ObjectKind;
if( toolWinKind.Equals(guidString) ) {
_toolWindow = toolWin;
break;
}
}The Equals() call may always result in 'false' even if you think you are looking at the correct tool window. The reason is that ObjectKind returns the guid all upper case. The example code has two lower case characters in the guidpos variable.
The same can also happen when you use "Create GUID" from the "Tools" menu in Visual Studio. It may generate a guid for you with one or more lower case digits ('a' through 'f') as well.
It's unfortunate that the online documentation doesn't mention that some time between calling CreateToolWindow2() and calling ObjectKind everything is made upper case. The example code leads to potentially incorrect behavior of your addin as well. This post gives you the heads-up.
It took me quite some time to spot this little difference. In my case it was 'f' versus 'F' and only when Equals() insisted on returning false I took a closer look. Maybe this helps you saving some development time.
And maybe someone from Microsoft is reading this. I tried to add it as Community Content at MSDN. It wasn't possible. So I rated the article and left a comment adding the suggestions for improvement. This would have been ideal for "Community Content". MSFT, you mind updating the online material? Thank you!
Labels:
Tools
Thursday, June 19, 2008
csUnit: What's Next?
csUnit 2.5 is very well received but since we are always trying to find improvements I'd like to share a couple of items that we plan for the next version.
For one, the performance has slightly slipped. Some new features resulted in an runtime penalty which we believe has become too high. So we did some performance analysis and have found ways to get a performance improvement of about 10% to 30% of the next version over version 2.5. Both the command line version and the GUI version benefit from this improvement.
The other area we didn't like too much was the slightly cluttered user interface on the test hierarchy tab, which is the most frequently used view in the tool. In addition the search feature on the test hierarchy tab worksfor the test hierarchy only. This is a limitation. So we decided to revisit the search feature. The next version will therefore have a new search feature that works across all tabs. And at the sime time we were able to remove the related buttons from the test hierarchy page and replace them with a single button in the already existing toolbar. This freed up screen real estate for the important information and also simplified the appearance.
These are just two of the improvements you will see in the upcoming version 2.6 of csUnit, which we are planning for August. Stay posted. If you'd like to participate in determining the future of csUnit then please don't hesitate to contact me or anybody else of the csUnit team.
Saturday, June 14, 2008
Vista: Finding Encrypted Files
To find encrypted files on Windows Vista do this:
- Open a command prompt and switch to a directory in which you have write permissions.
- Run the command: "cypher /s:c:\ /N /U > filelist.txt" and wait until finished (this example searches the entire volume c:
- When finished open the file filelist.txt. It contains a list of all files that are encrypted.
- In the Explorer window navigate to each file and though "Properties" -> "Advanced..." goto to the "Advanced Attributes" page and remove the checkmark from "Encrypt contents to secure data"
Labels:
Technology
Tuesday, June 10, 2008
Addin Command Names
What is the name of a command when you register it for an addin? Typically you use Commands.AddNamedCommand() to register a command. The second parameter is the command name.
Now, when you want to look up a command you can use _DTE.Commands using the name you used for AddNamedCommand() and you're done. Right? Wrong!
Let's take the csUnit addin for Visual Studio as an example. The addin has the name csUnit.csUnit4VS2005.Connect. This is the class that implements the interface Extensibility.IDTExtensibility2. This interface includes members such as OnConnection(), OnDisconnection(), etc. This full name - 'csUnit.csUnit4VS2005.Connect' - is also used in the addin file (see node Extensibilily / Addin / FullClassName).
What VS 2005 and VS 2008 do is this: When you register a command, the name of the command will be automatically prefixed with the name of the addin. So in this case a csUnit command named Foo would turn into csUnit.csUnit4VS2005.Connect.Foo.
Be aware of this. Otherwise your code may not be able to find your command in _DTE.Commands.
Labels:
Tools
Subscribe to:
Posts (Atom)