[ASP.NET MVC] (Part I) Controllers

En el patrón Modelo Vista Controlador, la función principal del controlador es responder a los eventos, normalmente producidos por la interacción del usuario con la vista, que pueden o no causar modificaciones en el modelo.

IController Inteface

Para que una clase actue como controlador, como mínimo debe implementar la interfaz IController:

using System;
using System.Web.Routing;
 
namespace System.Web.Mvc
{
    public interface IController
    {
        void Execute(RequestContext requestContext);
    }
}

Vamos a crear nuestro primer controlador implementado esta interfaz, para ello añadimos una nueva clase (Class.cs no Controller) a la carpeta Controllers y sustituiremos por este código:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
 
namespace Geeks.Controllers
{
    public class TestController : IController
    {
        #region IController Members
 
        public void Execute(System.Web.Routing.RequestContext requestContext)
        {
            requestContext.HttpContext.Response.Write("TestController");
        }
 
        #endregion
    }
}

Arrancamos la aplicación y probamos:

Controllers1

Una de las peculiaridades de ASP.NET MVC, es lo que se denomina Conventions over Configurations, es decir si aceptamos la norma de nomenclatura en la que todo controlador se identificará <Nombre>Controller, cuando queramos acceder al controlador bastará con utilizar solo el nombre y el Routing se encargará de hacer el resto del trabajo por nosotros, es decir, con esto nos evitamos mantener archivos de configuración, settings...

ControllerBase Class

Es la clase base para la clase Controller, que implementa IController y ademas nos provee de las propiedades TempData y ViewData, que como veremos más adelante nos servirá para enviar los datos a nuestra vista.

Controller Class

Es la clase base para nuestros controladores e implementa la clase ControllerBase

Action Methods

Tendremos que implementar nuestros Action Methods, que son métodos públicos que tienen una correspondencia 1 a 1 con las interacciones del usuario, por ejemplo, teniendo un controlador de productos, tendremos Action Methods para obtener un producto, alta, modificación, borrado…

namespace Geeks.Controllers
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using System.Web.Mvc.Ajax;
 
    public class ProductController : Controller
    {
        public ActionResult Get()
        {
            return View();
        }
 
        public ActionResult Add()
        {
            return View();
        }
 
        public ActionResult Edit()
        {
            return View();
        }
 
        public ActionResult Delete()
        {
            return View();
        }
    }
}

Sí ejecutamos http://localhost:1959/Products/Add, nos encontraremos con un error 404, porque cada Action Method de los anteriores debería tener una vista asociada (No siempre tienen porque tener asociada una vista, pero en este caso sí)

Los constructores, propiedades, eventos no pueden actuar cono Action Methods, ni los métodos definidos en la clase Object (Ej: ToString) ni Dispose()…

ActionResult

A simple vista nos puede llamar la atención que todos los Action Methods devuelven un tipo ActionResult:

using System;
 
namespace System.Web.Mvc
{
    // Summary:
    //     Encapsulates the result of an action method and is used to perform a framework
    //     level operation on the action method's behalf.
    public abstract class ActionResult
    {
        protected ActionResult();
 
        // Summary:
        //     Enables processing of the result of an action method by a custom type that
        //     inherits from System.Web.Mvc.ActionResult.
        //
        // Parameters:
        //   context:
        public abstract void ExecuteResult(ControllerContext context);
    }
}

En el primer ejemplo que vimos cuando implementamos IController, directamente escribiamos un texto a través de Response, pero esto rompe con el término inglés “Separation on Concerns”, es decir, rompemos el concepto de separación por funcionalidad, metemos en el controlador código que debería estar en la vista, por eso está la clase ActionResult y un buen ejemplo es que podemos pasar un ViewResult (Que hereda de ActionResult) a la vista y ella ya tiene el código para formatear y mostrar los datos del producto al usuario, qué por otra parte es la función de la vista:

public ActionResult Get(string id)
{
    List<Products> products = SqlRepository.GetProductById(id);
    ViewData.Model = products;
    return new ViewResult { ViewData = this.ViewData };
}

Y para simplificar código, podemos usar los Helper Methods que nos brinda la clase Controller:

public ActionResult Get(string id)
{
    List<Products> products = SqlRepository.GetProductById(id);
    return View(products);
}

Existen varios tipos de ActionResult a parte de ViewResult:

Action Method Helper Method Descripción
ViewResult View Llama al motor de vistas para renderizar la vista
PartialViewReult PartialView Como ViewResult, pero renderiza una vista parcial. Se usa normalmente en peticiones Ajax
RedirectResult Redirect Redirigir a otro Action Method usando una Url
RedirectToRouteResult RedirectToAction
RedirectToRoute
Redirigir a otro Action Method
ContentResult Content Retonar un tipo de contenido definido por el usuario
JsonResult Json Retornar contenido Json
JavaScriptResult JavaScript Retornar código JavaScript
FileResult File Retornar el contenido de un fichero (Binary Output)
EmptyResult   No hace nada (Null Object Pattern)

ActionNameAttribute

Nos permite enmascarar los nombres de los Action Methods, así podemos tener nombres más significativos en nuestro código y más facilmente accesibles a través de Url, por ejemplo:

[ActionName("Get")]
public ActionResult GetProductById(string id)
{
    return View();
}
image

ActionVerbsAttribute

Establece el método HTTP al que responderá el Action Method:

namespace Geeks.Controllers
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using System.Web.Mvc.Ajax;
 
    public class ProductController : Controller
    {
        [AcceptVerbs(HttpVerbs.Get)]
        public ActionResult Edit(string id)
        {
            return View();
        }
 
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Edit(string id, FormCollection form)
        {
            /// Save and Redirect
        }
    }
}
 
En la siguiente entrega veremos las vistas.
 
Salu2
Published 29/5/2009 14:24 por Luis Ruiz Pavón
Archivado en:
Comparte este post:
http://geeks.ms/blogs/lruiz/archive/2009/05/29/asp-net-mvc-part-i-controllers.aspx

Comentarios

# re: [ASP.NET MVC] (Part I) Controllers

Hola Luis

Tu post pinta muy interesante. Sin embargo soy uno de tantos que sabe poco de ASP.NET MVC, apenas un concepto definible en un par de líneas.

Me interesa mucho el tema y veo interesante tu post, sin embargo tengo (o tenemos) carencia en conceptos muy básicos (los típicos "10 mandamientos" que cada creador de tecnología define antes de desarrollarla.

Por ello me animo a pedirte que hagas un post con esos datos mínimos básicos que nos sirvan de introducción para absorber mejor esta tecnología.

Un cordial saludo

Saturday, May 30, 2009 12:35 PM por Julio Trujillo Leon

# re: [ASP.NET MVC] (Part I) Controllers

Hola Julio, lo primero gracias por tu comentario.

No he escrito nada introductorio y me he puesto manos a la obre porque son varios los que han hecho buenas introducciones en geeks:

geeks.ms/.../SearchResults.aspx

Salu2

Saturday, May 30, 2009 4:05 PM por Luis Ruiz Pavón