After struggling around for some time now and having several posts of installation failures (in the comments or at StackOverflow) I picked up the idea of Timur and managed to get the project template for NUnit and ASP.NET MVC 3 put together into a Visual Studio Extension.
The benefit is, that there is no installation which does registry changes but delegates the merge process of needed registry settings to Visual Studio. This is done via a package-definition file added to the extension. If you want to dig deeper into that I can recommend following to read:
Both articles describe the starting process of Visual Studio and the registry merging well.
At current state the extension is only available for Visual Studio 2010 Professional and higher editions. This is only while I am not aware of the fact if it is possible for lower editions to run extension. Maybe I will research about that later and eventually open the extension for all possible editions.
You can now find the extension under following download-link: ASP.NET MVC NUnit or via Extension Manager in Visual Studio.
Functionality is the same as before - ok there is no much to improve or change ;-)
As I updated the test-project shipped with ASP.NET MVC 3 some days ago to fit with NUnit I thought it’s time to do so as well with xUnit.net (and later maybe with MbUnit - so that all big 4 testing-frameworks could be used).
You can download the stuff right here or as usual in the download area. Installation is as simple it could be - just unzip and double click the install.bat. The package is both x86 and x64 aware as the installer checks your system and figures out what registry entries to be done.
If there are any problems let me know - I’ll try to fix ‘em.
[Sidenote:] I am aware about the fact that there is an xunit.installer.exe bundled with xUnit.net ;-) which will install templates for ASP.NET MVC 1, 2 and / or 3. These templates provided in my copy are 1:1 taken from the MSTest which are build-in. The installer provided templates differ. (just to clarify)
As I read about automated error reporting by Laila Lotfi’s article over at Red Gate’sSimple Talk community site, I first thought yeah nice that’s what we need in good software. But on a second thought I considered that it was not going far enough.
Truly having automated error reporting is quite well but having hundreds or thousands of error’s (depending on the amount of sold licenses) depending on same issues is not what I’d like to see and sorting duplicates out is like a job for someone who killes mom and dad. For a second reason much of a developers live and development process is guided by ticket system ((You can find some good comparison regarding issue-tracking systems at wikipedia.org.)). So why not integrated automated error reporting into a consolidating service (which does that ugly sort and compare job) and let it publish new issues to a ticket system?
Might not be the best solution in town but sounds even better than nothing - right? Next up here is a small image showing up how it should be done:
So our application reports its unhandled exceptions to the consolidation service (named AER service) which stores the exception report in it’s storage. I find it reasonable to store all reported exceptions in a storage (even for those issues which are already reported) because it gives the developer even more scenarios (assuming the exception report contains detailed informations about environment and current stack…) under which circumstances this error appears.
After storing the report it crawls the bugtracker to find a similar issue, if it doesn’t it creates a new entry containing necessary informations and even a sort of link to the reports in the storage so that the responsible developer can find additional infos for the exception.
That said I will try to post a little series about reaching this end-scenario. The tools and libraries I choose to achieve this goal are based on the facts that I owned licenses of them already - but I guess it is even achievable with others.
So what I have is:
Red Gate’s SmartAssembly 5: this tool does already a nifty job for automated error reporting. To be honest you will need the PRO version to reach the finish line in this scenario, while that is the version which gives you access to the SDK and a self-hosted custom web-service. ((You can read about its detailed features and why I chose to give it a shot for automated error reporting here and here))
JetBrain’s YouTrack - as they say the fastest issue and bug-tracker. This isn’t much the reason why ;-) - I have it so I use it - it has a REST API so I think I can even link it into the set goal.
What do I need (which seems to be not so much at least):
an interface to YouTrack - REST based!
a synchronisation job which is called after an exception gets reported - to decide if an issue has to be created and does so via the mentioned REST based client
First I thought:
This seems to be very pleasant and causing not very much work
But the problems I were facing are:
There is already a C# YouTrack REST client - named YouTrackSharp written by the famous @ hhariri - the JetBrains guru itself. Sadly it is an implementation which uses the JSON API of YouTrack - which is really really broken - so I did not get managed to hook some attachment support in it. Maybe another reason is that I do not know very much about JSONFx which is used in there, too. And the lack of documentation doesn’t made it easier for me. So I decided to build up my own REST client for YouTrack - based on the XML REST API using RestSharp which I know pretty well. I named it RestTrack. It isn’t 100% finished yet - but it does all I need to create issues, search them, create attachments and so on… I will release the source in near future. As said it isn’t such as good as YouTrackSharp (which uses .NET 4 dynamics already) - it’s more the old-school way using XML-Attributes but it fits my needs :-)
My second problem was/is that the SmartAssembly documentation in this case is a bit - let’s say - lean. So I have to trouble the support really a lot. But they are as always good and gave me lot of stuff at the hand - thanks for that!
Covering the basics here you can expect in the next post some code stuff about RestTrack and how it can be used to search, create and attach files to issues.
Stay tuned… and as always: suggestions are pretty well appreciated!
Update [2011-01-22]:
Meanwhile ASP.NET MVC 3 RTM has arrived - this template is still good to go even for RTM version. As you can see in the comments I initially forgotten to explicitly mention that the originally template was x64 only. As an result I tried to change the .bat file accordingly to handle x86 platforms as well. So when you download the newly packed template this should determine if your system is x86 or x64 and call the proper files for installing the template correctly.
The first deployed template also contained a reference to a specific NUnit version even when version-specific switch for Visual Studio was set to false I now removed this version-reference.
What ships with that release again is the possibility to create new test-projects (according to a new created projects), from the build-in project templates, which does use the Microsoft unit-testing framework (in the wizard called Visual Studio Unit Test). This isn’t anything new!
Based on Piotr’s MVC 2 test-project template I updated it (based on the shipped MvcWebApplicationTestProjectTemplatev3.0.cs.zip) to be compatible with ASP.NET MVC 3 (RC2) and changed the notation to Assert.That(…, Is-constraint) - which I prefer while using NUnit.
If you compare it to the old MVC 2 template you will probably notice that the extension wizard is gone. Don’t know why - maybe we should ask @haacked about that…
A sample of the generated NUnit-Tests (as of the HomeController):
12345678910111213141516171819202122232425
[TestFixture]publicclassHomeControllerTest{ [Test]publicvoidIndex(){// Arrange HomeControllercontroller=newHomeController();// Act ViewResultresult=controller.Index()asViewResult;// Assert Assert.That("Welcome to ASP.NET MVC!",Is.EqualTo(result.ViewBag.Message));} [Test]publicvoidAbout(){// Arrange HomeControllercontroller=newHomeController();// Act ViewResultresult=controller.About()asViewResult;// Assert Assert.That(result,Is.Not.Null);}}
To use the new template you still need a registry key referring to the new package. The one I used is only x64 compatible. Remember: The GUID’s of the vstemplate and the registry need to match.
123456
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\MVC3\TestProjectTemplates\NUnit]"Path"="CSharp\\Test""Package"="{E0915DB0-C6DC-4BF6-AEBF-9D72308FDB81}""Template"="MvcWebApplicationNUnitTestProjectTemplatev3.0.cs.zip""TestFrameworkName"="NUnit Test"
Alongside to the updated registry entry I added an install.bat file which does the necessary steps
insert registry key
copy template archive
update Viusal Studio 2010 project template cache
It isn’t much about magic glue in it, just for completeness sake I post the batch-script:
12345678910111213141516
@echo off
echo==== Installing ASP.NET MVC 3 NUnit project template====echo Updating registry settings [X64]regedit /s MvcWebApplicationNUnitTestProjectTemplate.reg
echo Copying MvcWebApplicationNUnitTestProjectTemplatev3.0.cs.zip to Visual Studio 2010 project templates folder
xcopy .\MvcWebApplicationNUnitTestProjectTemplatev3.0.cs.zip "C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ProjectTemplates\CSharp\Test" /Y /I
echo Updating Visual Studio 2010 project template cache
"C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe" /setup
echo====Done====pause
After executing the install.bat and creating a new ASP.NET MVC 3 application the project template should show up as following:
I packed an archive containing als the stuff (reg key, vstemplate.zip and install.bat). Feel free to download :-)
In my humble opinion there are two different steps in a validation process (either web-based or n-tier). First the formal/structural correctness, like all required fields are filled or a given credit card number matches its structural requirements etc. Second is the technical/functional correctness, like is this given user name / password combination (which meets its structural requirements as they are filled) even a valid combination in our database.
As differentiating these two steps in a validation process, I think they have to take place in two different locations. Functional correctness does not have to be proven, if a structural correctness isn’t given. Thinking of request - response scenarios why make a request if not all structural requirements are met. As speaking in client and server side - structural validation has to be done on the client-side whereas functional validation on the server-side. Most of you will agree in this points - as this is what the majority did over the last few years.
In web applications client-side validation is mostly done by using javascript - and jQuery is truely the state of art library for doing javascript operations. Therefore I used the jQuery validation plugin to do some checks on a form before posting it to the server for functional checks. As the docs are quite good what is this post all about you will surely ask?!
It’s not just about how to use jQuery validation but also how to extend it with your own validation checks and how to customize the messages thrown if some validations fail.
First of some basics in using jQuery validation to get it work. It’s quite simple (as written in the docs) to wire jQuery validation to your form. By a) auto-wiring the validator to a submit button (the sample is taken from the docs, where your form has id = commentForm):
Next step is to tell the validator the expectations you like to have on your fields. This is as simple as before. Just chain classes together. Each class represents an attribute on your field. So what are the possibilities? Thereare a few build-in classes (following is just an excerpt of the most often used, I guess):
required
optional
min
max
email
url
date
dateISO
number
digits
creaditcard
range
Wiring those attributes to my sample would result to:
As you can see, I bound the attributes required and digits to my input fields. A different possibility in place of classes is to set rules per javascript. (but I like the class notation a little more, because it’s much more clear to read). Same sample would result into following javascript notation:
123456789101112131415
$("#quickcheck_form").validate({rules:{e13:{required:true,digits:true}},messages:{e13:{required:"Enter your stock amount",digits:"Please enter digits only"}}});
So these are the basics you need to use the validation plugin. So me requirements were a bit more way off mainstream (I do not really think so, but that’s a different story ;-) ) I needed some decimal validator which accepts only positive digits, 0 to 1 decimal place and up to 2 pre-decimal places.
Luckily jQuery validation offers an addMethod function to extend the common rules (aka attributes or methods):
So I added a new custom test-method decimal1 (1 = assuming the max count of decimal-places) with two regular expression matching my requirements. Wow - that was easy! I “chained” 3 possible validations together:
optional –> maybe it isn’t a required field
max 2 pre-decimal places without decimal places
max 2 pre-decimal places with max 1 decimal place
The next requirements were to have some custom messages if any validations were broken. jQuery extend to the rescue:
This is a fine way to “overwrite” the default messages of jQuery validation (nevertheless jQuery validation offers some localization in may different languages). So these are some really good tools to build up client-side form validation to have some useful user-interaction on your web-ui and preventing unnecessary server-request.
Finally I like to mention another two articles dealing with client-side validation:
By default a WCF Service uses the QueryStringConverter to convert query parameter into typed objects. To the according MSDN Documentation (see link above) we cann see, that it supports by default following parameter/object types:
Byte
SByte
Int16
Int32
Int64
UInt16
UInt32
UInt64
Single
Double
Char
Decimal
Boolean
String
DateTime
TimeSpan
Guid
Byte array
Uri
Object
DateTimeOffset
Enums
Types that have a TypeConverterAttribute that can convert the type to and from a string representation
Hell, these are really lot of types which can be converted - but what if we like to have additional? Let’s guess we like to have Nullable types like DateTime? to make some sort of optional parameter. As the Nullable type is a build in framework type we do not have a chance to decorate it with a TypeConverterAttribute.aspx).
Writing our own QueryStringConverter to the rescue… The task is really simple - derive from QueryStringConverter, override 3 functions and fill in some rules:
As you can see this isn’t such a big task. Noticable (and this is why I chose DateTime) is the convention I used to convert DateTime into the RFC1123 pattern format. The client side has to do as well to circumvent any problems in converting from and to DateTime. You can read more about Standard Date and Time Format Strings at the MSDN Documentation.
As we have our very own QueryStringConverter (extending the default) supporting Nullable types now we need to tell our WCF Service to use this instead of the default. Therefore we need 2 additional classes to configure a custom behavior which uses our implementation. Theses two classes are a custom WebHttpBehavior and a custom BehaviorExtensionElement.
As you can see the custom behavior wires are implementation of the QueryStringConverter to our service. Next is the extension element to extend the service to use the custom behavoir.
Some time ago I posted about truncating a database. At that point (I guess my SQLServer skills weren’t as advanced as at nowadays - which doesn’t mean they are quite well now ;-) ) I thought this was a good solution - googling leads often to the same solution.
But getting older and gray in the head I realized there is a much better way to do: sp_MSdependencies one of several undocumented stored procedures of the SQLServer.
The advantage of sp_MSdependecies is, that it retrieves all dependent objects in a hierarchical list (expressed by the osequence). If you fill NULL on the objname parameter it retrieves all objects in the right order. Nice trick! So what I did is to load the data into a temp table and sort it according to its osequence to build the correct order. Remember: Deleting tables with foreign-keys needs to have a different order than deleting data from it.
I use the following snippet from time to time and want to share with you:
BEGINDECLARE@schemaNVARCHAR(32)='<your-schema-name-here>'DECLARE@tableNVARCHAR(128)DECLARE@statementNVARCHAR(128)DECLARE@dependenciesTABLE(oTypeSMALLINT,oobjnameSYSNAME,oownerNVARCHAR(50),osequenceSMALLINT)-- load dependecniesINSERTINTO@dependenciesEXEC[sys].[sp_MSdependencies]@objname=NULL-- filter by oType 8 == Table and given schemaDECLARETableCursorCURSORFORWARD_ONLYFAST_FORWARDREAD_ONLYFORSELECT[TD].[oobjname]FROM@dependenciesTDWHERE[TD].[oType]=8AND[TD].[oowner]=@schemaORDERBY[TD].[osequence]DESCOPENTableCursorFETCHNEXTFROMTableCursorINTO@tableWHILE@@FETCH_STATUS=0BEGINSET@statement=N'DROP TABLE ['+@schema+'].['+@table+']'EXEC[sys].[sp_executesql]@statementFETCHNEXTFROMTableCursorINTO@tableENDCLOSETableCursorDEALLOCATETableCursorEND
What we actually were trying to achieve is, that we can call a WCF RESTService function doing a PUT action and having multiple (exactly three) input parameter. First goal was having only two input parameter of type URL parameter and the third within the body. (should be like a kind of put that body parameter beneath the entity which is identified by parameter one and two - this is how we do the interpretation of a RESTful Service). From the WCF perspective this isn’t such difficult quest:
But we figured out some problems resulting from the type we chose for the input parameter. The Dictionary<string, byte[]> instance was always NULL. It took some time to figure out it was always NULL. Reading the MSDN docs carefully shows why: Stand-Alone JSON Serialization contains following paragraph:
Dictionaries are not a way to work directly with JSON. Dictionary<string,object> may not be supported in the same way in WCF as expected from working with other JSON technologies. For example, if “abc” is mapped to “xyz” and “def” is mapped to 42 in a dictionary, the JSON representation is not {“abc”:”xyz”,”def”:42} but is [{“Key”:”abc”,”Value”:”xyz”},{“Key”:”def”,”Value”:42}] instead.
So the cause is that WCF is not compatible to general AJAX/JSON serialization but uses its own Serializer/DeSerializer -> the DataContractJsonSerializer. RestSharp sits on top of the Json.NET library - a general approach to work with JavaScript and JSON formatted data. The incompatibility appears in our case in the Dictionary parameter while the other data types were well serialized and deserialized. The following graphic tries to show the incompatibilities in a more strikingly way.
Fortunately RestSharp offers the ISerializer and IDeserializer interfaces to contribute own implementations of adapter supporting special communication protocols (as the WCF datacontractjsonserializer is in this case). So what wie did is implement our own JsonWcfSerializer:
So as you can see in the second graphic the adapter turned from orange to gray and is now fitting the WCF communication protocoll.
At least I like to share some configuration parameters with you - in our case we need to send some byte[] with a length larger than the default 64kb (65536 bytes). Beneath the bindings-section of your system.ServiceModel section in the Web.config you need some additonal entries:
As you can see it consists of two parts - the binding and the readQuotas. The maxBufferSize (maxReceivedMessageSize - which must be of same value as maxBufferSize) controls the amount of data, which could be received by the service. (in our case we estimate a length not bigger than 10MB). As you can guess a byte[] of 10MB has some extraordinary length. Therefore you need the readQuotas to allow the service a deserialization of an array with such length. We set the quotas to Integer32.MaxValue which is the max value allowed - as we are in a closed private system.
Hope this helps to send dictionaries to and receive them from your Wcf-Service!