Tuesday, May 03, 2011

Crazy Project: Two steps forward, one step sideways

I would be definitely long done should I use my hammer familiar tools for the work, but I would miss all the fun. I am positively in love with MVC3 – the Microsoft team is doing an amazing job! Elegance with which they embrace the latest C# additions makes my cry Bazinga! Let me list some lessons I’ve learned so far on Crazy Project.

MVC3 Scaffolding – not just for Entity Framework

I almost got ready to bitch about MVC team again but discovered a neat expansion (it is fully expandable!) for the MVC 3 Scaffolding – in addition to default EF-centric and empty view templates it can use repositories. All you need to do is navigate to View->Other Windows->Package Manager Console in Visual Studio and type Install-Package MvcScaffolding. It would be nice to have them installed by default - all it does is generate CRUD-compatible Views and Controller and it really needs to know only the underlying entity type. It could cover 99% scenarios out there, including EF one.

MVC validation and Java Script manipulations

Building an interactive (Java Script-backed) form I hit a problem with the built-in validation (generated from Model validation attributes) – I was hiding some fields with Java Script but the validation was still firing for them. Quick search provided a solution: the Form element can be told to exclude fields decorated with certain class from the validation:

$("#myform").validate({
ignore: ".ignore"
})

Which means that no validation should be performed for a field decorated with the class=”ignore” attribute.

Unfortunately this didn’t work for me after I added the code snippet to my document.ready event (I guess, that I just misused the functionality but I don’t know better yet and hope for my audience help). As an immediate measure I had to change a bit the jquery.validate.unobtrusive.min.js file which is included with MVC3 template: right after success: a.proxy(j, d) text I added ,ignore: “.ignore”.

Similarly it should work in a wider scale: when ignore: “:hidden” rule is used instead, all hidden fields will be excluded from validation – the jQuery is smart enough to consider field hidden if it is inside a hidden container, like div tag. Search the jquery.validate.unobtrusive.js file for an unscrambled version of the code to understand better what it does – the resulting function should look like this:

function validationInfo(form) {
    var $form = $(form),
        result = $form.data(data_validation);

    if (!result) {
        result = {
            options: {  // options structure passed to jQuery Validate's validate() method
                errorClass: "input-validation-error",
                errorElement: "span",
                errorPlacement: $.proxy(onError, form),
                invalidHandler: $.proxy(onErrors, form),
                messages: {},
                rules: {},
                success: $.proxy(onSuccess, form),
                ignore: ":hidden"
            },
            attachValidation: function () {
                $form.validate(this.options);
            },
            validate: function () {  // a validation function that is called by unobtrusive Ajax
                $form.validate();
                return $form.valid();
            }
        };
        $form.data(data_validation, result);
    }
    return result;
}

I can’t say enough about awesomeness of MVC3’s adherence to the web standards. No more weirdo ASPX tricks – just pure old DOM, CSS and HTML!

Update: Aforementioned is still not enough - ModelState server-side validation will fail, because it is still going through all fields. Undesired properties should be removed from the ModelState:

if (payeeViewModel.Currency==US)
{
ModelState.Remove("InstitutionNumber");
}

Get Postal

I am new to MVC and jQuery, so I am stepping on the same mines, which my more experienced colleagues know by heart. I had this as my first jQuery exercise, which was returning a JSON list using AJAX get:

$.getJSON('@Url.Action("GetItems")', { id: selectedCategory }, function (response)
{
    each(response.items, function (index, iteml)
    {
       ...
    });
});

I was really proud of it until realized that simply by navigating to http://www.microsoft.com/items/333 u

Technorati Tags: ,,,,,
ser will get a nice (or weird, depending on a purpose) JSON array with my items back. Not good. So I changed it a bit:
$.post('@Url.Action("GetItems")', { id: selectedCategory }, function (response)
{
    each(response.items, function (index, iteml)
    {
       ...
    });
},'json');

And GetItems action, which does the job, accepts only HttpPost verb, while another one by the same name throws back a HttpNotFound result (back to the nature!). The solution is not perfect, as POST is not that difficult to hack (of course I have a security on top of it) but at least it won’t be stumbled upon accidentally.

Shaping workflow service to WCF

The default implementation of the WF4 service, which can be seen in 90% of presentations, uses Service Reference. If you ask me it is a part of Poor Man’s SOA Toolset - an ugly and inflexible technique. Here is an excellent post about how to avoid it – “How to make a WorkflowService implement a contract”. A couple tricks with ChannelFactory and you have a Service Reference-less project!

Workflow correlation

The sad discovery of the day – workflow can not use the same operation twice. Which kind of makes sense and doesn’t at the same time. It is all about correlation – the area where WF4 shares voodoo magic with BizTalk.
This particular post helped me to get better understanding the WF4 correlation. At least the sample is not using string-based correlation handler, unlike many others.

4 comments:

sri @ Scaffolding chennai said...

Interesting to read

Chris Barrow said...

Have to disagree about the service reference being a poor man's service but I do agree with you channel factory is a much cleaner and less bloated technique.

And yes, of course very soapy as opposed to restful which is what all good apis should be built on.

Michael Goldobin said...

REST is overrated! SOAP is better implementation of the Job Security Pattern :)

Chris Barrow said...

Ah. Yes, I forgot about the job security pattern, but used successfully in last project :-)


© 2008-2013 Michael Goldobin. All rights reserved