thoughts on coding

August 16, 2011

Porting a WPF App with MVVM Design Pattern to Silverlight 4 using Caliburn, FluentValidation

Filed under: .NET, Caliburn, FluentValidation, Silverlight, Uncategorized, WPF/Silverlight — Frantisek @ 7:04 am

There is a demo application from Josh Smith showing usage of M-V-VM pattern in WPF. It’s taken as WPF MVVM foundation and it was published in MSDN magazine here: http://msdn.microsoft.com/en-us/magazine/dd419663.aspx [DemoApp1]

There is another blog entry describing how to migrate it into Silverlight 4 here: http://edventuro.us/2010/03/porting-a-wpf-app-with-the-model-view-viewmodel-design-pattern-to-silverlight-4/ [DemoApp2]

Because of our current project I work on a proof-of-concept for a smart client based on  SL4, I used the demo application as a basement and I rewrote it using Caliburn (as an application framework) and FluentValidation (for hte client side validation).

The main differences against the ported demo application [DemoApp2] are:

View resolution/instantiation based on the view-model class types. The idea behind the scene is that the viewmodels are prohibited to talk to any UI specific part and views ( View -> ViewModel/View, ViewModel -> View). When it’s necessary to open another view from the view model, we “activate” the viewmodel or return a subroutine result (a similar concept as with ASP.NET MVC and their ActionResult).

Then it’s necessary to bind the active viewmodel to display a content control in UI.

In this case Caliburn tries to locate some view (based on a convention) to display/present the active viewmodel. You can find more info about it on http://caliburn.codeplex.com/documentation.

The next IMHO improvement is the messaging mechanism in Caliburn. In other words, the messaging is the mechanism how to call any method on viewmodel from the view or how to send a message from the view to the viewmodel. This mechanism replaces usage of commands together with any interactivity definitions (attaching to the event and reacting). More info can be found here:  http://caliburn.codeplex.com/documentation. I used it for displaying and handling the list of the menu links.

The viewmodel instatiates the list of the actions.

We bind then the model of the messages to the view like following

The last but not least part is the  validation on the client side. A little bit background note: There are 3 different types of the validations:

a) UI validation (in SL done via IDataErrorInfo internface)

b) ViewModel input validation/handling, navigating the user to input the correct data

c) model validation

In Josh’s demo application the viewmodel copies the model’s properties and wraps them +  the validation logic spreads among viewmodel and models. Yes, models contains the data, notifications and plus the validation (which could contain the multilanguage support). I think, this is breaking the separation of concerns and that’s the reason I usedFluentValidation to do the validation => I separated the validation concern into the special class(es) with the suffix Validator.

It looks like Silverlights was designed with Close/Close principle (many classes are sealed, internal methods, internal constructors) there are very few parts which we can extend (binding, validation, validation errors, etc. – all are very tightly coupled from the extension point of the view).

So we need to follow stander IDataErrorInfo mechanism to UI support validation. So every model class will need to implement IDataErrorInfo. I had to separate Silverlight infrastructure code into a base class called ValidatableModelBase  and my models derive from it. That’s the way where model is not disturbed very much by IDataErrorInfo specifics.

ViewModel exposes a model, called subject.  ViewModelValidator<TViewModel> then enables ViewModel properties and their child to be validatable (fullfulling the UI requirements).

[class model]

It’s a concern of the viewmodel validator to decide what (what properties)  and when will be validated.

Then ViewModel or any model class is able to validate its properties and return the error message (supporting the multilanguage).

 

ViewModel (as a validation root) validate method:

 

The main Validation goals I wanted to fullfill:

a) do not drive the validation by throwing the exceptions

b) viewmodels shouldn’t copy the model properties and wrap them. It increases the amount of the code and complexity in more advanced scenarios

c) models should only hold the data and inform about their changes (INotifyPropertyChanged). Unfortunatelly, they need also derive from the base class which provides the infrastructure code (IDataErrorInfo).

The validation is bigger part and I’d like to provide an additional blog entry only about the validation.

What blog entries will follow:

  • connecting the server side with Agatha [preffered] or RRSL Lite in order to communicate with the server + generating the models (entities) for the view model
  • unit testing of the client side
  • finalizing the server side
  • enhancing the client/server with tracing and logging
  • client side and server side validation

You can download the code here: MvvmSilverlightDemoApp.zip (after downloading remove the extension txt)

 

June 3, 2011

Caliburn(WPF, Silverlight/WP7): Extending the default convetion model to support the convention on more attributes

Filed under: .NET, Caliburn, WPF/Silverlight — Frantisek @ 10:51 pm

I like “convention over configuration/over-specification” approach very much. Caliburn is a briliant framework for building UI layer for Silverlight/WPF/WP7 apps with IoC,DI, extensibility, configurability, etc. using convetions.

We work on a proof of concept how we could (I will use it on my new project) use it. I publish the complete project later. But what I want to decribe here is that Caliburn supports the convetion style with the default property binding and how it would be good to extend it.

Let’s say I have a view model with the property Item which has the properties Title and Description.
So the final result I’d like to achieve is:

 

So XAML for that above result with the default element convention is:

 

Hm, I’m mixing convention and explicit style of definition. That’s not very good, I think. If I argue that Convetions are perfect I would like to use them in more than default situations.

Caliburn supports extensible model of conventions in this way (I write it in BDD style, it’s just for inspiration):

As a developer
I want to extend the default property convetions for new controls so
That I'll be able to use that convetion for new controls.

A possible solution could be:

 as a developer
 I want to extend the ANY! property convetions for ANY! controls
 so that I'll be able to use that convetions in UI layer.

So then I would write in XAML the following:

To support this I had to extend Caliburn convetion model:

  1. IElementConvention has new property

    This will enable to specify both: bindable property(target – where the data will be bound) and identification property (source – specifies what property contains the source data property name)

  2. DefaultElementConvetion which implements IElementConvetion
  3. DefaultConvetionManager which enables to specify both convention-required properties. Example for Textblock control:


    The fist definition code adds the default convention with “Name” as the identification property and “Text” as  the bindable property.
    The second definition code adds the additional convention for Tooltip where bindable and identification properties are same.

  4. method TryCreateApplication – a place where the convetion is tranformed into so called applicable binding and where the value in Identification property is taken as a source for determining the path to bind in the XAML binding.

I’m going to post it to the author of Caliburn if that would be a feature suitable for the framework. I think it culd be because it would enable to extend the default element bindings not only for Name properties but for any such property.

 

That’s all for now ;o)

February 28, 2011

Entity Framework: logging

Filed under: .NET, Entity Framework, Uncategorized — Tags: , , — Frantisek @ 11:25 am

I use EF4 CTP5 and I’d like to log ANY!!! SQL commands sent to the DB. You can use the method ToTraceString() to display the SQL commands of any ObjectQuery, but … you are not able to see the queries generated i.e. while saving changes OR lazy loading. You need to use i.e. EFProfiler to log it. EFProfiler is very cool tool but … I need to log it by my application.

So I found out the Tracing and Caching implementation by Jaroslaw Kowalski here which extends EF with tracing/logging and caching capabilities. The main disadvantages I found out are:
a) you need to you both! features otherwise logging/tracing will not work. I wanted to use only logging! After doing so I started to get strange exception (or I had to do something wrong). After enabling also tracing, it started to work. Shame because I needed to use ONLY tracing.
b) your Context classes HAS to be derived from his special classes.

Honestly, I don’t use this solution. It’s too much work.

MS guys, I’m sorry but I must say: IT’S BIG SHAME EF WAS NOT DEVELOPED IN EASY EXTENSIBLE MANNER with i.e. ServiceLocator, interceptors, etc. in place.

As far as I know, and correct me if I’m wrong, adding logging capabilities fits to AOP interceptors.

I.e. EFProfiler has quite hardly injects itself into creating new DB connection logic and then it has a capability to log everything. Their solution is more transparent than a by Mr. Kowalski.

My solution
I used the ideas from NHProfiler and I generalized it little bit. I made base AOP filter called IAopFilter.

public interface IAopFilter

    {

        void CommandDurationAndRowCount(Guid connectionId, long milliseconds, int? rowCount);

        void ConnectionDisposed(Guid connectionId);

        void ConnectionStarted(Guid connectionId);

        void DtcTransactionCompleted(Guid connectionId, TransactionStatus status);

        void DtcTransactionEnlisted(Guid connectionId, IsolationLevel isolationLevel);

        void StatementError(Guid connectionId, Exception exception);

        void StatementExecuted(Guid connectionId, Guid statementId, string statement);

        void StatementRowCount(Guid connectionId, Guid statementId, int rowCount);

        void TransactionBegan(Guid connectionId, System.Data.IsolationLevel isolationLevel);

        void TransactionCommit(Guid connectionId);

        void TransactionDisposed(Guid connectionId);

        void TransactionRolledBack(Guid connectionId);

    }

Due to the short of the time, I made only 1 its implementation and it was using Log4Net capabilities. Then I had to create AOP capable DbProviderFactory class called DbProviderFactoryEx which uses IAopFilters. In addition I had to create whole family of the classes following abstract factory pattern implemented in DbProviderFactory.

The main class is called EntityFrameworkExtender. This class wires-up AOP capabilities into EF. You just need to call:
EntityFrameworkExtender.Initialize();

The class by default uses Log4NetFilter as only the one filter but you can freely configure it.

EntityFrameworkExtender.Filters = () => new[] {new Log4NetFilter(“MyClass”)};

            EntityFrameworkExtender.Initialize();

Using it you are able transparently trace/log every SQL command sent from EF to DB.

I think, we, EF users would profit very much IF the EF team would develope the framework on enterprise level – easily extensible, configurable and if we could get also the unit tests! together with the framework.

[UPDATED!]
I bundled the whole source code into 1 project. The whole source code can be found here – save it as a file to the local disk  and delete .doc extension. It’s  normal zip file.
To use it you will need: log4net 1.2.10.0, EF4 CTP5, .NET 4.0

February 25, 2011

Entity Framework: Problem/Solution of default connection closing !

Filed under: .NET, Entity Framework, NCommon, StructureMap, Uncategorized — Tags: , — Frantisek @ 11:05 pm

I use EF CTP5 on my last project together with NCommon and its UnitOfWork, Repositories, IoC and DI abstracted by MS P&P team and StructureMap as the concrete implemetation of IoC and DI.

Problem :
Let’s have the following example (I took the example from the NCommon unit tests and extend it to do the same Linq query twice):

using (var scope = new UnitOfWorkScope())

{

    var repository = new EFRepository<User>();

 

    User user;

    user = repository.Where(u => u.ComsiID == "login").FirstOrDefault();

    user = repository.Where(u => u.ComsiID == "login").FirstOrDefault();

 

}

 

Just for the completion: creating new UnitOfWorkScope starts the DB transaction. In the above example, using UnitOfWork we create and start the transaction. Then we create new EFRepository instance which creates the ObjectContext. ObjectContext uses the connection identified by the same name AppDb and handles the connection on its own. Then we query the DB. EF opens the connection (this implies that the connection is enlisted into the current running transaction), reads the data and then close the connection. Fine! But then next (in this demo case) same query does the same: opens the connection. Because we run inside the transaction, so the connection is also enlisted into the transaction. And because there was already enlisted connection the transaction mechanism propagates it into DTS.

The result of the above code is that it works and sometimes not! The exception is following:
System.Data.EntityException: The underlying provider failed on Open.
---> System.InvalidOperationException: The connection object can not be enlisted in transaction scope.



THE PROBLEM IS IN ENTITY FRAMEWORK!!!!! and the result of the test depends on the underlying DB. If you use SQLExpress edition (as is used by default in NCommon unit tests), everything works fine! SQLExpress can not elevate the transaction to MS DTC. But if you change the connection to the real SQL server you starts to have the problems.

The problem is that in case you don’t send the concrete connection instance to EF, EF handles the connection status on his own => closes as soon as possible. I understand it but in case of Transaciton is fails! It would be good to have there a switch to configure that behavior. Anyway, the reality is different so how to fix it.

The solution is to manage the connection by your own and while creating the ObjectContext pass already created and open connection. You can find many examples about it on the internet.

Hm, fine but … not so nice. You need manually on all places where ObjectContext, or your class derived from ObjectContext, is used to manage the connection

With NCommon and it’s configuration capabilities you can do the following:

NCommon.Configure.Using(adapter)

    .ConfigureData<EFConfiguration>(config => config.WithObjectContext(

        () =>

        {

            AppDb db = new AppDb();

            if (Transaction.Current != null)

            {

                db.Connection.Open();

            }

            return db;

        }))

.ConfigureUnitOfWork<DefaultScopeUnitOfWorkConfiguration>();

 

 

So you don’t need to do open the connection over and over and on different places. Just configure NCommon on one place and use it. That’s the power of the centralized factory code-enabled configurations. In this case, thanks to StructureMap and NCommon!


Here is my full unit test class (using MS Tests):

[TestClass]

    public class SimpleTests

    {

        public IServiceLocator MyServiceLocator;

 

        [TestInitialize]

        public void Setup()

        {

            var _state = new FakeState();

            var _unitOfWorkFactory = new EFUnitOfWorkFactory();

            var _connectionString = ConfigurationManager.ConnectionStrings["AppDb"].ConnectionString;

            _unitOfWorkFactory.RegisterObjectContextProvider(

                () =>

                        {

                            var ctx = new AppDb(_connectionString);

                            if (Transaction.Current != null)

                            {

                                ctx.Connection.Open();

                            }

                            return ctx;

                        });

            var _locator = MockRepository.GenerateStub<IServiceLocator>();

            _locator.Stub(x => x.GetInstance<IUnitOfWorkFactory>()).Return(_unitOfWorkFactory);

            _locator.Stub(x => x.GetInstance<IState>()).Do(new Func<IState>(() => _state));

            ServiceLocator.SetLocatorProvider(() => _locator);

        }

 

        [TestCleanup]

        public void Cleanup()

        {

        }

 

        [TestMethod]

        public void Can_perform_simple_query()

        {

                using (var scope = new UnitOfWorkScope())

                {

                    var repository = new EFRepository<User>();

 

                    User user;

                    user = repository.Where(u => u.ComsiID == "a").FirstOrDefault();

                    user = repository.Where(u => u.ComsiID == "a").FirstOrDefault();

 

                }

        }

I must again say, NCommon and StructureMap rocks!

Happy coding…

February 24, 2011

NCommon: read-only operations = Unit Of Work without DB transaction

Filed under: .NET, NCommon, Uncategorized — Tags: — Frantisek @ 10:10 pm

Using NCommon I found one feature which can be an issue in some cases.

Repository can ONLY be used when you started an unit of work around it. Example:

using (var scope = new UnitOfWorkScope())

            {

                var savedCustomer = new EFRepository<Customer>()

                    .First(x => x.CustomerID == customer.CustomerID);

                scope.Commit();

            }

When new unit of work is created then it automatically starts the database transaction in the mode ReadCommited. Issue is that in case I need ONLY to read a data then I think, it’s too heavy. In other words why to pay the performance costs of creating a transaction when I want only to read the data from DB. In the default NCommon implementation this wouldn’t work:

var savedCustomer = new EFRepository<Customer>()

                    .First(x => x.CustomerID == customer.CustomerID);

I think it would be good avoid creating the DB transactions in case of read-only queries. It’s quite generic/DB-provider independed functionality so it fits into the base NCommon Repository classes. Unfortunatelly, I didnt want to change the base classes because in case new NCommon is releases and I changed the core functionality then I need to be in sync with latest NCommon verions. So I created my derived implementation for Entiry Framework v4. If there is no unit of the work created I create a single call unit of work without any transaction. Again, I think the change should be in the base NCommon classes but I wanted to stay compactible with the base classes as much as possible so I changed only the concrete Repository implementation for Entity Framework.

So using my changes the previous example works!

What do u think?

The changed NCommon for EFv4 can be found here

August 11, 2010

IEnumarable with a Count = IEnumerableList

Filed under: .NET, Uncategorized — Frantisek @ 1:07 pm

I do Domain-Drive-Design (DDD) and one of the golder rules practically says that the domain model shouldn’t expose more necessary.

Example:

    1 public class Item

    2 {

    3     public IList<Bid> Bids

    4     {

    5         get; private set; }

    6 

    7     public Item()

    8     {

    9         Bids = new List<Bid>();

   10     }

   11 }

   12 

   13 public class Bid

   14 {

   15 }

The class Item has collection of the Bid(s). So Item can expose property IList Bids {get;}. The problem is that in case Bid has a reference to Item then it’s possible that that Bid1 whose parent item is Item1 is added to Item2. The designer of the domain model enable us to do it. This is violation of the domain model rules.

Solution: we should add method AddBid(Bid bid) {} to the class Item and change the Item’s property Bids to the following IEnumerable Bids {get;}

Fine, but what to do in case there is a logic which would like to know how many bids some item has. IEnumerable doesn’t expose such property. For such cases I create my IEnumerableList.

    1 public interface IEnumerableList<T> : IEnumerable<T>

    2 {

    3     /// <summary>

    4     /// Gets the <see cref="T"/> at the specified index.

    5     /// </summary>

    6     /// <value></value>

    7     T this[int index] { get; }

    8 

    9     /// <summary>

   10     /// Gets the count.

   11     /// </summary>

   12     /// <value>The count.</value>

   13     int Count { get; }

   14 }

and I also created the List implementation called EnumerableList:

    1 public class EnumerableList<T> : IEnumerableList<T>

    2 {

    3     private readonly IList<T> underlyingList;

    4 

    5     /// <summary>

    6     /// Initializes a new instance of the <see cref="EnumerableList&lt;T&gt;"/> class.

    7     /// </summary>

    8     /// <param name="list">The list.</param>

    9     public EnumerableList(IList<T> list)

   10     {

   11         underlyingList = list;

   12     }

   13 

   14     #region Implementation of IEnumerable

   15 

   16     /// <summary>

   17     /// Returns an enumerator that iterates through the collection.

   18     /// </summary>

   19     /// <returns>

   20     /// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.

   21     /// </returns>

   22     /// <filterpriority>1</filterpriority>

   23     public IEnumerator<T> GetEnumerator()

   24     {

   25         return underlyingList.GetEnumerator();

   26     }

   27 

   28     /// <summary>

   29     /// Returns an enumerator that iterates through a collection.

   30     /// </summary>

   31     /// <returns>

   32     /// An <see cref="T:System.Collections.IEnumerator"/> object that can be used to iterate through the collection.

   33     /// </returns>

   34     /// <filterpriority>2</filterpriority>

   35     IEnumerator IEnumerable.GetEnumerator()

   36     {

   37         return underlyingList.GetEnumerator();

   38     }

   39 

   40     #endregion

   41 

   42     #region Implementation of IEnumerableList<T>

   43 

   44     /// <summary>

   45     /// Gets the <see cref="T"/> at the specified index.

   46     /// </summary>

   47     /// <value></value>

   48     public T this[int index]

   49     {

   50         get { return underlyingList[index]; }

   51     }

   52 

   53     /// <summary>

   54     /// Gets the count.

   55     /// </summary>

   56     /// <value>The count.</value>

   57     public int Count

   58     {

   59         get { return underlyingList.Count; }

   60     }

   61 

   62     #endregion

   63 }

And the final solution looks like the following:

    1 public class Item

    2    {

    3        public IEnumerableList<Bid> Bids

    4        {

    5            get

    6            {

    7                return new EnumerableList<Bid>(_bids);

    8            }

    9        }

   10        private IList<Bid> _bids;

   11 

   12        public Item()

   13        {

   14            _bids = new List<Bid>();

   15        }

   16 

   17        public void AddBid(Bid bid)

   18        {

   19            _bids.Add(bid);

   20        }

   21    }

   22 

   23    public class Bid

   24    {

   25    }

In this case the domain model doesn’t allow me to do prohibited action.

Original article was published at www.Catarsa.com

March 11, 2010

StructureMap v2.6.1 released!

Filed under: .NET, Di Factory, StructureMap, Uncategorized — Frantisek @ 9:30 pm

There is new version of really usefull library used for DI, IoC – called StructureMap – released. You can find more about that new version on the blog from Jeremy Miller, here

Jeremy explains what was changed there and what’s new but … we miss the up-to-date documentation ….

It’s really cool library, we use it quite much on our projects and it’s really a killer against other similar libraries (I’ll write a post about it later).  I was looking forward to check the new version and use it but here are my comments:

1) API was changed quite massively and there were made obsolete many methods and few were removed. I must say, that the comments used on the Obsolete attribute are not usefull in all situations the old version was able to be used (see example bellow).

2) The release is missing an up-to-date documentation describing how to migrate from old version to the latest version. The migration to the new version is not very straightforward, IMHO. The package (binaries), which you can download from here contains only binaries ;o), no documentation, no tests (which can act as a kind of the document as well), etc.

Solution

I think the NUnit tests are very good source of the documentation and explanation how to use the explored library and it should be UP-TO-DATE. So for all who wants to migrate to new version of Structure and dont want to wait for the documention or Jeremy’s blogs I propose the following:

download the full package which includes also NUnit tests 😮 from here (scroll down and take the latest commit, it includes more than 11MBs of data) and spend some time with analyzing code and NUnit tests.

My feedback

I really support the libraries with Fluent approach. Structure map has it but I think, some changes, which should be more fluent in the newer version are less fluent now.

Example: AsSingleton() construct replaced with Singleton(), as following:

I think, more fluent version would be:

I think it’s more fluent. I must say it took me a while to find it out, especially when old construct was completely different with AsSingleton() at the end ;o  I know, my suggestion i’s small change, but I would say, it would bring more fluent voice.

Another, but I think, bigger change was related to situation when we want to add the named instances to the container. It’s connected to the class IInstanceExpression<T> and its OfConcreteType<PLUGGEDTYPE>() method like on the following:

The obsolete attribute advice what to use is nice but useless in the situation when we use AddInstances() construct.

In this case we are not able to avoid using OfConcreteType<T>(). There are 2 possible solutions:

The first is to use the For<T1>().Add<T2>.Named(“name”) like on the following picture:

OR

the old way which was used in 2.5.4 version:

and live with the fact that there will be warnings.

I checked the NUnit tests from StructureMap because I wanted to know how to use this construct correctly and I was disappointed that the there is used the OLD version of the solution (the obsolete methods with the warnings) like the following:

Summary

It’s a shame that the release 2.6.1 contains API changes but MANY NUnit tests uses old, Obsolete version of the API. So the documentation is not up-to-date nor the tests.

I think, the team shouldn’t change the API without changing the unit tests to use that new API and thus providing us a solution how to migrate from old  version to the new version.

Anyway, StructureMap is really nice library with many very useful features, going hand in the hand with TDD, Mocking, Plugins, etc. and the biggest advantage is the implementation of Convention over Configuration approach which is unique!

I hope Jeremy will have more free time to blog more about the newest version.

January 4, 2010

SSL support in ASP.NET MVC

Filed under: .NET, ASP.NET MVC — Frantisek @ 9:25 am

I have some views which I need to secure with SSL (HTTPS) and rest should be plain HTTP.  Thankfully, MVC 2 supports RequireSSL attribute to ensure the cuser is performing the action with HTTPS protocol. Fine! Cool!

But if the user is on the view secured by HTTPS then all links (ALL!) created by ActionLink extensions methods are secured! So the question is who/how and when to navigate back to the unsecured links/views?

I tought that the routes configuration is the part where to setup the routes and then we should just use route capabilities to create the links, redirects, etc. In other workds, the configuration is on 1 place and only once! and I can generate the links from all other places. If I want to change the links, I should change only route configuration and all should work well. And whole implemnetaiton should follow DRY principle. But it’s not true. I can’t specify that all links should be sent over HTTP except some special routes which should be handled by HTTPS.

I’ve read several sources how to implement it, i.e. http://blog.codeville.net/2008/08/05/adding-httpsssl-support-to-aspnet-mvc-routing/ and Steve’s  implementation solves DRY principle but it overwrites VirtualPath to the absolute path and then the special context wrapper corrects it back.  I implemented it different way.

So what is my solution?

The idea behind the scene consists of 3 parts:

1) when configuring the routes, I add the data token scheme to the route definition

routes.Add(new Route("Account/Login", new MvcRouteHandler())
        {
            Defaults = new RouteValueDictionary(new { controller = "Account", action = "Login" }),
            DataTokens = new RouteValueDictionary(new { scheme = "https" })
        });

2) I had to implement and use my own ActionLink extentions methods called MyActionLink (hm, super name, isn’t?). MyActionLink methods are almost same as the default ActionLink implementation except the method with full parameter set.

public static MvcHtmlString MyActionLink(this HtmlHelper htmlHelper, string linkText, string actionName)
        {
            return htmlHelper.MyActionLink(linkText, actionName, null, new RouteValueDictionary(), new RouteValueDictionary());
        }
        public static MvcHtmlString MyActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, object routeValues)
        {
            return htmlHelper.MyActionLink(linkText, actionName, null, new RouteValueDictionary(routeValues), new RouteValueDictionary());
        }
        public static MvcHtmlString MyActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName)
        {
            return htmlHelper.MyActionLink(linkText, actionName, controllerName, new RouteValueDictionary(), new RouteValueDictionary());
        }
        public static MvcHtmlString MyActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, RouteValueDictionary routeValues)
        {
            return htmlHelper.MyActionLink(linkText, actionName, null, routeValues, new RouteValueDictionary());
        }
        public static MvcHtmlString MyActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, object routeValues, object htmlAttributes)
        {
            return htmlHelper.MyActionLink(linkText, actionName, null, new RouteValueDictionary(routeValues), new RouteValueDictionary(htmlAttributes));
        }
        public static MvcHtmlString MyActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes)
        {
            return htmlHelper.MyActionLink(linkText, actionName, null, routeValues, htmlAttributes);
        }
        public static MvcHtmlString MyActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, object routeValues, object htmlAttributes)
        {
            return htmlHelper.MyActionLink(linkText, actionName, controllerName, new RouteValueDictionary(routeValues), new RouteValueDictionary(htmlAttributes));
        }
        public static MvcHtmlString MyActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes)
        {
            if (string.IsNullOrEmpty(linkText))
            {
                throw new ArgumentNullException(linkText);
            }
            var requestContext = htmlHelper.ViewContext.RequestContext;
            var values = MergeRouteValues(actionName, controllerName, requestContext.RouteData.Values, new RouteValueDictionary(), true);
            var vpd = htmlHelper.RouteCollection.GetVirtualPath(requestContext, values);
            return htmlHelper.ActionLink(linkText, actionName, controllerName,
                (string)vpd.DataTokens["scheme"], (string)vpd.DataTokens["hostname"], null, routeValues, htmlAttributes);
        }

Note: The samilar changes can be done with RedirectToAction<T> and RedirectToAction methods in order to take care of “scheme”. But what I do is that I display the view that the secured action was done successfully and then the user is redirected to i.e. the index view of the controller.

3) decorate the appropriate action with RequireSSL attribute.

        [RequireHttps]
        [HttpPost]
        public ActionResult LogOn(LoginInput input)
        {
            ....
        }

And that’s all!

And you can use it as you would use ActionLink just with name MyActionLink.  So I replaced all ActionLink(s) to MyActionLink and that was all!

In my project I use MvcContrib. So I changed MvcRoute to include scheme “http” by default, all my links are created by MyActionLink extension method and sensitive actions are decorated with RequireSSL.

Do you know other, better implementation? Please, let me know.

March 11, 2009

TT template for MVC Grid with ordering and paging

Filed under: .NET, ASP.NET MVC, MVCContrib, TextTemplate — Tags: , , — Frantisek @ 1:35 pm

In my previous posts I wrote about my extensions to MVCContrib grid like paging and ordering.

It’s tedious work to create the pages with the grid and define all the columns by hand. As you know from MVC RC1 it’s possible to use the TT templates to gerenate the views. I found a TT template fofr MVC Grid somewhere on the web and I extended it to generate the views using my extentions for ordering an paging.

Here is a screenshot from the template:

mvccontrib

When you copy such template to the folder:

C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\ItemTemplates\CSharp\Web\MVC\CodeTemplates\AddView

then you will be able to use it in the dialog:

mvc_addview

and here is the result:

mvc_addview_result

While generating the view using the entities which are derived from some base class which is not in the same assembly as the entity, you can get the exception “Could not load type …”. You need to copy the base assembly to the location “C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PrivateAssemblies\\” and then it starts to work properly.

Using such template mechanism the developer can create the lists, details, etc. very quickly . The heart of the whole process is TT template. Just briefly, there is quite exhaustive blog here regarding TT templates.

The template can be found here

March 6, 2009

Ordering in the MVCcontrib grid

Filed under: .NET, ASP.NET MVC, MVCContrib — Frantisek @ 2:53 pm

I miss an ordering functionality in the grid so I had to extend it using and extension method of HtmlHelper.

What I want to achieve
When a user comes to my grid, the url could be i.e.

http://www.site.com/cars/list

and when the user clicks a link in the header to order the data in the gird then the URL could be changed to

http://www.site.com/cars/list?orderby=name,true

In addition we should be able to inform the user about current ordering (asc,desc)  and the user should have possibility to click the link to change the ordering in the header.

In short something like this:

ordering

Current MVCContrib doesn’t include such support so I added it.

I made an extension methods which you can you like in the following:

ordering_code

OrerbyLink extension methods have to check the current URL to see what’s the current ordering. It would be nicer if this would be part of some
interface as well as it is done with IPagination.

I think, it would be quite good if IPagination would be renamed to ICollectionModel which could contain both:
1) info about the pagination
2) info about the ordering
3) collection of the data itself

And then it would be good if there would be an easy way who to wrap the custom IEnumarable<T> to ICollectionModel. Propable using an extension method as it’s doen via AsPagination<T>().

The code can be downloaded from here

What do you think?

Older Posts »

Create a free website or blog at WordPress.com.