viernes, 4 de febrero de 2011

DLLs necesarios para una app portable con ODP .NET

Normalmente cuando creamos una aplicacion .NET con conexion a la base de datos Oracle, tenemos el cliente de Oracle instalado en nuestras maquinas y el DLL necesario esta en la gac entonces no necesitamos referirlo, todo funciona como se espera.

El problema esta cuando lo pasamos a un servidor de producción, no siempre encontraremos la versión esperada, es muy posible que la versión  instalada en el servidor sea utilizada por varias aplicaciones, y se te sea difícil instalar la versión que tu quieras elegir.

Para conseguir una aplicación con el driver portable, necesitas los siguientes DLLs(Todos están en el directorio donde instalaste ODP for .NET:
  • msvcr71.dll
  • oci.dll
  • ociw32.dll
  • Oracle.DataAccess.dll
  • orannzsbb11.dll
  • oraocci11.dll
  • oraociicus11.dll
  • OraOps11w.dll

Te recomiendo que en tu solución crees una carpeta y ahí copies todos los DLLs necesarios, después solo tienes que referirlos en tu proyecto y cambias las propiedad Copy Local de todos los DLL necesarios a True.

No podrás depender del tsnames.ora  así que utiliza este tipo de connection string:

Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=MyHost)(PORT=MyPort)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=MyOracleSID)));User Id=myUsername;Password=myPassword;

Con esto no necesitaras instalar el cliente de oracle, para la instalación de tu aplicación no necesitaras investigar si tu servidor soporta tu version de ODP .NET, y podrás tener TU el control de cual versión de ODP quieres usar.


jueves, 3 de febrero de 2011

Integracion de ASP .NET MVC 3 a un proyecto de Web Forms

En esta entrada documento como integrar web forms con asp .net mvc3. Esta nueva entrega tiene varias funcionalidades nuevas como el nuevo razor engine y soporte a unobstrusive javascript, para mas informacion

Mi guia esta basada en este tutorial pero hay que hacer algunas modificaciones y remover referencias innecesarias para MVC 3.
Esta guía les sirve a personas que quieren utilizar las capacidades de MVC 3 y no pueden crear un proyecto nuevo debido a que estan trabajando en una pagina existente.

Como integrar ASP .NET MVC 3 a un proyecto de ASP. NET web forms.


Lo primero es agregar todas las dependencias necesarias


  • System.Web.Routing
  • System.Web.Abstractions
  • System.Web.Mvc
  • System.Web.Helpers
  • System.Web.WebPages
  • System.Web.Razor
  • System.Web.WebPages.Razor

NOTA: Te recuerdo que es importante de que incluyas los DLLs si no están en la GAC( o si no están instalados en tu servidor de producción) dandole click derecho a cada referencia, seleccionando propiedades, y cambiando la opcion "Copy Local" de False a True.
(Para revisar los assemblies en la GAC, asi estas seguro de si debes incluirlos o no, debes de entrar a la ruta
%windir%/assembly y ver si se encuentran en el listado). Abajo una imagen de donde esta la propiedad.


El próximo paso es crear las estrucutras de directorios que utiliza MVC(debido a su principio de convención sobre configuración), creando las carpetas Controllers, Views y dentro de Views, creas otra carpeta llamada Shared.



Despues debemos de configurar en el web.config para adaptarlo a las necesidades de MVC.



<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="UnobtrusiveJavaScriptEnabled" value="true"/>
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.0">
      <assemblies>
        <add assembly="System.Core, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089"/>
        <add assembly="System.Web.Extensions,
Version=4.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35"/>
        <add assembly="System.Web.Abstractions,
Version=4.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35"/>
        <add assembly="System.Web.Routing,
Version=4.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35"/>
      </assemblies>
    </compilation>
    <pages>
      <namespaces>
        <add namespace="System.Web.Mvc"/>
        <add namespace="System.Web.Mvc.Ajax"/>
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Routing"/>
        <add namespace="System.Linq"/>
        <add namespace="System.Collections.Generic"/>
      </namespaces>
    </pages>
  </system.web>
</configuration>



NO se debe de sobrescribir la configuración actual con esta, solamente se deben de agregar los nodos que no están en el web.config del proyecto.

Solo falta configurar el enrutamiento de los requests. Para esto se necesita el elemento Global.asax, si no esta agregado en tu proyecto, debes de agregarlo. Para poder coexistir con ASP .NET se ignorara cualquier request que termine en .aspx, el codigo para lograr esto es el siguiente:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using System.Web.SessionState;
using System.Web.Routing;

namespace AspDemo
{
    public class Global : System.Web.HttpApplication
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.Ignore("{resource}.axd/{*pathInfo}");
            routes.Ignore("{resource}.aspx/{*pathInfo}");
            routes.MapRoute(
            "Default",
                // Route name
            "{controller}/{action}/{id}",
                // URL with parameters
            new { controller = "Home", action = "Index", id = "" }
                // Parameter defaults
            );
        }

        void Application_Start(object sender, EventArgs e)
        {
            RegisterRoutes(RouteTable.Routes);
        }

        void Application_End(object sender, EventArgs e)
        {
        }

        void Application_Error(object sender, EventArgs e)
        {
        }

        void Session_Start(object sender, EventArgs e)
        {
        }

        void Session_End(object sender, EventArgs e)
        {
        }

    }
}


Para habilitar razor se necesita un web.config igual al siguiente dentro de la carpeta Views.


<?xml version="1.0"?>

<configuration>
  <configSections>
    <sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
      <section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
      <section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
    </sectionGroup>
  </configSections>

  <system.web.webPages.razor>
    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <pages pageBaseType="System.Web.Mvc.WebViewPage">
      <namespaces>
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Routing" />
      </namespaces>
    </pages>
  </system.web.webPages.razor>

  <appSettings>
    <add key="webpages:Enabled" value="false" />
  </appSettings>

  <system.web>
    <httpHandlers>
      <add path="*" verb="*" type="System.Web.HttpNotFoundHandler"/>
    </httpHandlers>

    <!--
        Enabling request validation in view pages would cause validation to occur
        after the input has already been processed by the controller. By default
        MVC performs request validation before a controller processes the input.
        To change this behavior apply the ValidateInputAttribute to a
        controller or action.
    -->
    <pages
        validateRequest="false"
        pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
        pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
        userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
      <controls>
        <add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" namespace="System.Web.Mvc" tagPrefix="mvc" />
      </controls>
    </pages>
  </system.web>

  <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />

    <handlers>
      <remove name="BlockViewHandler"/>
      <add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
    </handlers>
  </system.webServer>
</configuration>


Debes de colocar el archivo Web.config con esta configuración en la carpeta Views.



Con esto ya tendrás intellisense cuando crees archivos .cshtml.

Ahora para probar la configuración creemos un controlador de prueba.



using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace IntegracionWebFormMVC.Controllers
{
    public class DemoController : Controller
    {
        public ActionResult Index() {
            ViewData["Message"] = "We are a family!";
            return View();
        }
    }
}


y un view para el mismo creando la carpeta Demo en Views y creando el archivo Index.cshtml.



<!DOCTYPE html>
@{
    ViewBag.Title = "Home Page";
}
<html>
<head>
    <title>@ViewBag.Title</title>
</head>

<body>
    <div class="page">

        <div id="header">
            <div id="title">
                <h1>My MVC Application</h1>
            </div>
        </div>

        <div id="main">
            @ViewData["Message"]
        </div>
            <div id="footer">
            </div>
      
    </div>
</body>
</html>



Compilalo todo y correlo con el servidor de prueba de Visual Studio, al llamar localhost:[TuPuertoAsignado]/Demo, obtendras la pantalla debajo:



El codigo fuente aqui.

Con esto finalizo el tutorial, espero que les sea útil.