Controles fuertemente tipados en asp.net 4.5

El problema de la seguridad en internet, siempre ha sido un tema prioritario para los desarrolladores, por eso, los grandes esfuerzos de las compañías en sacar frameworks cada vez más potentes y seguros. Hoy nos orientamos a mostrar uno de esos esfuerzos que vendrá incorporado en la nueva versión de ASP.NET 4.5

Todavía es una preview, pero la próxima versión de asp.net, ya está despertando un gran interés en el mundo del desarrollo web. No solo se da más impulso a la parte estándar del html5, sino que además incorpora modificaciones que hacen aún más potente esta gran herramienta de desarrollo web.

Hoy queremos hacernos eco de una novedad, que a nuestro modo de ver es un gran avance,  y que tendrá una gran repercusión tanto en la seguridad, como en los tiempos de respuesta de nuestras aplicaciones. Nos  referimos la posibilidad de tipar fuertemente los controles enlazados a datos. Y para ello veremos un ejemplo con el control que más flexibilidad nos proporciona, pero a la vez que más complejidad requiere: El repeater.

El repreater es un control, que nos permite repetir una especie de plantilla con cada elemento enlazado dentro del datasouce. Esta característica, que es de gran utilidad, hacía uso de un enlazado de datos dinámico, lo que daba una gran flexibilidad a este control, pero a la misma vez podía aumentar el  riesgo de crear vulnerabilidades por XSS (Cross-Site Scripting).

Si ya es verdad que se dieron pasos para solucionar este problema en asp.net 4.0, ahora con el tipado fuerte de datos se ha conseguido un gran avance (ya que no nos gusta decir en material de seguridad que algo es definitivo)

En estas líneas podemos observar cómo se hace el linkado de datos al campo text a través de las instrucciones <%#Eval(‘xxx’)%>. Este código es potencialmente peligroso, ya que es vulnerable a XSS.

<asp:Repeater  ID=”rptEjemplo1” runat=”server” >

<ItemTemplate>

<asp:Label runat=”server” ID=”lblComentario” Text=’<%# Eval(“Comments”) %>’/>

<asp:Label runat=”server” ID=”lblNombre” Text=’<%# Eval(“Name”) %>’/>

<asp:Label runat=”server” ID=”lblEmail” Text=’<%# Eval(“Email”) %>’/>

</ItemTemplate>

</asp:Repeater>

 

Ahora tendremos esto mismo, pero lo haremos estableciendo una nueva propiedad (ModelType) y cambiando las etiquetas peligrosas por estas otras

 <%#Item.Clientes.Email%>

 En el que al estar tipado el control no admitirá valores que no estén contemplados en la clase que se establece como tipo del control.

Así el ejemplo anterior nos quedará de esta forma:

<asp:Repeater  ID=”rptEjemplo1” runat=”server” ModelType=”Clientes”  >

<ItemTemplate>

<asp:Label runat=”server” ID=”lblComentario” Text=’<%#Item.Clientes.Comments %>’/>

<asp:Label runat=”server” ID=”lblNombre” Text=’ <%#Item.Clientes.Name %>’/>

<asp:Label runat=”server” ID=”lblEmail” Text=’ <%#Item.Clientes.Email %>’/>

</ItemTemplate>

</asp:Repeater>

La gran flexibilidad que nos da el repeater, se ve a veces contrarrestado por la seguridad, por ello es de necesidad, que los desarrolladores conozcamos tanto los puntos fuertes como los débiles de los controles que usamos. En este punto los esfuerzos de la compañía de Redmond han sido constantes, tanto en la versión 4, donde se realizaron grandes esfuerzos como en la versión 4.5 con el tipado fuerte de datos en controles. Desde aquí animar a que se vayan probando y conociendo las nuevas características que nos traerá el nuevo asp.net 4.5

 un saludo a todos

Ahora más que nunca innovacion y Silverlight

Muchas veces, la gran diferencia entre el éxito y el fracaso de una aplicación, es la experiencia de usuario. Ya no es válido pensar que la funcionalidad dará la satisfacción al cliente. Actualmente esta premisa, sin dejar de ser necesaria, no es ni mucho menos la única que garantiza la satisfacción de los usuarios finales. Ahora nos piden que la aplicación sea fácil de usar, que sea vistosa… en una frase: Que nos aporte una rica  experiencia de usuario

Cuando hablamos de aplicaciones web, todavía hay mucha gente que piensa en aplicaciones menos ricas que las de escritorio, y con una experiencia de usuario estática. Esta idea es la que debemos de desechar, ya que el crear aplicaciones estáticas, y poco vistosas, únicamente pensadas en la funcionalidad, está ya en desuso, y poco a poco nos echa del mercado.

 No se debe despreciar el diseño, simplemente porque el usuario final sea poco avanzado o formado en el uso de las nuevas tecnologías, más bien, en este caso debe ser todo lo contrario y dotar al usuario de más herramientas que faciliten su trabajo y formarle en el uso de la nueva aplicación. 

En nuestro mundo el lema debe ser “Innovate Don´t Imitate”, muy a pesar de muchos que piensan que en la costumbre está el éxito, ya que si ofreces lo mismo ¿para qué cambiar?

Para ello en .net disponemos de una potente herramienta, Silverlight, esta tecnología nos permite generar aplicaciones Ricas, que se ejecutan en el cliente, y le da una experiencia de usuario mucho más potente a nuestras aplicaciones. No se trata solo de que los botones tengan aspectos distintos, sino del  echo de dotar de animaciones, controles multimedia en incluso de un diseño gráfico vectorial a nuestras aplicaciones web.

Además hay que contar con la ventaja que todo eso se realiza con una programación en los lenguajes que utilizamos para el resto de aplicaciones (VB o C#).

Otra ventaja son las herramientas que tenemos para poder desarrollarlas, como son las herramientas Expression (en concreto Expression Blend) y de Visual  Studio.

Yo ya he creado mis controles y aplicaciones, si no habéis empezado os recomiendo que os vayáis poniendo al día, es fácil, sencillo y para toda la familia!

Configuración de IIS7 e IIS7.5 para el uso de DNI-e

No es ningún secreto que la administración pública está intentando, cada vez más, lanzar la utilización del DNI electrónico (a partir de ahora DNI-e). No obstante aunque su uso todavía no es muy elevado, las ventajas que nos proporciona si son abundantes, como es el poder realizar gestiones con la administración pública o incluso con entidades bancarias, de manera segura.

En este post nos centraremos en cosas técnicas, y más en concreto en como configurar un IIS 7.0 o 7.5 para  que sea capaz de requerir y admitir los certificados del DNI-e.

Para comenzar, debemos comentar la gran problemática que tiene IIS para la validación del certificado, más en concreto  el estado de la revocación del certificado cliente, este es el quid de la cuestión, ya que la configuración de IIS para pedir certificados es sencillo, pero hacer que admita un DNI-e es más complicado ya que conlleva más operaciones a realizar. El cómo configurar esto se verá como el último paso dentro de este proceso.

1º- El primer paso será la instalación del certificado del servidor, en esta demo crearemos un certificado propio del servidor, este no será reconocido como válido ya que la ruta de certificación no es válida al ser autoafirmado. Este certificado tendrá que ser validado por el cliente como un certificado de confianza.

http://marferdotnet.blogspot.es/img/1.png 

Como muestra la ilustración, en la vista de características del servidor, elegimos la opción de certificados del servidor, esto nos lleva a una pantalla que está vacía y en el menú de la derecha elegiremos la opción de “Crear certificado autofirmado”.

2-º A continuación crearemos el sitio web, que requerirá el certificado. Para ello  utilizamos el botón derecho sobre la carpeta de sitios y aparece una ventana como muestra la imagen siguiente, y en ella la rellenaremos como se muestra en dicha imagen, es aconsejable pulsar el “conectar como” y  configurarlo con un usuario de la máquina que tenga permisos sobre la carpeta en la que se configura la aplicación web.

http://marferdotnet.blogspot.es/img/2.png 

También es posible crearlo sin más en el puerto que no sea de SSL y luego hacer que sean determinados archivos que lo requieran añadiendo un enlace SSL al sitio web.

3-º Una vez realizado este paso configuramos que el sitio requiera el SSL, a través de la vista de características de la página que queremos que la requiera. En esta nueva ventana marcaremos las opciones de requerir SSL y requerir certificado del cliente, con esto aseguramos la identificación mutua entre el navegador cliente y el servidor.

4-º Ahora pasaremos a configurar el acceso, para eso en la opción de autenticación deshabilitamos todas excepto el acceso anónimo y modificamos este acceso para que sea con el usuario que tenía permisos sobre esta carpeta

http://marferdotnet.blogspot.es/img/3.png 

Hasta aquí son los pasos lógicos de una aplicación web. Pero ahora viene la parte más complicada que es la que puede demorar la configuración para todos aquellos que lo hacen por primera vez.

5-º En la vista de características del sitio tenemos la opción de Editor de configuración, es un asistente que nos facilitará mucho el siguiente trabajo.

http://marferdotnet.blogspot.es/img/4.png 

 

6-ºA continuación se accede al menú ManyToOneMappings, en el que se tienen que definir las asociaciones entre certificados y cuenta de usuario. Se deben configurar los parámetros con los siguientes valores:

  • description: dnie.
  • enabled: True.
  • name: dnie. (usuario de la máquina)
  • pasword: contraseña usuario de la maquina especificado en el campo anterior.
  • permissionMode: Allow.
  • userName: dnie. (usuario de la máquina)

http://marferdotnet.blogspot.es/img/5.png 

7-ºPor último se crea una regla para definir qué certificados se aceptarán. En este caso, se aceptan los certificados de autenticación del DNI-e, para ello se tendrán que configurar los parámetros con los siguientes valores:

  • certificateField: Issuer.
  • certificateSubField: OU.
  • compareCaseSensitive: True.
  • matchCriteria: DNIE

http://marferdotnet.blogspot.es/img/6.png 

8-º Ahora nos toca instalar los certificados root y CA del DNI-e, en los almacenes de confianza (tanto el raíz de confianza, como la subordinada)

Ahora tenemos deshabilitar la validación de la revocación del certificado, para eso seguimos los siguientes pasos

9-º en ejecutar hacemos cmd y en la consola escribimos

netsh> http
netsh http> show sslcert

Esto nos mostrará los certificados instalados en el servido. Copiaremos el certificado del sitio para el que estamos configurando la autenticación DNIe a un block de notas, puesto que posteriormente necesitaremos los datos de hash y appid.


10-º Eliminamos el certificado:
netsh http> delete sslcert ipport=0.0.0.0:443

11-º Lo agregamos nuevamente pero deshabilitando la opción de verificación de revocación de certificado cliente:

netsh http>add sslcert ipport=0.0.0.0:443 certhash=3c7a212548dbf8941a3709b4a7bc3db4fe7297ba appid={4dc3e181-e14b-4247-b022-59fc669b0914} certstorename=MY verifyclientcertrevocation=disable

 

y con esto estará listo para funcionar.

Un saludo a todos

Detectar si esta activo JavaScript

Los problemas del diseño web, y la accesibilidad siempre están ocupando un gran volumen de post y de información en la web. Pero aunque hacer una web accesible no es complicado (simplemente hay que seguir unas normas estrictas de diseño e implementación) cuando se quiere hacer además una web que dote de una buena experiencia de usuario la cosa va cambiando.

Hasta ahora hemos visto equipos de desarrollo que realizan dos portales webs, uno accesible y otro no accesible, de tal manera que según se activa o desactiva el javascript la web va redirigiendo a una versión u a otra. Esta solución es para mí bastante mala, ya que esto conlleva el mantenimiento de dos portales en paralelo, con lo que siempre se crean incongruencias.  Aunque tiene la ventaja de que la página funcional es plenamente funcional y la accesible es plenamente accesible.

La otra solución es la de poner etiquetas noscript y dotar de esa funcionalidad a la web…

Yo propongo otra solución consistente en intercambiar controles accesibles y no accesibles dependiendo de si esta activo el javascript. Eso nos presenta el problema de como saber si el navegador tiene activado el javascript.

La primera idea es utilizar el objeto Request.Browser.IsJavaScript, pero esto trae problemas ya que solo dice si el navegado lo admite no si está activo o no (además está en desuso y dará un bonito Warning).

Yo propongo esta otra solución, lo malo que hay que ponerlo encada página que se necesite.

  public static bool JavascriptActivo { get; set; }

        #region Eventos del formulario

        protected void Page_Load(object sender, EventArgs e)

        {

            JavascriptActivo = false;

           

        }

       

        #endregion

 

        [WebMethod]

        public static void TieneJavascript()

        {

            JavascriptActivo = true;

        }

 Y en el aspx:

<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="True">    

    </asp:ScriptManager>

 

<script language="javascript" type="text/javascript">

 

        PageMethods.TieneJavascript();

    </script>

 

Con esto le decimos que queremos utilizar el método de página “TieneJavaScript”, el método de página activa la propiedad estática de que lo utiliza, y por último en cada postback le decimos que la ponga  a false (que no utiliza javascript)

La explicación es sencilla, según el ciclo de vida primero se ejecuta el  onload, y luego se renderiza la página, es entonces cuando se ejecuta el javascript, que está funcionando por Ajax, y por lo tanto no realiza refresco de la página.

Si utiliza javascript se hace la llamada y todo transcurre como se espera, si no, simplemente se actualiza la variable y se muestra la página sin javascript.

un saludo a tod@s

Por qué no usar GridViews en ASP MVC

A veces lo que parece lógico, otras no lo es tanto… me explico un poco mejor. Yo siempre he trabajado con ASP.net y como tal uno de los controles estrellas era el gridview, este control de servidor nos permitía un manejar totalmente los datos que se iban a mostrar, e incluso unas opciones de personalización abismales.

Ahora bien, con la llegada del nuevo ASP.MVC, nos podemos plantear el uso de este control en nuestras nuevas webs, lo cierto es que el control es admitido sin problemas, y funciona, pero solo a nivel de mostrar datos. Es decir, no se puede hacer uso de las opciones avanzadas de manejo de datos.

Lo primero que hay que tener en cuenta, es que en ASP MVC no hay postback, por lo que este control no puede ni paginar, ni ordenar, ni seleccionar, ni de forma automática (cosa que ya era algo no aconsejable, pero se podía) ni de forma personalizada (a través del postback). Esta restricción es clara ya que al no haber postback la vista que se envía no ha recibido nuevos datos, la pantalla no se ha refrescado y seguimos visualizando los mismos datos.

Lo segundo es que no hay viewstate, y por tanto el estado de este control no puede guardarse en el mismo aspx.

Por último decir que la forma que nos presenta (al menos de manera fácil ) es asociar los datos a través de un datasource asociada a la  página, y esto contrasta (por no decir se pega) con cualquier arquitectura de aplicaciones, el tener un select dentro de un aspx , desde mi punto de vista es una aberración que debemos evitar.

Asique ya sabeis, no los useis, y para presentar en forma de tabla lo mejor es crearla con HTML y escupirla al navegador a través de las vistas.

Un saludo a todos

Utilización de pruebas automáticas incluso con Framework2

Todavia me acuerdo de la primera vez que vi los proyectos de test, la verdad, no me gustaron nada. Los veía inútiles y una perdida de tiempo. Esa imprseión duro poco la verdad, en cuanto empezamos a desarrollar cosas complejas y las probábamos sin tener que lanzar toda la aplicación y ese código era reutilizado en la aplición propiamente dicha… mi primera impresión cambió de forma radica.

Para los que todavía no lo sepan, (seguro que son pocos…) un proyecto de test es tipo de solución que aparece en Visual Studio 2008 (y que se reafirman en 2010), que permite crear pruebas automáticas del código generado, estas pruebas son una buena descripción del código que estamos generando ya que el código hace exactamente lo que dicen las pruebas.

Se debe tener  un 80% del código probado por estas pruebas, aunque en la realidad debido a la carga de código en los proyectos de presentación se reduce a un 60% o a veces menos..

Pero en la realidad un proyecto de test, es la forma más segura de garantizar una calidad del software acepable, es decir, por lo menos podemos asegurar que el código hace lo que se pretende, y además podemos ver en los tiempos en que lo hace… por  lo tanto mejorar las partes para que sean más optimas.

El problema que yo me he encontrado, es una aplicación en framework 2.0. y una ampliación de este proyecto. Lanzar toda la aplicación es muy lento, y compilarla  tarda unos 4 minutos de reloj (en informática ya sabemos que ese tiempo es imposible de aguantar)

Asique  me he propuesto añadir pruebas automáticas (que no están en framework 2…) y para ello utilizo visual Studio 2010,  añadiendo la dll del proyecto en framework 2 que estoy haciendo con Visual Studio 2005. Y he aquí la mejor de las sorpresas… Visual Studio me permite depurar dentro de las clases que están incluidas en la dll que he añadido. Todo un gran paso para el proceso de desarrollo, y sin molestar a mis compañeros  que tendrían que haberse cambiado a visual studio 2010.

Espero que el post haya sido de interés o de ayuda para todos aquellos que quieran realizar pruebas unitarias y que no hayan podido por el entorno de desarrollo.

 

Un saludo a todos

Ventajas del uso de Azure

Hola a todos, hace mas de un año que Microsoft presentó Windows Azure, su plataforma de cloud computing, orientado a llevar a la nube las aplicaciones, o al menos una gran parte de ellas.

En principio parecia que seria un hosting avanzado, pero con el tiempo se ha demostrado que es algo mas que todo eso, y por ello en este post, ire desgranando algunas de las ventajas que esta plataforma ofrece.

Bajo coste: Esta plataforma nos permite un gran ahoro al externalizar el CPD, será microsoft quien se encarga de mantenimiento de los servidores, de las actualizaciones de los servidores de bases de datos y todo a un modico precio (ya que se rentabiliza segun el uso que se haga)


Por supuesto, es muy importante que la compañía tenga en este punto el máximo número posible de clientes, vendedores, desarrolladores y usuarios para poder migrar, desarrollar y ejecutar las aplicaciones en su Nube, de esta manera, al pagar por uso... conseguimos el mayor ahorre de coste, es decir si tenemos muchos clientes y el uso es alto.. pues pagamos más, y si se utiliza poco.. pues se paga poco.

Esta es la razón, por la que cada vez más empresas estan decidiendo el migrar sus sistemas a Azure.
En palabras de Noël y Steve Ballmer:
“Normalmente, empezamos las discusiones con los clientes empresariales sobre aplicaciones no críticas. Hacemos que prueben Windows Azure con rapidez y una vez que se den cuenta de la sencillez que tiene la migración de las aplicaciones, luego se dan cuenta que pueden mover todas las aplicaciones e la nube”

“A causa de que es tan fácil trasladar las aplicaciones desde un centro de datos local a la Nube lo que empezamos a ver son los escenarios donde para una aplicación un cliente ya tendrá una pista sobre la demanda en algún momento.

“Las aplicaciones pueden configurarse para que manejen picos en la demanda, desde que la plataforma pedirá automáticamente los recursos adicionales y aprovechará la potencia informática que ofrecemos para garantizar que el pico en el tráfico se gestiona. Las aplicaciones pueden hacer un balance dinámico en la carga y usar la Nube para una capacidad adicional siempre que haga falta.

“Y esto es muy potente porque por nuestro lado estamos funcionando a tal escala que podemos ofrecer enormes cantidades de potencia a un coste muy competitivo.

“Admitimos muchos frameworks, PHP, Ruby, etc. Las aplicaciones creadas en .NET son fáciles de migrar. Si están creadas en .NET desde el principio la migración de las aplicaciones se realiza en cuestión de días o incluso horas.

“Pero también hay soporte para PHP, hay muchas aplicaciones que se ejecutan en Windows Azure y han sido escritas en PHP, y muestran nuestro compromiso por la interoperabilidad.

“Desde la perspectiva de un desarrollador, cualquier cosa que se ejecuta en tu entorno Visual Studio es admitida en Windows Azure.

“Por ejemplo si tienes una aplicación Java es muy fácil tener el mismo código Java ejecutado en la Nube. Tratamos de hacerlo muy fácil y transparente para las personas que utilizan nuestros centros de datos y la potencia de la computación que tenemos”.

“Las ventajas principales de Windows Azure están alrededor de la capacidad de administración y la sencillez de implementación, y el coste es obviamente una gran ventaja así como la integración con otros servicios de la empresa”.

“La verdadera ventaja al final es sobre tener administrados enormes cantidades de servidores con un uso muy eficiente de la potencia. El objetivo general es proporcionar la gran cantidad de potencia de computación a un precio muy asequible.

“En el caso en que tienes una carga pico, para la enorme carga de trabajo que viene de manera previsible o imprevisible, la Nube y Windows Azure te ayudan a gestionar aquellos picos porque descargas la capacidad de computación a la Nube.

“En los casos en que empiezas un negocio, o una aplicación, y realmente no sabes si será o no exitosa. Normalmente vemos muchos emprendedores que están muy interesados porque no pueden empezar sin comprar un enorme centro de datos.

“Ellos pueden poner simplemente sus aplicaciones en la Nube y si será exitosa pueden pagar por la potencia de computación que necesitan, y si no es exitosa, entonces no han desperdiciado mucho dinero pagando por centros de datos que al final no son usados.

“Todos los escenarios en las que la demanda no es estable y predecible son unos increíbles escenarios para la computación en la Nube.”

Espero que os haya sido ilustrativo de lo que es esta plataforma

 

Un saludo a todos

Ventajas del uso de Azure

Hola a todos, hace mas de un año que Microsoft presentó Windows Azure, su plataforma de cloud computing, orientado a llevar a la nube las aplicaciones, o al menos una gran parte de ellas.

En principio parecia que seria un hosting avanzado, pero con el tiempo se ha demostrado que es algo mas que todo eso, y por ello en este post, ire desgranando algunas de las ventajas que esta plataforma ofrece.

Bajo coste: Esta plataforma nos permite un gran ahoro al externalizar el CPD, será microsoft quien se encarga de mantenimiento de los servidores, de las actualizaciones de los servidores de bases de datos y todo a un modico precio (ya que se rentabiliza segun el uso que se haga)


Por supuesto, es muy importante que la compañía tenga en este punto el máximo número posible de clientes, vendedores, desarrolladores y usuarios para poder migrar, desarrollar y ejecutar las aplicaciones en su Nube, de esta manera, al pagar por uso... conseguimos el mayor ahorre de coste, es decir si tenemos muchos clientes y el uso es alto.. pues pagamos más, y si se utiliza poco.. pues se paga poco.

Esta es la razón, por la que cada vez más empresas estan decidiendo el migrar sus sistemas a Azure.
En palabras de Noël y Steve Ballmer:
“Normalmente, empezamos las discusiones con los clientes empresariales sobre aplicaciones no críticas. Hacemos que prueben Windows Azure con rapidez y una vez que se den cuenta de la sencillez que tiene la migración de las aplicaciones, luego se dan cuenta que pueden mover todas las aplicaciones e la nube”

“A causa de que es tan fácil trasladar las aplicaciones desde un centro de datos local a la Nube lo que empezamos a ver son los escenarios donde para una aplicación un cliente ya tendrá una pista sobre la demanda en algún momento.

“Las aplicaciones pueden configurarse para que manejen picos en la demanda, desde que la plataforma pedirá automáticamente los recursos adicionales y aprovechará la potencia informática que ofrecemos para garantizar que el pico en el tráfico se gestiona. Las aplicaciones pueden hacer un balance dinámico en la carga y usar la Nube para una capacidad adicional siempre que haga falta.

“Y esto es muy potente porque por nuestro lado estamos funcionando a tal escala que podemos ofrecer enormes cantidades de potencia a un coste muy competitivo.

“Admitimos muchos frameworks, PHP, Ruby, etc. Las aplicaciones creadas en .NET son fáciles de migrar. Si están creadas en .NET desde el principio la migración de las aplicaciones se realiza en cuestión de días o incluso horas.

“Pero también hay soporte para PHP, hay muchas aplicaciones que se ejecutan en Windows Azure y han sido escritas en PHP, y muestran nuestro compromiso por la interoperabilidad.

“Desde la perspectiva de un desarrollador, cualquier cosa que se ejecuta en tu entorno Visual Studio es admitida en Windows Azure.

“Por ejemplo si tienes una aplicación Java es muy fácil tener el mismo código Java ejecutado en la Nube. Tratamos de hacerlo muy fácil y transparente para las personas que utilizan nuestros centros de datos y la potencia de la computación que tenemos”.

“Las ventajas principales de Windows Azure están alrededor de la capacidad de administración y la sencillez de implementación, y el coste es obviamente una gran ventaja así como la integración con otros servicios de la empresa”.

“La verdadera ventaja al final es sobre tener administrados enormes cantidades de servidores con un uso muy eficiente de la potencia. El objetivo general es proporcionar la gran cantidad de potencia de computación a un precio muy asequible.

“En el caso en que tienes una carga pico, para la enorme carga de trabajo que viene de manera previsible o imprevisible, la Nube y Windows Azure te ayudan a gestionar aquellos picos porque descargas la capacidad de computación a la Nube.

“En los casos en que empiezas un negocio, o una aplicación, y realmente no sabes si será o no exitosa. Normalmente vemos muchos emprendedores que están muy interesados porque no pueden empezar sin comprar un enorme centro de datos.

“Ellos pueden poner simplemente sus aplicaciones en la Nube y si será exitosa pueden pagar por la potencia de computación que necesitan, y si no es exitosa, entonces no han desperdiciado mucho dinero pagando por centros de datos que al final no son usados.

“Todos los escenarios en las que la demanda no es estable y predecible son unos increíbles escenarios para la computación en la Nube.”

Espero que os haya sido ilustrativo de lo que es esta plataforma

 

Un saludo a todos

Generación de codigo II

Hola a todos:

Lo prometido es deuda y más cuando lo que se promete queda por escrito en un blog…

Lo cierto es que la debería disculparme por la tardanza, pero ha sido por una gran razón y es que no todos los años uno es padre. Si, Alba nació el día 7 de enero siendo el mejor regalo de reyes que se puede tener, y como es obvio nos llenó de felicidad.

Volviendo al tema del día… hoy hablaremos de la generación de código a través de la herramienta wsdl, que nos permitirá la definición de interfaces, para servicios web que cumplan totalmente con la definición del mismo.

Antes de empezar vamos a aclarar varios conceptos como:

Wsdl: es el contrato, es un documento en formato xml, que da la especificación del serbio, de los prototipos de los métodos y de los datos que se van a utilizar.

.Net, nos dá una potente herramienta, que además se llama igual que este tipo de documentos, que nos facilita la generación de interfaces para poder implementar servicios web interoperables.

 

Lo primero que haremos es irnos a la carpeta de herramientas de visual studio, y allí en la consola de comandos escribiremos un comando con esta sintaxis.

wsdl [options] {URL | path}

 

Donde las opciones son:

URL :Dirección URL de un archivo de contrato WSDL (.wsdl), de un archivo de esquemas XSD (.xsd) o de un documento de descubrimiento (.disco). Hay que tener en cuenta que no se puede especificar una dirección URL de un documento de descubrimiento (.discomap).

Opción

Descripción

/appsettingurlkey: key

O bien

/urlkey: key

Especifica la clave de configuración que se utiliza para leer el valor predeterminado de la propiedad de la dirección URL cuando se genera código. Cuando se utiliza la opción /parameters, este valor es el elemento <appSettingUrlKey> y contiene una cadena.

/appsettingbaseurl: dirección url base

O bien

/baseurl: dirección url base

Especifica la dirección URL base que se utiliza al calcular el fragmento de dirección URL. Esta herramienta calcula el fragmento de dirección URL convirtiendo la dirección URL relativa desde el argumento URL base en la dirección URL que contiene el documento WSDL. Se debe especificar la opción /appsettingurlkey con esta opción. Cuando se utiliza la opción /parameters, este valor es el elemento <appSettingBaseUrl> y contiene una cadena.

/d[omain]:dominio

Especifica el nombre del dominio que se utiliza para conectarse a un servidor que requiera autenticación. Cuando se utiliza la opción /parameters, este valor es el elemento <domain> y contiene una cadena.

/l[anguage]:lenguaje

Especifica el lenguaje que se utiliza para la clase de proxy generada. Puede especificar CS (C#; valor predeterminado), VB (Visual Basic), JS (JScript) o VJS (Visual J#) como argumento de lenguaje. También se puede especificar el nombre completo de la clase que implementa System.CodeDom.Compiler.CodeDomProvider (Clase). Cuando se utiliza la opción /parameters, este valor es el elemento <language> y contiene una cadena.

/n[amespace]:espacio de nombres

Especifica el espacio de nombres del proxy o plantilla generados. La opción predeterminada es el espacio de nombres global. Cuando se utiliza la opción /parameters, este valor es el elemento <namespace> y contiene una cadena. Este elemento debe estar en el archivo de parámetros.

/nologo

Suprime la presentación de la portada de inicio de Microsoft. Cuando se utiliza la opción /parameters, este valor es el elemento <nologo> y contiene true o false.

/order

Genera identificadores de orden explícitos en miembros de partícula.

/o[ut]:nombre de archivo o nombre de directorio

Especifica el archivo (o directorio) en el que se guarda el código proxy generado. También puede especificar un directorio en el que se podrá crear este archivo. La herramienta deriva el nombre de archivo predeterminado del nombre de servicio Web XML. La herramienta guarda los conjuntos de datos generados en varios archivos. Cuando se utiliza la opción /parameters, este valor es el elemento <out> y contiene una cadena.

/parameters

Se leen las opciones de línea de comandos del archivo xml especificado. Utilice esta opción para pasar a la herramienta Wsdl.exe un gran número de opciones de una vez. La forma abreviada es '/par:'. Los elementos de opción se encuentran dentro de un elemento <wsdlParameters xmlns="http://microsoft.com/webReference/"> Para obtener más detalles al respecto, vea la sección Comentarios.

/parsableerrors

Muestra los errores en un formato similar al formato de los informes de errores que utilizan los compiladores de lenguajes. Cuando se utiliza la opción /parameters, este valor es el elemento <parsableerrors> y es true o false.

/p[assword]:contraseña

Especifica la contraseña que se utiliza para conectarse a un servidor que requiera autenticación. Cuando se utiliza la opción /parameters, este valor es el elemento <password> y contiene una cadena.

/protocol: protocolo

Especifica el protocolo que se implementa. Se puede especificar SOAP (el valor predeterminado), HttpGet, HttpPost o el protocolo personalizado que se especifique en el archivo de configuración. Cuando se utiliza la opción /parameters, este valor es el elemento <protocol> y contiene una cadena.

/proxy: dirección URL

Especifica la dirección URL del servidor proxy utilizada para las solicitudes HTTP. La opción predeterminada es que se utilice la configuración del sistema proxy. Cuando se utiliza la opción /parameters, este valor es el elemento <proxy> y contiene una cadena.

/proxydomain: dominio

O bien

/pd: dominio

Especifica el dominio que se utiliza para conectarse a un servidor proxy que requiera autenticación. Cuando se utiliza la opción /parameters, este valor es el elemento <proxydomain> y contiene una cadena.

/proxypassword: password

O bien

/pp: password

Especifica la contraseña que se utiliza para conectarse a un servidor proxy que requiera autenticación. Cuando se utiliza la opción /parameters, este valor es el elemento <proxypassword> y contiene una cadena.

/proxyusername: username

O bien

/pu: username

Especifica el nombre de usuario que se utiliza para conectarse a un servidor proxy que requiera autenticación. Cuando se utiliza la opción /parameters, este valor es el elemento <proxyusername> y contiene una cadena.

/server

Genera una clase abstracta para un servicio Web XML basada en contratos. El valor predeterminado es que se generen clases de proxy cliente. Cuando se utiliza la opción /parameters, este valor es un elemento <style> que contiene el valor "server".

/serverInterface

Genera interfaces para la implementación en el servidor de un servicio Web ASP.NET. Se genera una interfaz para cada enlace en los documentos WSDL. WSDL por sí solo implementa el contrato WSDL (las clases que implementan la interfaz no deben incluir lo siguiente en los métodos de clase: atributos de servicio Web o atributos de serialización que cambien el contrato WSDL). La forma abreviada es '/si'. Cuando se utiliza la opción /parameters, este valor es un elemento <style> que contiene el valor "servicerInterface".

/sharetypes

Activa la característica de uso compartido de tipos. Esta característica permite crear un archivo de código con una definición de tipo única para tipos idénticos que comparten distintos servicios (el espacio de nombres, el nombre y la firma de conexión deben ser idénticos). Haga referencia a los servicios con direcciones URL "http://" como parámetros de línea de comandos o cree un documento discomap para los archivos locales. Cuando se utiliza la opción /parameters, este valor es el elemento <sharetypes> y es true o false.

/u[sername]:nombre de usuario

Especifica el nombre de usuario que se utiliza para conectarse a un servidor que requiera autenticación. Cuando se utiliza la opción /parameters, este valor es el elemento <username> y contiene una cadena.

/?

Muestra la sintaxis de comandos y opciones para la herramienta.

*Tabla obtenida de la web de Microsoft msdn (http://msdn.microsoft.com/es-es/library/7h3ystb6(v=vs.80).aspx)

Ejemplo:

wsdl /language:VB /out:myProxyClass.vb http://hostServer/WebserviceRoot/WebServiceName.asmx?WSDL

 

Espero que sea de utilidad

 

 

Generación de clases con xsd

Hola a todos:

Trabajando con servicios web, que se comuniquen de forma satisfactoria con Servicios Java, o con aplicaciones java, me he encontrado con algunas cosas que me gustaria contar aquí.

La primera es la generación de clases de manera automática con los comandos xsd.exe y wsdl.exe.

Los nombre, son muy apropiados, ya que como todos sabreis un archivo xsd, es un archivo xml que define un conjunto de clases, y con esta herramienta podremos pasar de ese esquema a un conjunto de clases sin tener que generarlas a mano. De igual manera funciona wsdl, pero sus opciones las definiremos en el proximo post.

Lo primero que haremos es irnos a la carpeta de herramientas de visual studio, y alli en la consola de comandos escribiremos un comando con esta sintaxsis.

xsd file.xsd {/classes | /dataset} [/element:element]

             [/language:language] [/namespace:namespace]

             [/outputdir:directory] [URI:uri]

Conde:

/classes: Genera clases que corresponden al esquema especificado. Para leer datos XML del objeto, se debe utilizar el método

/dataset: Genera una clase derivada de DataSet que corresponde al esquema especificado.

/element: Especifica el elemento del esquema para el que se genera código. De forma predeterminada se escriben todos los elementos. Este argumento se puede especificar varias veces

/language: Definiremos si queremos que sea en VB o C#, aquí recomiendo encarecidamente que sea con c# porque a veces el wsdl que se genera a partir de una interfaz en VB y otra en C# no es el mismo, y pude dar problemas en caso de interoperatividad

/namespace: Especifica el espacio de nombres del motor en tiempo de ejecución para los tipos generados. El espacio de nombres predeterminado es Schemas

/outputdir: Especifica el directorio de resultados donde colocar los archivos. El valor predeterminado es el directorio actual.

URI:uri: Especifica el identificador URI de los elementos del esquema para el que se genera código. Este identificador URI, si existe, se aplica a todos los elementos especificados con la opción /element.

Yo  recomiendo ussar la opcion /clasess (/c), languaje (/l) y outputdir (/o). con esto definimos un esquema completo, tambien es bueno utilizar el namespace .

Ejemplo:

xsd C:\data.xsd /classes /language:CS

 

Espero que sea de utilidad y en el proximo post pondremos las opciones de wsdl

tiempos de acceso a BBDD

Hola a todos

Otra vez retomo la escritura en el blog, esta vez con un estudio que he podido realizar y que me parece interesante. Los tiempos de acceso.

 

He montado una aplicación web que lo que hace es realizar una misma consulta por distintas tecnologias y presentarla de la misma manera, estas tecnologias son:

ADO conectado, Datasets Tipados, EntityFramework y LinQ

 

¿Los resultados? al final de este post.

 

Lo primero que voy a comentar es el entorno.

He montado un SQL Server 2008 con Adventure Works como Base de datos.

Un entorno Visual Studio 2010 para lanzar la aplicación y mostrar los resultados.

Y el Sql profiler para capturar los tiempos de acceso, los tiempo de acceso varian porque la maquina siempre realiza operaciones y por lo tanto no siempre las consultas tardan lo mismo.

 

Despues de montar la aplicación... vemos que el mas rápido es

ADO conectado, luego los otros tres se llevan mas o menos poco, el segundo más rápido es linQ y seguido de cerca de los datasets tipados (en este punto haciendo un poco de trampa ya que lo que lanzamos es un procedimiento salmacenado).

El mas lento es el entity framework.

 

Y ahora las coclusiones:

Es normal que el mas rápido sea el ADO conectado ya que es un cursor sobre los datos

Que el segundo más rápido sea LinQ se debe a que una vez generada la consulta se lanza sobre la base de datos de manera conectada... pero de forma transparente al usuario.

Que el tercero sea datasets tipados, es consecuencia del uso de procedimientos almacenados, ya que estos se guardan optimizados y junto con los planes de ejeucción y eso le da una gran velocidad.

Por ultimo el entity framework... ¿Será por eso por lo que Microsoft quiere centrarse en mejorar esta tecnologia? lo ciento es que aunque aporta una gran abstracción y es facil de usar, aunque nos permite manejar el modelo de datos de forma optima, es el mas lento de todos.

 

Un saludo a todos

 

 

visual WebPart en Sharepoint

Sigo entudiando y trabajando con la beta de este genial producto y de verdad que lo han mejorado... no solo en presencia, si no en funcionalidad y tambien en posibilidad de extension.

Uno de los mejores inventos era el proyecto que codeproyect llamo smartPart que era la posibilidad de crear webpart de forma visual a traves de controles de usuario (ascx). Con Visual Studio 2010, esta funcionalidad viene ya incorporada y mejoradas.

antes cuando instalabas el proyecto, te dejaba unas clases que tenias que cambiar el namespace y hacer que compilaran con el nuevo namespace, luego una vez compilado te creaba los archivos xml de despliegue y el webpart... osea que tenias que lidiar con una serie de tareas y eso que ya este proyecto te facilitaba mucho el trabajo.

ahora con visual Studio 2010 tenemos la ventaja de elegir el proyecto Visual Webpart y en el asistente diremos para que sitio es, las clases ya vienen compiladas en una dll (no hay que tocarlas) el archivo ascx se programa como siempre y simplemente tenemos que dar a publish para publicar este nuevo webpart y ademas la feature estara activada...

Una pasada de verdad, probarlo

 

un saludo

Error en beta de sharepoint 2010

a veces te quedas asombrado cuando estas trabajando con una aplicación, todo funciona correctamente, y de repente haces algo que estas acostumbrado de hacer y falla.

el problema me surgio ayer, cuando al crear en moss 2010 una plantilla de una lista custom a la que habia añadido un campo de texto, luego me fui a crear una lista con esta nueva plantilla... y mi sorpresa fue que el campo creado no lo habia heredado.

En ese momento me quede helado porque no habia razón, esa forma de crear plantillas era la correcta, no habia mas formas... y de repente vimos el porque, a un compañero haciendo exactamente lo mismo si le habia funcionado pero el no tenida instalado Silverligth.

Asique ya sabemos que en la Beta de Sharepoint 2010 tenemos problemas con el silverligth, yo espero que en la version definitiva este error sea subsanado, ya que me parece de bulto.

 

un saludo a todos

Charla Introduccion Dispositivos moviles

Hablando con la gente del club, he visto que habia un tema que parece que a la gente le interesa. El tema de los dispositivos moviles, como programarlos, con Windws 6 y con compac framework.

 

Asique el proximo lunes día 30 a las 19:00 vamos a tener una charla en la Facultad de Informática de la UPSAM sobre introducción a la programación mobile, alli veremos como desarrollar aplicaciones de forma sencilla con telefonos moviles, con .net y windows mobile.

 

Un saludo y no falteis!!

vision artificial en .net

El otro dia me comento un amigo que queria algo para trabajar con vision artificial y .net, la cosa es que hay un monton programas y apis para c++, pero para c# no encontraba demasiado.

me hablo de una herramienta (OpenCV) pero esta era para c++, y que queria algo parecido por lo facil que le resultaba o que le parecia que era, para mi sorpresa, cuando estube investigando sobre este tema me encontre que hay una version de este software para .net que se llama openCVdotNet.
 
Aqui os dejo mas información sobre esta herrmeinta
 
http://code.google.com/p/opencvdotnet/
 
un saludo a todos

Un error raro en MOSS

Hola a todos, desde que vine de la luna de miel parece que estoy muy activo actualizando el blog y poniendo post.

La cosa es que el otro dia me encontre con un error un tanto raro, la cosa es que aparentemente todo va bien, pero en el visor de eventos de la maquina aparece un error vinculado al infopath.

Para reproducirlo, simplemente envia un formulario de infopath y mira el visor de eventos en la parte de aplicaciones... y ahi esta un error como este

 

Error Description: InfoPath Forms Services has detected a mismatch between the user's data in the browser and on the server. This may indicate the SESSION_STATE_PASCAL_CASED is not configured properly on a multiple front end farm or that a malicious user is trying to tamper with client data. Error Description: InfoPath Forms Services has detected a mismatch between the user's data in the browser and on the server. This may indicate the SESSION_STATE_PASCAL_CASED is not configured properly on a multiple front end farm or that a malicious user is trying to tamper with client data.

 

La cosa es que al instalar un sp en moss, puede pasar que haya un desajuste entre las plantillas y los formularios, por eso lo primero que debes hacer el limpiar la cache, e intentar de nuevo, como esto dudo que funcione te dejo el otro paso que es el que debes ejecutar para que todo vaya bien

 

ve al inicio, ejecuta el cmd

y en linea de comando pon esto

 

 stsadm -o reconvertallformtemplates

 

con esto estara arreglado el problema

 

Un saludo a todos

windows 7 y Oracle

Hoy voy hablar de una de las cosas mas raras (aunque si sabes como funcionan algunas cosillas muy logica)... Si uno mira que version de Oracle hay hasta la fecha y se da cuenta de que no hay ninguna... luego uno empieza a pensar en el nucleo de windows 7

que es una evolucion de windows vista (comparten mucha parte del nucleo, aunque w7 esta muy muy mejorado...) y empieza a probar algunas cosillas

 

Instalarlo a pelo la version 10gi con un parche (10.0.4) o la version 11... pero da un erro de verificación del sistema operativo...

 

Luego se me ocurrio marcar el check de verificación (como si fuese correcto y lo hubiera hecho bien) y BINGO!!! todo funciona correctamente!!

 

El porque es claro, la verificación es a nivel de instalador, y solo valida la version del windows, si te lo saltas como el nucleo de Vista y windows 7 son parecidos y los cambios que afectarian al oracle son triviales para su funcionamiento... todo funciona correctamente.

 

Un saludo y espero que os sirva en caso de que os encotreis en con este problema

WebCast de LinQ

Hola a todos!!

 

Hoy estoy muy contento, si estoy muy contento, porque he estado en el TTT con un monton de amigos de microsoft, MVPs y una gente muy muy especial que son de los dotnetclubs (clubs de estudiantes apasionados por la tecnologia .net)

 

De estas cosas salen cosas muy interesantes, se aprende un monton y uno sale muy contento e ilusionado con estas tecnologias nuevas.

 

Esta vez, he conocido a Jesús Bosch, un amigo de los clubes y que por fin despues de hablar muchas veces nos hemos conocido personalmente. Pues bien, Jesus me propuso dar un webcast de LinQ y titulamos el evento como LinQ Vs ADO, y en este evento mostrare como usar LinQ que avances nos da, y que ofrece con respecto al ADO.net que utilizabamos hasta ahora.

 

Yo os invito a verlo, ademas porque asi os conocere a la mayoria de vosotros que leeis este blog.

Sera el dia 9 de noviembre a las 7

 

Un saludo a tod@s

cuarto paso: webpart o smartpart

El uso de smartpart como si fueran webparts es bastante común, porque mermite utilizar las técnicas de diseño y no renderizar el código en tiempo de ejecución.

Es decir, si queremos crear un webpart, y diseñar nosotros sus elementos… una forma secilla es utilizar los smartPart, que son unas plantillas que te puedes descargar de codeproject en con las que te crea una structura propia de carpetas y código, a partir de aquí, create un control web de usuario (un ascx) y prográmalo como si tal fuese, al compilarlo te crea unos archivos de despliegue y un nuevo archivo dwp que es otro xml con un formato  especial que permite especificar los elementos de este smartpart.

Una vez desplegado este smartpart se utilizará como un webpart, pero el desarrollo es mas agil

Archivo dwp

version="1.0" encoding="utf-8"?>

<WebPart xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.microsoft.com/WebPart/v2">

  <Title>Webpart de visualización del imagen y texto</Title>

  <Description>Webpart de visualización del imagen y texto</Description>

  <UserControl xmlns="SmartPart">~/_controltemplates/miapp/ImagenTexto.ascx</UserControl>

 

  <FrameType>Default</FrameType> 

  <IsIncluded>true</IsIncluded>

  <PartOrder>0</PartOrder>

  <FrameState>Normal</FrameState>

  <AllowRemove>true</AllowRemove>

  <AllowZoneChange>true</AllowZoneChange>

  <AllowMinimize>true</AllowMinimize>

  <AllowConnect>true</AllowConnect>

  <AllowEdit>true</AllowEdit>

  <AllowHide>true</AllowHide>

  <IsVisible>true</IsVisible>

  <HelpMode>Modeless</HelpMode>

  <Dir>Default</Dir>

  <PartImageSmall />

  <MissingAssembly>Cannot import this Web Part.</MissingAssembly>

  <PartImageLarge />

  <IsIncludedFilter />

  <Assembly>miapp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6e15695f6e48dbe2</Assembly>

  <TypeName>GBP.Innovacion.Common.Portal.WebParts.SmartPart.SmartPart</TypeName>

  <ShowUserControlList xmlns="SmartPart">false</ShowUserControlList>

</WebPart>

 

Feature.xml

<Feature

  Id="{BB5DE3BE-7A99-4195-B889-C19500516669}"

  Title="Webpart del portal de innovación"

  Description="Webpart del portal de innovación"

  Scope="Site"

 

  xmlns="http://schemas.microsoft.com/sharepoint/">

 

  <ElementManifests>

    <ElementManifest Location="ProvisionedFiles.xml"/>

    <ElementFile Location="wpImagenTexto.dwp" />

    <ElementFile Location="wpVisorXSL.webpart" />

    <ElementFile Location="wpZoneTabs.dwp" />

  </ElementManifests>

 

</Feature>

 

Install.bat

ECHO Copying DLL ...

XCOPY  /Y ..\..\..\BIN\*.dll C:\Inetpub\wwwroot\wss\VirtualDirectories\80\BIN\

 

ECHO Copying ASCX files ...

XCOPY  /Y ..\..\..\Code\Webparts\WPImagenTexto\*.ascx "%CommonProgramFiles%\Microsoft Shared\web server extensions\12\TEMPLATE\CONTROLTEMPLATES\Innovacion\"

XCOPY  /Y ..\..\..\Code\Webparts\WPContactosInnovacion\*.ascx "%CommonProgramFiles%\Microsoft Shared\web server extensions\12\TEMPLATE\CONTROLTEMPLATES\Innovacion\"

XCOPY  /Y ..\..\..\Code\Webparts\WPGestionAlias\*.ascx "%CommonProgramFiles%\Microsoft Shared\web server extensions\12\TEMPLATE\CONTROLTEMPLATES\Innovacion\"

 

 

ECHO Copying ASCX files ...

XCOPY  /Y ..\..\..\Code\Webparts\WPImagenTexto\ImagenTextoToolParts\*.ascx "%CommonProgramFiles%\Microsoft Shared\web server extensions\12\TEMPLATE\CONTROLTEMPLATES\Innovacion\ImagenTextoToolParts\"

 

ECHO Copying ASPX files ...

XCOPY  /Y ..\..\..\Code\Webparts\WPImagenTexto\ImagenTextoToolParts\*.aspx "%CommonProgramFiles%\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\Innovacion\"

XCOPY  /Y ..\..\..\Code\Webparts\WPContactosInnovacion\Popup\*.aspx "%CommonProgramFiles%\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\Innovacion\"

 

ECHO Copying ASCX files ...

XCOPY  /Y ..\..\..\Properties\*.resx  C:\Inetpub\wwwroot\wss\VirtualDirectories\80\App_GlobalResources

 

pause

Un saludo a todos

MOSS: Despliegue de la master y layout

De todo lo que aprendi en este proyecto lo que mas me gusto fue lo de los archivos de despliegue.

Si porque te creas un batch medianamente sencillo y con unos archivos xml la aplicación queda instalada de forma rápida y sencilla. Pero antes de llegar a este punto… vamos a ver como se instala lo que hemos hecho hasta este momento.

Creamos un dos archivos xml y un .bat

El primero lo llamaremos feature.xml y contendrá lo siguiente:

                <?xml version="1.0" encoding="utf-8"?>

<Feature  Id="{1ADF1A07-4F4C-4f6c-A1CE-D59DF275E681}"

          Title="InnovacionCommonLayout"

          Description="Layouts comunes del Portal de Innovación."

          Version="1.0.0.0"

          Hidden="FALSE"

          Scope="Site"

          DefaultResourceFile="core"         

          xmlns="http://schemas.microsoft.com/sharepoint/"

          SolutionId="{23F5AF49-D7EC-48b9-8184-0054FD3DAA73}">

  <ElementManifests>

    <ElementManifest Location="ProvisionedFiles.xml"/>

  </ElementManifests>

</Feature>

El segundo se llamara ProvisionedFiles.xml y tendrá el siguiente contenido

                <!-- _lcid="1033" _version="12.0.6211" _dal="1" -->

<!-- _LocalBinding -->

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

  <!-- Espacio Home -->

  <Module Name="InnovacionHomeLayout" Url="_catalogs/masterpage" Path="PageLayouts" RootWebOnly="TRUE">

    <File Url="InnovacionHomeLayout.aspx" Type="GhostableInLibrary">

      <Property Name="Title" Value="Layout para la home" />

      <Property Name="MasterPageDescription" Value="Layout para la home" />

      <Property Name="ContentType" Value="$Resources:cmscore,contenttype_pagelayout_name;" />

      <Property Name="PublishingPreviewImage" Value="~SiteCollection/_catalogs/masterpage/$Resources:core,Culture;/Preview Images/BlankWebPartPage.png, ~SiteCollection/_catalogs/masterpage/$Resources:core,Culture;/Preview Images/BlankWebPartPage.png" />

      <Property Name="PublishingAssociatedContentType" Value=";#$Resources:cmscore,contenttype_welcomepage_name;;#0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF390064DEA0F50FC8C147B0B6EA0636C4A7D4;#" />   

    </File>

    <File Url="InnovacionBlankFormLayout.aspx" Type="GhostableInLibrary"/>

  </Module>

 

</Elements>

 

Por ultmo el batch que se llamara instalarHome.bat

<!-- _lcid="1033" _version="12.0.6211" _dal="1" -->

<!-- _LocalBinding -->

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

  <!-- Espacio Home -->

  <Module Name="InnovacionHomeLayout" Url="_catalogs/masterpage" Path="PageLayouts" RootWebOnly="TRUE">

    <File Url="InnovacionHomeLayout.aspx" Type="GhostableInLibrary">

      <Property Name="Title" Value="Layout para la home" />

      <Property Name="MasterPageDescription" Value="Layout para la home" />

      <Property Name="ContentType" Value="$Resources:cmscore,contenttype_pagelayout_name;" />

      <Property Name="PublishingPreviewImage" Value="~SiteCollection/_catalogs/masterpage/$Resources:core,Culture;/Preview Images/BlankWebPartPage.png, ~SiteCollection/_catalogs/masterpage/$Resources:core,Culture;/Preview Images/BlankWebPartPage.png" />

      <Property Name="PublishingAssociatedContentType" Value=";#$Resources:cmscore,contenttype_welcomepage_name;;#0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF390064DEA0F50FC8C147B0B6EA0636C4A7D4;#" />   

    </File>

    <File Url="InnovacionBlankFormLayout.aspx" Type="GhostableInLibrary"/>

  </Module>

 

</Elements>

 

En futuros post iremos poniendo como se puede desplegar un sitio entero con todos los webparts ya incluidos a través de una feature y de un batch

 

Un saludo a todos

segundo paso. MasterPage y Layouts

Una vez que tenemos una colección de sitios, y que tenemos nuestro sitio raíz podemos ver dos cosas:

El sitio es feo: tema de este post

No cumple con todo lo que queremos: siguiente post

En este post trataremos de dar un aspecto bonito a nuestra web, para eso cambiaremos la masterpage.

El concepto de masterpage es idéntico que en una web aspx, pero con una diferencia clara, y es que aunque se pueda adjuntar un archivo de código a esta master, se debe y es norma de buenas prácticas, que la master solo tenga el aspecto.

Lo complicado viene ahora… En MOSS hay una serie de content template que deben estar de forma obligatoria, y otros que serán el contenido que serán optativos.

En este post mostramos un ejemplo de masterpage que es sencilla y casi mínima, y que luego se puede ampliar con otros contentplate.

Una vez que tenemos la master, hay que darla un formato, y en este punto entra el concepto de Layout, que es la presentación que tendrá la pagina, esta da formato y  redefine algunos content que fueron declarados en la master. A veces se tiene una master y un layout por cada página de la web, aunque puede tener páginas o sitios dentro de la colección que usen el mismo layout.

Ejemplo master:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

 

<%@ Register TagPrefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages"

    Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

<%@ Register TagPrefix="wssuc" TagName="Welcome" Src="~/_controltemplates/Welcome.ascx" %>

<%@ Register TagPrefix="wssuc" TagName="DesignModeConsole" Src="~/_controltemplates/DesignModeConsole.ascx" %>

<%@ Register TagPrefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls"

    Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

<%@ Import Namespace="Microsoft.SharePoint.ApplicationPages" %>

<%-- Uses the Microsoft Office namespace and schema. --%>

<html xmlns="http://www.w3.org/1999/xhtml">

<%-- The head section includes a content placeholder for the page title and links to CSS and ECMAScript (JScript, JavaScript) files that run on the server. --%>

<head id="Head1" runat="server">

                <META Name="GENERATOR" Content="Microsoft SharePoint">

                <META Name="progid" Content="SharePoint.WebPartPage.Document">

                <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">

                <META HTTP-EQUIV="Expires" content="0">

    <SharePoint:RobotsMetaTag ID="RobotsMetaTag1" runat="server" />

    <asp:ContentPlaceHolder runat="server" ID="head">

        <title>

            <asp:ContentPlaceHolder ID="PlaceHolderPageTitle" runat="server" />

        </title>

    </asp:ContentPlaceHolder>

    <SharePoint:CssLink ID="CssLink1" runat="server" />

    <SharePoint:CssRegistration ID="CssRegistration" Name="<% $SPUrl:~SiteCollection/Style Library/miapp/mi.css %>"

        runat="server" />

    <asp:ContentPlaceHolder ID="PlaceHolderAdditionalPageHead" runat="server" />

</head>

<%-- When loading the body of the .master page, SharePoint Server 2007 also loads the SpBodyOnLoadWrapper class. This class handles .js calls for the master page. --%>

<body onload="javascript:_spBodyOnLoadWrapper();">

    <form id="Form1" runat="server" onsubmit="return _spFormOnSubmitWrapper();">

    <%-- The SPWebPartManager manages all of the Web part controls, functionality, and events that occur on a Web page. --%>

    <WebPartPages:SPWebPartManager ID="SPWebPartManager1" runat="server" />

    <div id="contenedor1" class="contenedor1">

        <div id="head">

            <img src="/Style%20Library/miapp/Images/headlogo.png" width="181" height="100"

                alt="headlogo" />

        </div>

    <div id="contenedor2">

        <div id="menuAccionesSitio">

            <SharePoint:SiteActions runat="server" AccessKey="<%$Resources:wss,tb_SiteActions_AK%>"

                ID="SiteActionsMenuMain" PrefixHtml="&lt;div&gt;&lt;div&gt;" SuffixHtml="&lt;/div&gt;&lt;/div&gt;"

                MenuNotVisibleHtml="&amp;nbsp;">

                <CustomTemplate>

                    <SharePoint:FeatureMenuTemplate ID="FeatureMenuTemplate1" runat="server" FeatureScope="Site"

                        Location="Microsoft.SharePoint.StandardMenu" GroupId="SiteActions" UseShortId="true">

                        <SharePoint:MenuItemTemplate runat="server" ID="MenuItem_Create" Text="<%$Resources:wss,viewlsts_pagetitle_create%>"

                            Description="<%$Resources:wss,siteactions_createdescription%>" ImageUrl="/_layouts/images/Actionscreate.gif"

                            MenuGroupId="100" Sequence="100" UseShortId="true" ClientOnClickNavigateUrl="~site/_layouts/create.aspx"

                            PermissionsString="ManageLists, ManageSubwebs" PermissionMode="Any" />

                        <SharePoint:MenuItemTemplate runat="server" ID="MenuItem_EditPage" Text="<%$Resources:wss,siteactions_editpage%>"

                            Description="<%$Resources:wss,siteactions_editpagedescription%>" ImageUrl="/_layouts/images/ActionsEditPage.gif"

                            MenuGroupId="100" Sequence="200" ClientOnClickNavigateUrl="javascript:MSOLayout_ChangeLayoutMode(false);" />

                        <SharePoint:MenuItemTemplate runat="server" ID="MenuItem_Settings" Text="<%$Resources:wss,settings_pagetitle%>"

                            Description="<%$Resources:wss,siteactions_sitesettingsdescription%>" ImageUrl="/_layouts/images/ActionsSettings.gif"

                            MenuGroupId="100" Sequence="300" UseShortId="true" ClientOnClickNavigateUrl="~site/_layouts/settings.aspx"

                            PermissionsString="EnumeratePermissions,ManageWeb,ManageSubwebs,AddAndCustomizePages,ApplyThemeAndBorder,ManageAlerts,ManageLists,ViewUsageData"

                            PermissionMode="Any" />

                    </SharePoint:FeatureMenuTemplate>

                </CustomTemplate>

            </SharePoint:SiteActions>

        </div>

        <div>

            <wssuc:DesignModeConsole id="IdDesignModeConsole" runat="server" />

            <SharePoint:DelegateControl ID="DelegateControl1" runat="server" ControlId="PublishingConsole"

                PrefixHtml="&lt;tr&gt;&lt;td colspan=&quot;4&quot; id=&quot;mpdmconsole&quot; class=&quot;ms-consolemptablerow&quot;&gt;"

                SuffixHtml="&lt;/td&gt;&lt;/tr&gt;">

            </SharePoint:DelegateControl>

        </div>

        <div id="menuhorizontal">

            <SharePoint:AspMenu   ID="TopNavigationMenu"

                              Runat="server"

                              DataSourceID="topSiteMap"

                              EnableViewState="false"

                              AccessKey="<%$Resources:wss,navigation_accesskey%>"

                              Orientation="Horizontal"

                              StaticDisplayLevels="2"

                              MaximumDynamicDisplayLevels="1"

                              DynamicHorizontalOffset="0"

                              StaticPopoutImageUrl="/_layouts/images/menudark.gif"

                              StaticPopoutImageTextFormatString=""

                              DynamicMenuItemStyle-BackColor="Black"

                              DynamicMenuStyle-ForeColor="White"

                              SkipLinkText=""

                              StaticSubMenuIndent="0"

            >

            </SharePoint:AspMenu>

            <SharePoint:DelegateControl ID="DelegateControl2" runat="server" ControlId="TopNavigationDataSource">

                <Template_Controls>

                    <asp:SiteMapDataSource ShowStartingNode="False" SiteMapProvider="SPNavigationProvider"

                        ID="topSiteMap" runat="server" StartingNodeUrl="sid:1002" />

                </Template_Controls>

            </SharePoint:DelegateControl>

            <asp:ContentPlaceHolder ID="PlaceHolderTopNavBar" runat="server">

                <asp:ContentPlaceHolder ID="PlaceHolderHorizontalNav" runat="server">

                </asp:ContentPlaceHolder>

            </asp:ContentPlaceHolder>

        </div>

        <div>

            <asp:ContentPlaceHolder ID="PlaceHolderTitleBreadcrumb" runat="server">

                <asp:SiteMapPath SiteMapProvider="SPContentMapProvider" ID="ContentMap" SkipLinkText=""

                    NodeStyle-CssClass="ms-sitemapdirectional" runat="server" />

                &nbsp;

            </asp:ContentPlaceHolder>

        </div>

        <div>

            <placeholder id="MSO_ContentDiv" runat="server">

                                                                                                                                               <asp:ContentPlaceHolder id="PlaceHolderPageDescription" runat ="server"/>

                                                                                                                                               <asp:ContentPlaceHolder id="PlaceHolderMain" runat="server" />

                                                                                                                                               </placeholder>

        </div>

      

            <asp:ContentPlaceHolder ID="PlaceHolderBodyAreaClass" runat="server" />

            <asp:ContentPlaceHolder ID="PlaceHolderTitleAreaClass" runat="server" />

            <asp:ContentPlaceHolder ID="PlaceHolderBodyRightMargin" runat="server" />

       

            <asp:ContentPlaceHolder ID="PlaceHolderSearchArea" runat="server" />

            <asp:ContentPlaceHolder ID="PlaceHolderPageTitleInTitleArea" runat="server" />

            <asp:ContentPlaceHolder ID="PlaceHolderLeftNavBar" runat="server" />

            <asp:ContentPlaceHolder ID="PlaceHolderPageImage" runat="server" />

            <asp:ContentPlaceHolder ID="PlaceHolderBodyLeftBorder" runat="server" />

            <asp:ContentPlaceHolder ID="PlaceHolderNavSpacer" runat="server" />

            <asp:ContentPlaceHolder ID="PlaceHolderTitleLeftBorder" runat="server" />

            <asp:ContentPlaceHolder ID="PlaceHolderTitleAreaSeparator" runat="server" />

            <asp:ContentPlaceHolder ID="PlaceHolderMiniConsole" runat="server" />

            <asp:ContentPlaceHolder ID="PlaceHolderCalendarNavigator" runat="server" />

            <asp:ContentPlaceHolder ID="PlaceHolderLeftActions" runat="server" />

            <asp:ContentPlaceHolder ID="PlaceHolderTitleRightMargin" runat="server" />

      

    </div>

    <div id="footer">

        Grupo Banco Popular. Todos los derechos reservados</div>

    </form>

</body>

</html>

Ejemplo de Layout:

 

<%@ Page

    language="C#"

    inherits="Microsoft.SharePoint.WebPartPages.WebPartPage, Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"

    masterpagefile="~masterurl/custom.master"

    meta:progid="SharePoint.WebPartPage.Document"

%>

<%@ Register

    Tagprefix="SharePointWebControls"

    Namespace="Microsoft.SharePoint.WebControls"

    Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"

%>

<%@ Register

    Tagprefix="WebPartPages"

    Namespace="Microsoft.SharePoint.WebPartPages"

    Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"

%>

<%@ Register

    Tagprefix="PublishingWebControls"

    Namespace="Microsoft.SharePoint.Publishing.WebControls"

    Assembly="Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"

%>

<%@ Register

    Tagprefix="PublishingNavigation"

    Namespace="Microsoft.SharePoint.Publishing.Navigation"

    Assembly="Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"

%>

 

<asp:content contentplaceholderid="PlaceHolderTitleBreadcrumb" id="contentMigaPan"

    runat="server">

</asp:content>

 

<asp:content id="Content1" runat="Server" contentplaceholderid="PlaceHolderMain">

                               <div id="banner1" runat="server" class="banner1">

                               <WebPartPages:WebPartZone runat="server" AllowPersonalization="true" ID="CenterColumnZone" FrameType="TitleBarOnly"

                                                                               Title="" Orientation="Horizontal">

                                                                              <ZoneTemplate>

                    </ZoneTemplate>

        </WebPartPages:WebPartZone>

    </div>

 

                <div id="contenedor2">

                               <div id="homeColumnaIzquierda" class="homeColumnaIzquierda">

                                <WebPartPages:WebPartZone runat="server" AllowPersonalization="true" ID="FirstColumnZone" FrameType="TitleBarOnly"

                                                                                              Title="Solicitud de ideas" Orientation="Horizontal">

                                                                                              <ZoneTemplate>

                        </ZoneTemplate>

            </WebPartPages:WebPartZone>

                                </div> 

                                <div id="homeLoMasNuevo" class="homeLoMasNuevo" >

                                               <WebPartPages:WebPartZone runat="server" AllowPersonalization="true" ID="MostNewColumnZone" FrameType="TitleBarOnly"

                                                                                              Title="Lo más nuevo" Orientation="Vertical">

                                                                                              <ZoneTemplate>                                          

                        </ZoneTemplate>

            </WebPartPages:WebPartZone>

                                </div>   

                </div>

                <div id="homelaboratorioBiblioteca" class="homeColumnalabBiblio" style="left: 0px; top: 0px" >

        <WebPartPages:WebPartZone runat="server" AllowPersonalization="true" ID="laboratorioColumnZone" FrameType="TitleBarOnly"

        Title="laboratorio" Orientation="Vertical">

            <ZoneTemplate>

            </ZoneTemplate>

        </WebPartPages:WebPartZone>                  

                </div>

</asp:content>

 

Bueno y en el siguiente pos mostraremos un script para poder desplegarlas de forma automática

Un saludo a todos

Mi primer paso en MOSS:Instalacion

Hay dias que es mejor no levantarse, son esos en los que cuando nunca has tocado MOSS te llega un gerente con cara de amigos de toda la vida y sonriendo te dice que te vas a un proyecto con esa maravillos herramienta de Microsoft.

Puess ese es mi caso, y entonces ves que se abre un mundo nuevo, que la mayoría de cosas que sabias… sirven, pero poco, y que cosas sencillas se vuelven difíciles… en fin el maravilloso mundo de MOSS 2007

En este primer post solo quería comentar que hay que tener para empezar a hacer algo con MOSS, y  ir tomando nota.

Una maquina virtual (preferiblemente windows2003)

Comenzando con ejecutar el Setup, introducir el ID Key dependiendo de la versión que quieran instalar, Standard o Enterprise.

Posteriormente les preguntará el tipo de instalación, y de las 3 opciones la más recomendada es la primera opción "Completa" y comenzará a instalar todos los archivos, y registros correspondientes del registry.

Después de un rato, se abrirá la pantalla de configuración del setup:

Damos clic en siguiente para comenzar la instalación y creación de bases de datos de configuración y administración, así como el copiado de archivos necesarios y la creación de llaves del registry.

Nos avisará que posiblemente tenga que detener algunos servicios, y confirmamos dando clic en Yes. 

En la siguiente pantalla nos preguntará si queremos que el servidor donde estamos instalando MOSS se una a la granja de servidores ya existentes o si deseamos crear una nueva (es decir una nueva base de datos de configuración), y este sería el caso, por lo que seleccionamos la segunda opción para instalar el primer servidor de MOSS 2007.

Nos pregunta el nombre del Server de SQL, propone el nombre default de creación de la base de datos de configuración (Microsoft recomienda dejar el default), y tenemos que proporcionar a continuación una cuenta de dominio (a la cuál previamente le dimos ya permisos de dbcreator y syssecurity en el Server de SQL que contendra las bases de MOSS) dominio\usuario y el password correspondiente. [Para efectos de esta descripción esta imagen fue editada y eliminado el nombre de dominio pero si se tiene que proporcionar al momento de la instalación de MOSS 2007].

En seguida una vez habiendo hecho el paso anterior (para crear la base de datos de configuración), el setup propone un puerto aleatorio (que será distinto si se volviera a ejecutar el setup desde el principio) para el sitio web de Administracion de MOSS (SharePoint Central Administration V3). Aunque se cuenta con la posibilidad de cambiarlo, podemos dejar el valor default; y de igual forma el default de la seguridad (NTLM).

Nos presenta una pantalla de confirmación.

Comienza a ejecutar los scripts de bases de datos, instalación de los archivos en el file system (como por ejemplo Features), y los registros necesarios del registry.

Al ultimo nos presentará la pantalla de termino exitoso.

Al hacer clic en el boton de "Finalizar", abrirá automáticamente la nueva página Web recién creada de Administración de MOSS 2007

 

un saludo y espero que os guste

Fuente:http://sharepointmx.mvps.org/blogs/ldusolier/archive/2006/08/21/60.aspx

Page.IsValid en javascript

hoy me he encontrado con una de esas cosas que si las sabes las haces en 10 minutos y si no... pues estas condenado a perder una mañana mirando en internet porque esta poco documentado y lo poco que esta no te dice nada.

 

El problema es saber si ha saltado un validador dentro de la pagina, pero en cliente, osea con javascript, para luego ejecurtar otra funcion.... al final si hay una propiedad que te lo dice y es Page_IsValid, esta propiedad te dice si la pagina es valida o no.

 

Pero si lo pones tal cual puedes ver que hace cosas raras asi que ospongo el codigo mas eficiente:

 

var isPageValid = Page_ClientValidate('');

if(isPageValid)

{

    funcionJavascriptAlanzar();

}

 

con esto obligamos a la pagina a lanzar los validators, y a ver si es correcta, y luego vomprobamos el resultado para llamar a la otra funcion.

 

Un saludo y en este post debo dar las gracias a mis compañeros Borja y Mario

Gracias a los dos por la ayuda

 

ref: http://msdn.microsoft.com/en-us/library/aa479045.aspx

busqueda de un usuario en LDAP

A veces buscamos un solo dato en un LDAP, otras autenticación y en definitiva siempre tiramos el mismo codigo para unas cosas que para otras.

Hace ya algunos meses publiqué un post sobre como lanzar una consulta a un LDAP, y en ese caso queriamos recuperar todos los usuarios de un grupo, la verdad es que fue muy util, pero no siempre queremos un listado.

En este caso voy a escribir como recuperar el correo electronico de un usuario al que queremos mandarle un mail, lo util es que como sabemos cual es su nombre de usuario,podemos acceder a la propiedad directamente ahorrandonos un par de bubles anidados y conseguir un tiempo de n o trivial en vez de n2 como se haria recorriendolo entero

 

El codigo seria este:

 

/Primero acotamos los varoles de busqueda y la ruta del Active Directoy,

                string[] domainAndUsername =usuario.Persona.AccountName.Split('\\');             
                string strDomain =domainAndUsername[0].ToString();
                string username = domainAndUsername[1].Trim();

                //Creamos una entra al Active Directory que devolverá el árbol en la variable entry.
                DirectoryEntry entry = new DirectoryEntry(UrlLdap,UsuarioLDAP,PaswordLDAP);

                //Realizamos una busqueda sobre la entrada anteriormente seleccionada.
                DirectorySearcher search = new DirectorySearcher(entry);

                //Filtramos el usuario del que queremos obtener los datos.
                search.Filter = "samaccountname=" + username;

                //Y realizamos una busqueda de todos sus datos.
                SearchResult results = search.FindOne();

                ResultPropertyCollection colProperties = results.Properties;

                //Obtenemos la propiedad mail
                string mail = string.Empty;
                foreach (object value in colProperties["mail"])
                {
                    mail = value.ToString();
                }

                return mail;

 

el bucle es necesario aunque solo hara una iteración, he intentado hacerlo sin el foreach, pero no lo he conseguido...

 

Este codigo para obtener los datos de un solo usuario es bastante eficiente, pero si sabeis alguno mejor, por favor no dudeis en postear

 

Un saludo a todos

una de patrones... workflow

En la una aplicación que estabamos montando teniamos un workflow con estados y el problema es que cada vez que lo modificabamos los objetos que entraban en el workflow se perdian... Es decir teniamos un problema con la persistencia de los objetos del workFlow (entonces lo montamos con WF), pero esto tampoco solucionó nuestro problema, ya que le pasaba lo mismo...

 

En ese momento un compañero tubo la idea feliz, usar un patron de diseño, e implentar nosotros mismos el workflow, con esta solución perdiamos la capacidad de ver el workflow como un conjunto de actividades y verlo de forma grafica... pero solucionabamos el problema de la persistencia, y la funcionalidad era la misma.

 

Asi pues... manos a la obra

 

declaramos una clase que sea virtual, y que implemente la transición por todos los estados como el salto de una excepcion (asi no deja pasar de un estado a otro)

 

Declaramos una clase por cada estado que sobre escribe los metodos de transitar a los estados que el puede transitar, de esta forma la excepcion solo saltara cuando se pretenda saltar a un estado que no pueda y con eso tenemos implementado el patron.

 

Si quereis saber mas sobre esta idea... escribirme o si sabeis alguna solución mas brillante tambien

 

Un saludo a todos

LinQ to SQL

Muchas veces he pensado en como hacer una aplicacion que leyera de un XML el cual puede ser modificado para configurar la aplicación, pero que no fuese el app.config, porque este archivo se lee de forma distinta.

La verdad es que era tedioso, y a veces por la cantidad de codigo que se tiraba era bastante dificil de hacerlo ya que habia que ir recorriendo el archivo en un bucle nodo a nodo.

 

Ahora es más sencillo y rápido, ya que contamos con LinQ to XML que permite lanzar sentecias tipo SQL pero sobre archivos XML. y ademas de forma sencilla

 

Aqui os dejo una demostración de como coger un archivo xml que esta en le disco duro

 

#region LinQ to XML

XElement elemento = XElement.Load(Server.MapPath("XMLFile1.xml"));

IEnumerable<string> a = (from c in elemento.Elements("empleado")

select

(String)c.Attribute("nombre").Value.ToString()

);

this.ListBox1.DataSource = a;

this.ListBox1.DataBind();

Con esto carga en el listBox todos los datos que necesitamos

 

un saludo

Servicios web en MOSS

Este es un post que llevaba tiempo queriendo escribir, no es mucho de programación pero si no lo tienes en cuenta... te puedes tirar tres dias intentando ver porque falla es servicio web.

 

Para entrar en materia, pongamos una situacion... un servidor con MOSS que tiene varios sitios creados, y en uno de ellos tenemos una biblioteca de documents. Queremos utilizar un servicio web lists para gestionar la biblioteca y cuando añadimos a nuestra aplicacion el servicio web con la url

http:/servidor/_vti_bin/lists.asmx

vemos que esto falla y entonces te vuelves loco para ver porque, la url de la biblioteca esta bien, el servicio esta levantado... pero todo falla.

¿Por que? la respuesta es sencilla y es que para que encuentre los elementos de la biblioteca el servicio que hay que añadir es el del sitio en el que se alojo la biblioteca de documentos

 

http://servidor/sitio/_vti_bin/lists.asmx

 

En fin que por esas cosas, puedes perder unos dias de trabajo maravillosos y volverte loco.

 

Un saludo a todos

Observacion sobre LinQ

Este post es uno de esos, que pongo y no tienen codigo. más que nada explica como funciona LinQ.

 

LinQ es uno de esos grandes inventos, que te permiten tirar una select a practicamente cualquier cosa que sea enumerable, y tambien sobre una BD. pero si lo usas intentando obtenerun Ienumerable y un var... puedes hacer que la sentencia tire un monton de sentencias SQL.

 

Este problema es sencillo de arreglar, si en vez de devolver un Ienumerable vas devolviendo un IQueryable, asi lo que devuelves en casa sentencia en una query, que se ira puliendo segun sobre ella vayas concatenando nuevas querys. Al final en el sitio donde quieras obtener los datos tendras que poner un .AsEnumerable, y esto es lo que ejecutara la sentencia SQL sobre la BD, y lo mejor es que esta sentencia sera8 por regla general muy optimizada.

 

Bueno solo era unas aclaraciones sobre el funcionamiento de linQ

 

Un saludo a tod@s

una de accesibilidad

Hoy vamos a hablar de accesibilidad, no pretendo hacer una guía exhaustiva de  cómo hacer una página accesible triple AAA, porque el proceso además de ser peliagudo, conlleva la verificación de varios puntos, que a veces incluso se pueden llegar a omitir si se cumplen ciertas cosas. O sea que nuestro objetivo es crear una página accesible y que luego con tiempo se verifiquen los puntos y si hay algo que cambiar sea lo mínimo.

1-      Las tablas son solo para datos, se acabo el utilizar tablas para maquetar, ya que esto crea confusión, en su lugar se utilizarán los div

2-      Las tablas tienen que tener una estructura lógica (th, summary…)

3-      El posicionamiento debe ser con “position:relative;” ya que esto nos permite posicionar donde queramos pero la posición será relativa al tamaño de pantalla.

4-      Los tamaños son en base a “em” que es un tamaño relativo al tamaño de pantalla, con esto evitamos el problema de ampliar el tamaño de letra y que se solapen los contenidos

5-      Utilizar margin-left, margin top, o margin-right para separar y posicionar elementos

6-      Agrupar elementos de formulario comunes con un fileset y poner una etiqueta legend para aclarar el contenido

7-      Cuidado con el contraste de colores, debe ser suficiente como para que no haya equivocación.

8-      Las imágenes tienen que tener el atributo alt

9-      La pagina debe valiar sintácticamente el html generado en por la w3c

10-   La pagina si utiliza algo de javascript, la misma funcionalidad implementada con javascript debe darse la opción de hacerla por postback

11-   Se recomienda el uso de la etiqueta noscript para poner botones que solo se vean si no hay javascript

12-   Los textos deben ir en una etiqueta p o span

13-   Las label deben ir asociadas a algún elemento de formulario como los input text

14-   Utilizar una estructura lógica de elementos h1,h2..etc

 

Bueno de momento esto es lo que se me ocurre, no obstante os dejo la pagina de una empresa que se dedica a esto de la accesibilidad y que tiene la documentación de los puntos a verificar en español (siempre es de agradecer leer la lengua de Cervantes  y no la de un Shakespeare)

http://www.technosite.es/document_accesibilidad.asp

 

Un saludo

consultas al Active Directory

Despues de una temporada sin escribir hoy hare el esfuerzo con un tema que realmente merece la pena LDAP y loggin, porque a ver, ¿a quien no se le ha ocurrido que el registro de login sea el de Active Directory?¿y en este caso como consultar desde .net el Active Directory?

 

La verdad es que es un tema que da mucho juego, pero en definitiva consiste en conectarse a una zona del active directory y coger lo datos que se necesitas, estos datos estan almacenados en las propiedades.... pero bueno mejor os dejo un ejemplo:

 

public DataTable getUsuarios()
        {
            //creo el dataTable y su estructura
            DataTable dt = new DataTable();
 
            dt.Columns.Add("Columna1");
            dt.Columns.Add("Columna2");
            dt.Columns.Add("Columna3");
 
            //Cargo el documento que contiene los mapeos

            //se conecta a la direcion LDAP
string path="LDAP://miempresa.dominio/DN=miempresa DC=dominio" ;                
                DirectoryEntry ent = new DirectoryEntry(path);
                DirectorySearcher busc = new DirectorySearcher(ent);
                SearchResultCollection resul = busc.FindAll();
               
                //Desglose de la informacion que necesitamos
                string[] rutaparcial = path.Split('/');
                string[] elementos = rutaparcial[3].Split(',');
                //Nombre del grupo que estamos consultando
                string grupo = elementos[0].Replace("CN=", "");
               
                //modulo del que se tiene permisos
                string modulo = nodoProc.InnerText.ToString();
             
 
 
                string member = "";
 
                foreach (SearchResult resultados in resul)
                {
                    ResultPropertyCollection colproperties = resultados.Properties;
 
                    foreach (string key in colproperties.PropertyNames)
                    {
                        foreach (object value in colproperties[key])
                        {
                            // Console.WriteLine(key.ToString()+"  "+value.ToString());
 
 
                            if (key.ToString() == "member")
                            {
                                member = value.ToString();
                                string s = member.Replace("member", "");
                                string nuevopath = "LDAP://" + s;
                                DirectoryEntry ent1 = new DirectoryEntry(nuevopath);
                                DirectorySearcher busc1 = new DirectorySearcher(ent1);
                                SearchResultCollection resul1 = busc1.FindAll();
 
 
                                for (int i = 0; i < resul1.Count; i++)
                                {
                                    SearchResult resultados1 = resul1[i];
                                    string username = (string)resultados1.Properties["userprincipalname"][i];
                                    string[] users = username.Split('@');
                                    string CN = (string)resultados1.Properties["CN"][i];
                                    DataRow dr = dt.NewRow();
                                    dr[0] = modulo.ToString();
                                    dr[1] = grupo.ToString();
                                    dr[2] =CN+" ( "+ users[0].ToString()+")";
                                    dt.Rows.Add(dr);
                                }
 
 
 
                            }
                        }
                    }
                }
            }
            return dt;
        }

Problemas con Team Foundation Server y MOSS

Ha veces que nos encontramos con un problema y no sabemos de que, y te comes la cabeza un buen rato hasta que descubres que te esta afectando algo que nisiquieras utilizabas... A mi esto me paso ayer y el problema era bien sencillo

 

Lo primero es decir que estaba trabajando con Reporting Services y tenia publicados varios informes que funcionaban perfectamente bajo el Visual Studio, luego me cree unas paginas aspx desde donde veia los informes, que cosa tan bonita!!, el problema fue cuando quise verlos directamente generados por Team Foundation Server, que no se veia y siempre con el mismo error (Alguno dirian, joder pues que se vea a traves del aspx!!!) pero eso aqui no vale (no me dejan chapucear a mis anchas...jejejeje)

 

Bueno el error que daba y la solucion lo dejo aqui:

 

The type Microsoft.SharePoint.Portal.Analytics.UI.ReportViewerMessages, Microsoft.SharePoint.Portal,
Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c does not implement
IReportViewerMessages or could not be found.
 
El problema era que el moss 2007 y reporting services se pegan por la librería, por lo que hay que quitarla,
 
En los dos web.confing, tanto el de ReportMananger como en el de SerpotServer hay que añadir en la seccion de appsetting esto
<remove key=”ReportViewerMessages” />
 
En caso del ReportServer no estaba esta seccion, pues se crea y ya esta.
 
La solucion esta basada en este articulo
http://secondstanza.com/category/team-foundation-server/

 

un saludo a todos

EnterpriseLibrary

Hace tiempo Microsoft saco unas librerias que eran un conjunto de buenas practicas y patrones de diseño para su entorno .net, estas librerias fueron evolucionando hasta lo que hoy es la version 4 de las EnterpriseLibrary

 

Que como se utilizan? lo primero es bajarlas de la pagina web e instalarlas, esto de la instalacion es bueno porque no solo te instala las librerias, sino que tambien un programita para configurar los archivos .config que los utiliza para poder escribir logs...etc

 

El segundo paso seria añadir las librerias que vamso a utilizar al proyecto, y en el using añadir los namespaces que nos hagan falta.

 

a partir de ahi ha programar, y una vez que compila, no te olvides de usar la aplicacion de las EnterpriseLibrary para configurar el archivo de configuracion.

 

Un ejemplo de codigo seria este:

 

Using Microsoft.Practices.EnterpriseLibrary.Logging;

 

 

public int logar (Exception err)

{

 

   try

    {

       LogEntry log=new LogEntry();

       log.Message=error.Message.ToString();

       log.Categories.add("Warnning");

    

       Logger.Write(log,"Application",0);

   

       return 0;

     }

catch { return -1;

    }

}

Hilos

Una de las cosas que más me gusta de mi trabajo, es el poder aprender cosas nuevas... o por lo menos, cosas que aunque son ya antiguas, su tienes que aprender su uso.

 

Una de estas cosas es el uso de hilos de ejecucion, la verdad es que este post es mas bien para mi, ya que la mayoria ya lo sabreis, pero como me hace ilusion el publicar un post de algo que he aprendido ahi va.

 

La cosa es poder dividir en hilos paralelos, la ejecucion de un problema, asi si tenemos algo que hay que hacer n veces y son independientes entre ellos, podemos pasar un array de n /numero de hilos. asi cada hilo hace paralelamente con otros unas cuantas iteraciones menos de los que se haria sin ellos. y el tiempo de ejecucion es menor.

 

Un ejemplo...

 

 

ArrayList lista=Obtenerlista();

ArrayList ListaArrays = new ArrayList();

for (int i = 0; i < numeroHilos; i++)

{

ArrayList a = new ArrayList();

ListaArrays.Add(a);

}

int posicion = 0;

for (int i=0; i < lista.count; i++)

{

  int pos=lista.count%(i+1);

ArrayList a=(ArrayList)listaArrays[pos];

a.add(lista[i].toString());

listaArrays[pos]=a;

}

/*generacion y arranque de los hilos*/

for (int i = 0; i < numeroHilos; i++)

{

ArrayList lista =(ArrayList) ListaArrays[i];

if (lista.Count > 0)

{

hilo1 h1 = new hilo1(lista);

Thread hilo = new Thread(h1.Tratar);

hilo.Start();

Console.WriteLine("lanzado el hilo: " + i.ToString() + " primera incidencia: " + lista[0].ToString());

}

}

 

linQ to DataSet

Hola a tod@s !!!

 

Por fin he tenido tiempo de aprender una de esas nuevas cosas que hay en el Framework 3.0 y 3.5. La verdad es que este es un post que tenia ganas de publicar, pero que por falta de tiempo y sobre todo porque tenia que investigar como se hacia no he podido hacer hasta ahora.

 

La problematica es muy simple, hacemos una consulta a la BBDD y lo dejamos en un dataset, entonces, ya tenemos en memoria un conjunto de datos, pero ahora queremos pequeñas consultas parciales a esos datos para mostrar por partes los datos obtenidos.

 

La solución es untilizar LinQ con consultas a los datos del dataset, ya que podemos utilizar un where que nos filtre los datos, y ademas seleccionar solo los campos que queremos mostrar en ese apartado.

 

Aqui os dejo como se haria una consulta a un dataset con una sola tabla (para mi es el caso normal... aunque a veces hay que meter en un mismo dataset varias tablas, este ejemplo lo pondre en un futuro post)

 

 

DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);

DataTable orders = ds.Tables["SalesOrderHeader"];

var query =
    from order in orders.AsEnumerable()
    where order.Field<bool>("OnlineOrderFlag") == true
    select new
    {
        SalesOrderID = order.Field<int>("SalesOrderID"),
        OrderDate = order.Field<DateTime>("OrderDate"),
        SalesOrderNumber = order.Field<string>("SalesOrderNumber")
    };

foreach (var onlineOrder in query)
{
    Console.WriteLine("Order ID: {0} Order date: {1:d} Order number: {2}",
        onlineOrder.SalesOrderID,
        onlineOrder.OrderDate,
        onlineOrder.SalesOrderNumber);
}

 

Un saludo

 

fuente: http://msdn.microsoft.com/es-es/library/bb386910.aspx

 

Primeros pasos con LinQ

Hoy es uno de esos dias que son productivos, sip, hoy he aprendido como utilizar el linQ.

Para todos aquellos que no sepan nada de esta tecnologia (como yo hace poco tiempo...todo hay que reconocerlo) se trata de un nuevo añadido a .net que le permite crear sentencias de seleccion sobre los tipos de datos agregados.

 

me explico que esto suena muy pedante: Se trata de poder hacer una especie de sentencia select, a un array, o a un dataset...etc.

 

Un ejemplo de ello es esta sentencia sobre un array, ya ire escribiendo sobre linQ segun vaya aprendiendo:

 

string[] cities = { "London", "Amsterdam", "San Francisco", "Las Vegas",

                            "Boston", "Raleigh", "Chicago", "Charlestown",

                            "Helsinki", "Nice", "Dublin" };

 

        GridView1.DataSource = from city in cities

                               where city.Length > 4

                               orderby city

                               select city.ToUpper();

 

        GridView1.DataBind();

 

Un saludo

SQL server y PDAS

Hola a todos:

 

Ultimamente no escribo mucho, y la verdad es que es por falta de tiempo y de tener cosas realmente interesantes que escribir relacionadas con este mundo.

 

Aunque prometo escribir pronto uno de interes general (por lo menos para mi) aunque no este muy relacionado con la tecnologia, sera algo muy importante... y creo que merecerá la pena publicarlo.

 

Volviendo al tema que me ha llevado a escribir este post, he de decir, que hasta hoy una de las cosas que mas me fastidiaban de las PDAs es que no podia utilizar motores de BBDD, y eso es un incordio el tener que guardar todo en ficheros de texto (si quieres que la información sea permanente).

 

La solucion la he encontrado hoy.

A parte de los motores e BBDD de pago que hay en el mercado, Microsoft con el Visual Studio 2005 permite crear una BBDD con SQL server express, pero para compact Framework (y todo de forma grafica...jejeje). Luego se gestiona con la API System.Data.SqlServerCe. a partir de ahi, pues se maneja como una base de datos normal, aqui os dejo una clase conexion, un select y un insert, cosa muy utiles para trabajar con ellas.

 

 

using System;

using System.Data;

using System.Configuration;

 

 

/// <summary>

/// Summary description for Conexion

/// </summary>

public class Conexion

{

System.Data.SqlServerCe.SqlCeConnection conexion=new System.Data.SqlServerCe.SqlCeConnection();

public Conexion()

{

conexion.ConnectionString = "Data Source = \\Archivos de programa\\EnersysTPV\\tpv.sdf";

}

public System.Data.SqlServerCe.SqlCeConnection abrir()

{

try

{

this.conexion.Open();

return (conexion);

}

catch (Exception conerr)

{

Console.WriteLine(conerr.Message);

return (conexion);

}

}

public System.Data.SqlServerCe.SqlCeConnection getConexion()

{

return (this.conexion);

}

 

public void cerrar()

{

this.conexion.Close();

}

}

 

 

 

string select="select * from clientes";

Conexion con = new Conexion();

try

{

System.Data.SqlServerCe.SqlCeDataAdapter da = new System.Data.SqlServerCe.SqlCeDataAdapter();

da.SelectCommand = new System.Data.SqlServerCe.SqlCeCommand(select, con.abrir());

DataSet ds = new DataSet();

da.Fill(ds, "clientes");

dataGrid1.DataSource = ds.Tables[0];

}

catch (Exception err) { MessageBox.Show(err.Message.ToString()); }

finally { con.cerrar(); }

 

 

 

string sentencia = "insert into clientes (nombre,apellidos,direccion,nif)values ('fernando','Gomez','C\\ Parque del teide','123123123')";

Conexion con =new Conexion();

try{

System.Data.SqlServerCe.SqlCeCommand cmd= new System.Data.SqlServerCe.SqlCeCommand();

cmd.CommandText=sentencia.ToString();

cmd.Connection=con.abrir();

cmd.ExecuteNonQuery();

}catch (Exception err){MessageBox.Show(err.Message.ToString());}

finally {con.cerrar();}

 

 

 

Un saludo a todos y espero que os guste este post

Problemas con los protocolos de los webservices

Hola a todos

Este post lo escribo porque me surgió un problema que me ha traido de cabeza durante dos días, si no es mucho tiempo, pero cuando creas un nuevo webservices lo ejecutas en el debug y funciona, y cuando lo llamas desde otro ordenador te dice que no, te mosqueas, ademas el mensaje es gracioso, te dice que solo lo puede ejecutar en local.

Bien despues de intentar darle permisos, y darle control total a todos los archivos (cafrada lo sé, pero es lo que tiene cuando quieres que funcione algo y no sabes que falla). Despues de probar todo lo que se me ocurria, fui al "doctor google" el cual me solucionó mi problema.

El problema es de protocolos, tienes que añadir los protocolos en el webc.onfig si suena a coña, pero es que para los webservices, el unico protocolo que por defecto esta activo el localhostPOST... con lo que solo puede ejecutarlo en local

La solución es añadir esto:

<webServices>

<protocols>

<add name="HttpGet"/>

<add name="HttpPost"/>

<add name="HttpSoap"/>

<add name="HttpPostLocalhost"/>

</protocols>

</webServices>

</system.web>  //Estos dos ultimos ya estaban los meto para que veais donde lo he puesto

</configuration>

 

Bueno espero que os haya servido de algo, y si no ya se donde esta publicado para la proxima vez que no me acuerde...

os dejo una url con la solución al completo y explicadita.

Un abrazo a todos

http://support.microsoft.com/kb/819267/es

Envio de datos por FTP y .net

¿nunca habeis tenido la necesidad de subir un archivo a un servidor? yo me he encontrado con un problema asi, y la unica forma fue crear un programa que subiera un archivo por ftp.

Como mi gran amigo Lucas diria (tio si ya existe el filezilla...) ya pero el problema se puede volver mas complejo si lo que queremos es actualizar una base de datos remota con una local, y la unica forma de pasarle los datos al servidor es por ftp, y es usuario (o cliente ) es un manazas que no quieres que toque el servidor. Asi se me ocurrio una aplicacioncilla que se basa en esta clase.

 

Lo malo era lo de enviar el archivo, pero en este mundo todo tiene solucion y por eso mirando el la web he encontrado esta pagina y eso si, lo amplio con los using que hay que poner:

 

using System;

using System.Collections.Generic;

using System.Text;

using System.IO;

using System.Net;

 

namespace SubirArchivos

{

class ftp

{

public ftp()

{

}

 

public void UploadFTP(string FilePath, string RemotePath, string Login, string Password)

{

using (FileStream fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.Read))

{

string url = Path.Combine(RemotePath, Path.GetFileName(FilePath));

// Creo el objeto ftp

FtpWebRequest ftp = (FtpWebRequest)FtpWebRequest.Create(url);

// Fijo las credenciales, usuario y contraseña

ftp.Credentials = new NetworkCredential(Login, Password);

// Le digo que no mantenga la conexión activa al terminar.

ftp.KeepAlive = false;

// Indicamos que la operación es subir un archivo...

ftp.Method = WebRequestMethods.Ftp.UploadFile;

// … en modo binario … (podria ser como ASCII)

ftp.UseBinary = true;

// Indicamos la longitud total de lo que vamos a enviar.

ftp.ContentLength = fs.Length;

// Desactivo cualquier posible proxy http.

// Ojo pues de saltar este paso podría usar

// un proxy configurado en iexplorer

ftp.Proxy = null;

// Pongo el stream al inicio

fs.Position = 0;

// Configuro el buffer a 2 MBytes

int buffLength = 2097152;

byte[] buff = new byte[buffLength];

int contentLen;

// obtener el stream del socket sobre el que se va a escribir.

using (Stream strm = ftp.GetRequestStream())

{

// Leer del buffer 2Mb cada vez

contentLen = fs.Read(buff, 0, buffLength);

// mientras haya datos en el buffer ….

while (contentLen != 0)

{

// escribir en el stream de conexión

//el contenido del stream del fichero

strm.Write(buff, 0, contentLen);

contentLen = fs.Read(buff, 0, buffLength);

}

}

}

}

}

}

 

Luego para utilizarlo simplemente pon esto con tus datos:

 

ftp f = new ftp();

f.UploadFTP(@"C:\Archivo.txt", "ftp://ftp.vtortola.net/Upload", "MiUsuario", "MiPassword");

 

Un saludo a todos
Fuente: http://www.vtortola.net/post/Enviar-un-archivo-por-FTP.aspx

 

 

Manejo de camara de fotos en una PDA

Siempre es interesante cuando te compras un cacharrito saber lo que puedes hacer con el, y en el caso de un ordenado o una PDA más aun, ya que si sabes programación puedes construirte tus propias aplicaciones, esas que necesitas.

 

En este caso voy a hablar de como podemos manejar la camara de fotos de una PDA desde una aplicación ¿para que sirve? pues bueno podemos bajar la resolucion y enviar la foto por ftp, a un servidor... que no es poco, o mandarla por mail a la direccion que quieras (en este caso ya necesitamos el servicio web que lo envie)

 

Yo en este post voy a poner la solucion de manejo de la camara de fotos y ya en los sucesivos ire poniendo como mandarla por mail, o por ftp:

 

La solucion es sencilla si conoces la API, se trata de la API CameraCaptureDialog que permite el manejo de todos los parametros de la camara. apartir de ella podemos bajar la resolucion de la las fotos, y modificar el nombre de las fotos (el que sale por defecto) Aqui os dejo un ejemplo para modificar la resolución.

 

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

 

namespace PruebasCamaraFotos

{

public partial class Form1 : Form

{

public Form1()

{

InitializeComponent();

}

private void button1_Click(object sender, EventArgs e)

{

Microsoft.WindowsMobile.Forms.CameraCaptureDialog capturas = new Microsoft.WindowsMobile.Forms.CameraCaptureDialog();

capturas.Resolution = new Size(50, 50);

capturas.ShowDialog();

}

}

}

 

 

Aqui como fuente tengo que dar las gracias a mi amigo Javier Albert Segui, que me prestó su ayuda lo mas rápido que pudo.

Gracias tio

Dimensionar una columna de un datagrid

Hola a tod@s,

 

¿A quien no le ha ocurrido, el mostrar en un datagrid dos columnas resultado de una consulta a la base de datos, y el resultado es dos columnas muy pequeñas que quedan horriblemente mal?

 

Pues yo el primero, y mira que me he pegado con este problema, pero todo trabajo tiene su recompensa y hoy lo he solucionado, al final le problema solo requiere unas pocas lineas de codigo, pero que si no las sabes... pues se convierte en algo muy complejo.

 

Aqui os dejo mi solución

 

Un abrazo a tod@s!!!.

 

 

DataGridTableStyle ObjEstiloTabla= new DataGridTableStyle();

this.dataGrid1.TableStyles.Add(ObjEstiloTabla);

this.dataGrid1.DataSource = dt;

// DataGridTextBoxColumn ObjEstiloColumna = new DataGridTextBoxColumn();

dataGrid1.TableStyles[0].GridColumnStyles[0].Width = 60;

dataGrid1.TableStyles[0].GridColumnStyles[1].Width = 150;

 

 

Fuente: El Guille (como no)

 

http://www.elguille.info/colabora/NET2005/Percynet_PersonalizandoDataGrid.htm

expresiones regulares en php

Si, hoy es un dia productivo para el blog, lleva una o dos semanas sin escribir... pero hoy ya he escrito dos, y al ritmo que voy no niego la posibilidad de escribir otro post.

 

El tema de hoy es manejar expresiones regulares, y mas en concreto el poder reemplazar un caracter por otro, bien vamos por partes:

 

Las expresiones regulares permiten definir patrones de coincidencia y aplicarlas a cadenas de texto para saber si la cadena (o parte de ella) cumple el patrón e incluso realizar transformaciones de la cadenaLas expresiones regulares permiten definir patrones de coincidencia y aplicarlas a cadenas de texto para saber si la cadena (o parte de ella) cumple el patrón e incluso realizar transformaciones de la cadena, en php hay dos tipos de expresiones regulares:

    POSIX extendido: Las funciones básicas de expresiones regulares POSIX extendido para comparar una cadena con un patrón son ereg($patron, $cadena) y eregi($patron, $cadena). La diferencia entre ellas es que ereg() distingue entre mayúsculas y minúsculas y eregi() no. Estas funciones comprueban si la cadena cumple el patrón y devuelven el valor 1 (verdadero) o 0 (falso). Los argumentos de las funciones pueden ser cadenas o variables que contengan cadenas. Si el patrón es la cadena vacía, las funciones devuelven error.

    compatibles con Perl: La función de expresiones regulares compatibles con Perl preg_match($patron, $cadena [, $matriz_coincidencias [, $modificadores [, $desplazamiento]]]) compara una cadena con un patrón y devuelve 1 si el patrón ha coincidido o 0 si no. La primera coincidencia encontrada se puede guardar en el argumento opcional $matriz_coincidencias y, si se añade el modificador PREG_OFFSET_CAPTURE, se guarda también en el argumento opcional $matriz_coincidencias la posición de la coincidencia encontrada. El argumento opcional $desplazamiento es un número que permite indicar en qué carácter se inicia la búsqueda.

 

Para utilizar el reemplazo simplemente hay que utilizar la sentencia:

 

ereg_replace ('expresion regular', 'expresion por la que cambiar', $cadenaEnLaQueAplicar);

 

ejemplo para quitar los saltos de linea y retornos de carro ejecutamos dos veces la sentencia de esta forma

 

$cadena=mysql_result($result,0, "noticia");
$hola= ereg_replace("\n", " ", $cadena);
$cadenafinal =ereg_replace("\r", " ", $hola);

 

Un abrazo a todos y espero os sirva tanto como a mi me ha servido

 

 

fuentes:

http://www.mclibre.org/consultar/php/lecciones/php_expresiones_regulares.html

http://www.forosdelweb.com/f18/ereg_replace-377907/

 

Conferencia en la UPSAM

Hola tod@s

 

Este año estamos más rezagados, pero bueno la verdad es que esta año empezamos fuertes.

El año pasado se dieron un ciclo de conferencias en la UPSAM y este año repetimos, la primera la damos mi gran amigo José Llobell y yo, es de desarrollo de aplicaciones moviles y servicios web. Contamos con la inestimable colaboracion de Mari Anageles (la chica de mis sueños).

 

Pues el objetivo es mostrar como desarrollar aplicaciones distribuidad con dispositivos moviles y .net.

El lugar es en la sede de Madrid de la Universidad Pontificia Salamanca, (UPSAM) en el paseo Juan XXII a las 17:00 Aula B (edificio blanco)

 

Si quereis conocernos o aprender un poquito mas sobre este mundo. no dudeis en venir, la conferencia es gratis!!!

 

Un abrazo a tod@s

envio de mails con php

Buenas, ya se que es muy pronto, y que encima esta lloviendo...

Pero en fin,¿que se va ha hacer?

Ayer me llego el jefe y me pido que una aplicacion php enviara mails, todos sabeis que mi especialidad es el .net, y que el envio de mails, siempre lo habia hecho con esa clase maravillosa que me enseño uno de los grandes gurus de la programacion web ("El Guille"- elguille.info)

Asi que le dije, lo tengo que mirar. y bueno despues de ojear unas pocas paginas he encontrado una solucion a este problema. y esque para php hay mazo de documentación...

Resumiendo. Aqui se trata de una funcion que ya tiene php que es la funcion mail. que recibe tres parametros por defecto y que puede recibir alguno mas como complemento.

el codigo es el siguiente:

 

Un abrazo a tod@s

<?
$destinatario = "fernando.gomez@marferdotnet.com"; //esta direccion es falsa
$asunto = "Este mensaje es de prueba";
$cuerpo = '
<html>
<head>
   <title>Prueba de correo</title>
</head>
<body>
<h1>Hola amigos!</h1>
<p>
<b>Bienvenidos a mi correo electrónico de prueba</b>. Estoy encantado de tener tantos lectores. Este cuerpo del mensaje es del artículo de envío de mails por PHP. Habría que cambiarlo para poner tu propio cuerpo. Por cierto, cambia también las cabeceras del mensaje.
</p>
</body>
</html>
';

//para el envío en formato HTML
$headers = "MIME-Version: 1.0\r\n";
$headers .= "Content-type: text/html; charset=iso-8859-1\r\n";

//dirección del remitente
$headers .= "From: Angeles Macias<angeles.macias@marferdotnet.com>\r\n";

//dirección de respuesta, si queremos que sea distinta que la del remitente
$headers .= "Reply-To: mariano@marferdotnet.com\r\n";

//ruta del mensaje desde origen a destino
$headers .= "Return-path: holahola@marferdotnet.com\r\n";

//direcciones que recibián copia
$headers .= "Cc: maria@marferdotnet.com\r\n";

//direcciones que recibirán copia oculta
$headers .= "Bcc: pepe@pepe.com,juan@juan.com\r\n";

mail($destinatario,$asunto,$cuerpo,$headers)
?>

 

Fuente: http://www.desarrolloweb.com/articulos/969.php

Mis primeros pasos con php

No solo vivo de Net, hay muchas otras tecnologías, y como yo estoy en expansión he decidido informar de cosas que seguramente ya sepáis de otras tecnologías pero que para mi son nuevas.

 

Una de ellas es php, si ese lenguaje interpretado, del servidor, que funciona tipo java (pero sin VM ) y que es muy utilizado en paginas Web…

 

Pues trasteando con php, hoy he conseguido aprender un par de cosas muy interesantes, la primera era el uso de plantillas, para eso te haces una Web normal, con su código y la guardas como una plantilla, entonces se guardara por defecto en la carpeta templates. Luego cuando te crees una nueva pagina créala de esta manera Archivo/nuevo y en la venta pon crear pagina de plantilla.

Elige la plantilla y ya solo con actualizar la plantilla se te actualizaran las páginas que has creado con esa plantilla. Eso si no te olvides de las secciones editable, que son las que varían de una pagina a otra

 

La otra es el poder crear un script de javascript de forma dinámica, lo se es sencillo con PHP pero… yo lo descubrí ayer y la verdad es que me gusto solo hay que poner esto

 

Echo “<script lenguaje=’javascript’>

                        Codigo javascript

           

            </script>”;

En el código javascript se puede alternar, cerrando el echo, y poniendo el código php que se quiera para volver a poner echo y código javascript según las condiciones de las variables php

 

Esto le da una gran potencia al poder crear funciones que tienen un codigo distinto dependiendo de algunas variables.

 

Un saludo y hasta otra.

Oracle y .net

Buenas a todos:

ya se sabe que en el mundo hay otras tecnologias que no son de Microsoft, y claro tambien hay que conocerlas y utilizarlas.

 

hoy toca hablar de Oracle y entorno de desarrollo .net (Visual Studio 2005), y esque a veces mezclar tecnologias y empresas... por mucho que sean ambas muy buenas en su sector... pues es un lio que hay que solventar de la mejor manera.

 

Hoy estaba en el curro, y no conseguia hacer una delete a una tabla en una base de datos.

El proveedor de oracle para .net es System.Data.OracaleClient, (System.Data.OracaleClient.dll), y trae los mismos metodos que cualquier otro proveedor SqlProvider,  Odbc, u OleDb. Para mi sorpresa no ejecutaba los deletes, no los updates, ni los insert, es mas no daba error y se quedaba colgado... un mierda (hablando claro), en fin.

Pero al provar con el generico, es decir oledb, ha empezado a funcionar... Osea que los proveedores no hacen su trabajo bien, y si quieres que algo funcione correctamente prueba con el generico, que es menos probable que te falle.

 

 

Un abrazo  

Imprimir en un TXT

Yo a veces me pregunto... ¿Por que no nos enseñan a imprimir? Lo cierto es que cuando haces un programa para alguien es muy comun que te digan, que quieren imprimir, ya sea una factura o un listado...

Yo me he encontrado con ese problema varias veces, pero la mayoria habia que hacer una web, y el navegador ya tiene el control de impresión, con lo que solo te tienes que encargar de que el documento quede bonito...

En este post queria poner una solución a este problema e invitaros a que me digais como imprimir un word, por ejemplo, o una factura donde se meta incluso imagenes... no se es amplio, asique espero vuestras aportaciones.

 

Un abrazo

using System;using System.Drawing;
using System.IO;
using System.Drawing.Printing;
using System.Windows.Forms;
namespace PrintApp{   
public class Form1 : Form    {
 private Button printButton; 
 private PrintDocument printDocument1 = new PrintDocument();
 private string stringToPrint; 
 
 public Form1()   {
 this.printButton = new System.Windows.Forms.Button();
 this.printButton.Location = new System.Drawing.Point(12, 51);           
 this.printButton.Size = new System.Drawing.Size(75, 23);  
 this.printButton.Text = "Print"; 
 this.printButton.Click += new
 	System.EventHandler(this.printButton_Click);  
 this.ClientSize = new System.Drawing.Size(292, 266); 
 this.Controls.Add(this.printButton);
 // Associate the PrintPage event handler with the PrintPage event.          
 printDocument1.PrintPage += new
 PrintPageEventHandler(printDocument1_PrintPage);
}
 
 private void ReadFile() {
   string docName = "testPage.txt";
   string docPath = @"c:\";   
   printDocument1.DocumentName = docName;   
   using (FileStream stream = new 
    FileStream(docPath + docName, FileMode.Open))            
 
  using (StreamReader reader = new StreamReader(stream))  {
       stringToPrint = reader.ReadToEnd();          
  } 
 }
private void printDocument1_PrintPage(object sender,PrintPageEventArgs e)
 {
    int charactersOnPage = 0;
     int linesPerPage = 0;
// Sets the value of charactersOnPage to the number of characters          
 // of stringToPrint that will fit within the bounds of the page.   
    e.Graphics.MeasureString(stringToPrint, this.Font,  
    e.MarginBounds.Size, StringFormat.GenericTypographic, 
           out charactersOnPage, out linesPerPage); 
           // Draws the string within the bounds of the page 
  e.Graphics.DrawString(stringToPrint, this.Font, Brushes.Black, 
               e.MarginBounds, StringFormat.GenericTypographic);  
          // Remove the portion of the string that has been printed.  
          stringToPrint = stringToPrint.Substring(charactersOnPage);
            // Check to see if more pages are to be printed. 
           e.HasMorePages = (stringToPrint.Length > 0);        }    
 
private void printButton_Click(object sender, EventArgs e)
{
   ReadFile();      
   printDocument1.Print();        
} 
       [STAThread]     
static void Main(){  
  Application.EnableVisualStyles();  
  Application.SetCompatibleTextRenderingDefault(false); 
  Application.Run(new Form1());
}    
}
}
 
fuente:

http://msdn2.microsoft.com/es-es/library/cwbe712d.aspx

Cadenas de conexion

¿Aquien no le ha pasado el tener una base de datos y no saber como conectarse a ella?

Lo reconozco a mi el primero, y sin ir muy lejos el otro dia cuando mi jefe me dijo, este "archivo access por odbc", ¡¡Que marron!! ¡¡ Yo siempre lo habia hecho por OleDB!! y mirando y mirando por internet encontre la solución que es la que os pongo aqui, y ya de paso os planteo varias cadena de conexion a otras BBDD.

 

Por cierto si quereis alguna cadena mas, o si sabeis alguna otra cadena de conexio... pues escribirmela y o... pedirmela e intentare hacer lo que pueda. Ah si alguna no funciona tambien, asi la pruebo y la quito

 

Un abrazo:

Microsoft Access

 

Conecta a una base de datos de tipo Access mediante OleDB

  Dim path_Bd As String      path_Bd = App.Path & "\Nombre.mdb"   
 cnn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & "Data Source=" & _ 
  path_Bd & ";" & "User Id=admin;Password=" 

 

Conecta a una base de datos Microsoft Access mediante ODBC. Sin password y sin contraseña

  cnn.Open "driver={Microsoft Access Driver (*.mdb)};" & _ 
         "dbq=c:\LaBase.mdb;uid=admin;pwd="
 

Conecta mediante ODBC en modo exclusivo

  cnn.open "Driver={Microsoft Access Driver (*.mdb)};" & _  
        "Dbq=C:\Labase.mdb;Exclusive=1;Uid=admin;Pwd=;" 

 

Para .net mediante OleDB y con Password

    cnn.open "Provider=Microsoft.Jet.OLEDB.4.0;" & _ 
           "Data Source=C:\LaBase.mdb;" & _ 
           "Jet OLEDB:Database Password=Password;" 

 

Conecta a una base de datos Microsoft Access mediante OLEDB, usando un Grupo de trabajo

  Dim path_Bd As String  path_Bd = App.Path & "\Nombre.mdb"
cnn.Open "Provider=Microsoft.Jet.OLEDB.4.0;
Data Source=" & path_Bd & ";" & _
 "Jet OLEDB:System Database=c:\Archivo.mdw", "User", "Password" 

 

Igual al anterior pero usando ODBC

  Dim path_Bd As String  path_Bd = "c:\carpta\LaBase.mdb"
 cnn.Open "driver={Microsoft Access Driver (*.mdb)};" & _
"dbq=" & path_Bd & ";" & _
 "systemdb=c:\Archivo.mdw;", _ 
   "usuario", " password " 

Microsoft Sql Server

 

Cadena de conexión usando OLEDB

 cnn.Open "Provider=sqloledb;" & _    
"Data Source=Nombre_del_Servidor;" & _ 
"Initial Catalog=Nombre_de_la_base;" & _ 
"User Id=USUARIO;Password=PASSWORD" 

 

Usando ODBC

  cnn.Open "driver={SQL Server};" & _     
 "server=NOMBRE_DEL_SERVIDOR;database=LA_BASE;uid=USUARIO;pwd=PASSWORD" 

 


MySql

A un servidor MySql Server mediante OLEDB en .NET

  cnn.Open "Provider=MySQLProv;" & "Data Source=base;" & _   
       "User Id=USUARIO;Password=PASSWORD" 

A una base Mysql remota mediante ODBC

  cnn.Open "Driver={MySQL ODBC 3.51 Driver};" & _   
       "Server=data.domain.com;" & _  
        "Port=3306;Database=LaBase;" & _  
        "User=USUARIO;Password=PASSWORD;Option=3;" 

 

Base de datos local mediante ODBC

  cnn.Open "Driver={MySQL ODBC 3.51 Driver};Server=localhost;" & _ 
         "Database=LaBase;User=Usuario;Password=Password;Option=3;"
 

Cadenas de conexión para conectar a Microsoft Excel

 

A un archivo Excel mediante OLEDB

  conexion.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
                "Data Source=" & path_Bd & _
                ";Extended Properties=""Excel 8.0;HDR=Yes;""" 
 A Excel Mediante ODBC
  cnn.Open "driver={Microsoft Excel Driver (*.xls)};" & _  
 "driverid=790;dbq=c:\libro.xls;" & _  
        "defaultdir=c:\lacarpeta" 

 


ConnectionString para archivos de texto ( txt, Csv etc..)

 

ODBC

   cnn.Open "DRIVER={Microsoft Text Driver (*.txt; *.csv)};" 
& _ "DBQ=" & App.Path & ";", "", ""

'Ejemplo para cargar un recordset

'El archivo de texto en la cláusula From
rs.Open "select * from [ElArchivo#txt]", conn, adOpenStatic, _ 
     adLockReadOnly, adCmdText 

 

Mediante OLEDB

 cnn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _ 
 "Data Source=Path_De_La_carpeta;" & _ 
        "Extended Properties=""text;HDR=Yes;FMT=Delimited"""   
  rst.Open "select * from ElArchivo.csv", cnn, _    
      adOpenStatic, adLockReadOnly, adCmdText 


FoxPro - Dbf

 

Conectar por ODBC

  Coneccion = "Driver={Microsoft dBASE Driver (*.dbf)};" & _
              "DriverID=277;Dbq=c:\Path_de_carpeta;"
 

OLEDB

  Connection = "Provider=Microsoft.Jet.OLEDB.4.0;" & _ 
              "Data Source=c:\La_Carpeta;" & _  
             "Extended Properties=dBASE IV;" & _  
             "User ID=Admin;Password=;" 

 

 

Fuente de: http://www.recursosvisualbasic.com.ar/htm/trucos-codigofuente-visual-basic/296-connectionstring-ado.htm

Alertas en ASP.NET en el codebehind

Lo prometido es deuda y como le dije en el primer post. hoy voy a colgar una solución par indicar como se ponen alertas y mensajes de confirmación en .net

 

Porque... a ver seamos sinceros, cuantas veces en nuestras web creamos botones que haces insert, update o delete sin avisar al usuario, es decir el tipico mensaje ese de... "¿Esta seguro que quiere eliminar?". Que si que muchas veces es muy pesado... y sobre todo cuando luego te sale otro de "¿Pero seguro? Mira que despues no se va a podre recuperar..."

 

Pues eso, si quieres dar la vara al usuario y poner ventantas de confirmacion lo puedes hacer de esta manera:

 

Button1Attributes.Add("onclick", " if (!confirm('Se va a borrar la categor¡a, ¨Esta seguro?')){return false};");

Esto añadelo an el On_Load de tu pagina, y ya esta si el cliente pulsa aceptar se ejecuta el metodo por defecto si no devuelve false, y no hace nada

 

Bueno si otro sabe alguna otra forma le invito a ponerla,  pero si no espero que haya servido de algo a alguien.

 

Un saludo y hasta otra...

Para empezar no esta mal

   Siempre he tenido ganas de empezar un diario, si algo donde contar mi vida, pero como mi vida era muy triste (igual que la de todos, no penseis nada del tipo infancia dificil) y un diario no lo lee ni el Tato, ni siquiera mi colega el Pichu, que se tira varias horas en la web.

Pues eso, resumiendo que ya era hora que empezara algo chulo, a contar cosas que interesen a la gente, como cosas de tecnologia, cosas que encuentre y cosas curiosas sobre DotNet, y los DotNetClubs.

 

Se aceptan criticas constructivas, y tambien, sugerencias mejores que las que propongo, total, como dice mi titulo, soy un informatico en expansión

¿Mi nombre? Fer

 

Un abrazo a todos!!!

Albergado en:blogspot.es

Noticias: Noticias

Contador gratis contadorplus.com