ASP.NET MVC and ReturnUrl

I’ve seen many ASP.NET MVC samples and some of them do not honor de ReturnUrl parameter, rendering this unusable.

Classic ASP.NET has the login form component that puts the same exact URL used to access the login page in the form action URL, preserving the ReturnUrl parameter and then, FormsAuthentication.GetReturnUrl() gets it from the Request.QueryString collection.

Fortunately, the GetReturnUrl() method looks as well in Request.Form in case there’s nothing in the query, this way, we can use a hidden field as well to store the ReturnUrl in the View and pass it through POST when the login form is submitted.

So, in ASP.NET MVC we have two options:

  1. Use simply Html.BeginForm() without parameters, which will put a simple form tag, with the same URL as the current one and use POST by default
  2. If we want to have more control on the Html.BeginForm(), put a hidden field with the value of the ReturnUrl, only if the ReturnUrl is not empty, or it will fail. This can be obtained from the Request.QueryString collection, the ViewData if we put it previously on the Controller action or even better store it in the ViewModel and have a strong typed reference.

And that’s it. Then, FormsAuthentication.GetReturnUrl() will get the proper URL and other methods like FormsAuthentication.RedirectFromLoginPage() will also work seamlessly.

El principio KISS

El nombre del principio es el acrónimo del inglés Keep It Simple, Stupid o Keep It Short and Simple. El sentido, se puede imaginar. Es en realidad la aplicación de lo que se conoce como La Navaja de Occam (Ockham’s Razor) aplicado a la informática. Todo se basa en una simple premisa: “dadas dos soluciones a un problema determinado, la más simple es probablemente la correcta”.

Aplicado al mundo del desarrollo de software, lo que se conoce como el principio KISS, implica resolver los problemas del modo más sencillo posible y posiblemente ésta sea la mejor solución.

Código
Desde el punto de vista del código tiene más implicaciones a parte de la simplicidad:

  • Un código más simple es más sencillo de mantener, lo que ahorrará tiempo en el futuro.
  • Además, será más sencillo de comprender por cualquier persona que entre en el equipo de desarrollo.
  • Cuesta menos de escribir
  • Menos lineas equivalen a menos bugs, lo que significa código de mayor calidad

Gestión de proyectos
Pero todo esto carece de sentido si desde no se tiene también en cuenta desde el nivel de gestión de los proyectos de software. Es estupendo pensar en miles de funcionalidades para un producto pero ¿qué sentido tienen? Primero habrá que hacer lo más simple para luego ir añadiendo más cosas a una base sencilla y comprensible.

Hay que construir software sobre una base sólida y unos requisitos simples y concretos. Esto permitirá desarrollar unas funcionalidades simples y robustas en menos tiempo y una vez el producto tiene cara y ojos, se pueden ver las carencias y se pueden encontrar nuevas posibilidades.

Pensar en cientos de funcionalidades, además tiene otras implicaciones menos obvias:

  • Tests de usuario menos frecuentes pero mucho más complejos y largos.
  • Bugs más difíciles de encontrar y de solucionar.
  • Time-To-Login (tiempo entre que se empieza el desarrollo hasta que se tiene una primera release) mucho más alto.

Muchas de las metodologías ágiles se basan en parte en este principio para desarrollar un software evolutivo en vez de crear gran cantidad de especificaciones y documentos que pueden tardar años en implementarse y meses en integrarse.

En resumen, antes de escribir un método, piensa si no lo estás complicando demasiado y antes de añadir un requisito a una release… piensa si realmente es necesaria en ese momento. Recuerda: KISS.

Principios básicos de OOP: SOLID

Últimamente reviso mucho código, tanto mío como de otros y me doy cuenta de que muchas veces se pasan por alto los principios básicos del paradigma de orientación a objetos y en muchos casos porque la formación es deficiente o inexistente.
Así pues, uno de los acrónimos en el mundillo de la programación orientada a objetos (OOP) es SOLID, que sirve de regla mnemotécnica para recordar 5 principios básicos:

SRP: Single Responsibility Principle:
El principio de responsabilidad única nos dice que nunca debe haber más de un motivo para que una clase cambie, o lo que es lo mismo, que una clase solamente debe tener un propósito. Esto parece simple pero en realidad es uno de los principios más fáciles de violar y muchas veces no es fácil distinguir las responsabilidades.

OCP: Open-Closed Principle:
El principio abierto/cerrado implica que las clases de software deben estar abiertas para la extensión pero cerradas para la modificación. Este es el principio por el cual se hacen privadas las variables del miembro o que no se usan variables globales. El truco de este principio está en la abstracción. Las clases abstractas implementan un código inalterable desde fuera pero obligan a extender de ellas para usar este código a parte de que se promueve la reusabilidad.

LSP: Liskov Substitution Principle:
El principio de sustitución de Liskov implica que las clases derivadas deberían poder ser sustituidas por sus clases base. Es decir, es en cierto modo una extensión del principio anterior: mientras que OCP promueve la herencia de clases base, LSP promueve que la herencia se haga de forma transparente, es decir, que heredar es bueno pero no hay que olvidar las raíces. Es decir, no implementemos un método en una clase heredada que no esté en la clase base porque romperemos este principio.

De OCP y LSP se deduce que las clases base (abstractas o no) modelan el aspecto general y las clases heredadas modelan el comportamiento local.

DIP: Dependency Inversion Principle:
Básicamente, el principio de inversión de dependencia promueve que hay que depender de abstracciones, no de concreciones. Dicho de forma más compleja, los módulos de más alto nivel no deben depender de los de más bajo nivel sino que ambos deben depender de abstracciones. Y a su vez, las abstracciones no deben depender de los detalles sino al contrario.

En este caso, el uso de interfaces resulta muy beneficioso y un framework de inversión de control (Castle Windsor, StructureMap, por citar algunos) van a hacer que resulte más obvia la necesidad de abstracciones. Además, el testado unitario resulta mucho más sencillo ya que la independencia entre los distintos módulos es muy elevada.

ISP: Interface Segregation Principle:
Este principio de segregación de interfaces indica que no se debe hacer depender las clases de interfaces que no necesitan y que debe haber granularidad en las interfaces para dotar de aspectos específicos a las distintas implementaciones.

En general, en Java y C# se pueden implementar tantos interfaces como se quiera por lo que es sencillo llevar a cabo este principio. Las interfaces son la forma más práctica de modelar las clases y dotarlas de aspectos particulares así como incluso tratarlas de diferente modo según las interfaces implementadas.

Y estos son básicamente los principios SOLID que aunque llevan ya muchos años siguen siendo vigentes y ayudan a desarrollar un código más reusable, mantenible y claro. Además, con las herramientas actuales de refactorización es muy fácil extraer interfaces y clases abstractas de las ya existentes sin tener que revisar cientos de líneas de código. Y cómo no, tener un buen conjunto de tests unitarios ayudará a que cualquier refactorización se haga sin miedo a romper toda la funcionalidad existente.

Referencias: Principles of OOD