[TIP] Renderizando una Vista Parcial dentro de un WebForm

Introducción

Actualmente estoy en un proyecto donde están conviviendo formularios Web (tradicionales WebForms) y vistas de MVC (de ahí mi primera entrada de ayer).

Bien, mi problema ha venido al tener distintas MasterPages (como es comprensible) para los WebForms y para las Vistas, por eso de que implementan una página base distinta.

Bueno en definitiva el problema era para usar el mismo menú sin tener que rescribir el código de la vista parcial.

Solución

Dentro de la vista de mi WebForm, he definido un contenedor div, y gracias a jQuery he renderizado el contenido de mi menú dentro de dicho div.

<script type="text/javascript">
                   $(document).ready(function() {
                       var uri = '/Menu/Menu';//Está es la url donde se encuentra mi Vista parcial con el menu.
                       $.get(uri, function(data) {
                           $("#menu").append(data);
                       });
                   });
</script>    

El porqué de una vista parcial para el menú, vendrá en el siguiente post donde voy a explicar como definir un menú de manera dinámica con una tabla en BD.

Saludos

[Tip Rápido] Convivencia de WebForms dentro de MVC.

 

Introducción

En este pequeño post, vamos a ver un pequeño consejo rápido para ver como dentro de un mismo proyecto ASP.NET pueden coincidir páginas WebForms tradicionales con las Vistas de MVC.

Al Jaleo

Bien, el “truco” consiste en definir una ruta a ignorar dentro de nuestra tabla de rutas (en el fichero Global.asax) dentro de la función “RegisterRoutes”:

routes.IgnoreRoute("Carpeta");

De está manera todas los formularios Web existentes dentro de dicha “Carpeta”, no van a intentar ser mapeados dentro de la tabla de rutas de nuestra App.

 

Espero que os sea de utilidad.

 

Saludos

[Básico]Enumerados con tipo distinto de Int

Introducción:

En este post vamos a ver como utilizar otros tipos de datos numéricos dentro de una enumeración.

Si bien, no es un problema que nos vayamos a encontrar a menudo, pero que podamos realizarlo si lo necesitamos.

Al lio:

A la hora de definir nuestro enumerado tendremos que indicar uno de los siguientes valores:

– Byte

– SByte

– Short

– UShort

– Long

– ULong

– UInt

Ejemplo:

   1: public enum MyLongEnum  :long    

   2: {

   3:     Value = 1569874585236L

   4: }

Para que posteriormente podamos utilizar dicho valor desde nuestro código será necesario hacer una conversión:

   1: var myValue = (long)MyLongEnum.Value;

Espero que os sea de utilidad.

 

Saludos!

WinRT: Establecer un estilo Condicional (2) #Metro #Win8

Introducción

Ayer publique una entrada en la que hablaba de aplicar un estilo condicional a un control en xaml.

Después de  revisar si se puede utilizar StyleSelector o DataTemplateSelector, ambos son válidos a aplicar para un control como el ListBox, pero no por ejemplo para un TextBox o un TextBlock.

Código V2:

Dandole una pequeña vuelta de tuerca, y a pesar que me sigue pareciendo un “Bad Code Smell”, me he creado un nuevo converter:

   1: public class BooleanStyleConverter : IValueConverter

   2: {

   3:  

   4:     public object Convert(object value, Type targetType, object parameter, string language)

   5:     {

   6:         var page = new MyXamlPage();

   7:  

   8:         return ((bool)value ? page.Resources["StyleA"] as Style : page.Resources["StyleB"] as Style);

   9:     }

  10:  

  11:     public object ConvertBack(object value, Type targetType, object parameter, string language)

  12:     {

  13:         throw new NotImplementedException();

  14:     }

  15: }

En el converter se define la pagina donde se encuentran los estilos, y nuestro control, y a través del diccionario de recursos devolvemos un estilo según nuestro condicionante.

Su aplicación en  código:

1) Definir el converter en los recursos:

   1: <converters:BooleanStyleConverter x:Name="GenderConverter"/>

2) Definir nuestro control con su Binding y Converter:

   1: <TextBlock Text="{Binding Child.Name}" Style="{Binding Child.Gender,Converter={StaticResource GenderConverter}}" />

Espero que os sea de utilidad, o si veis alguna opción mejor, lo comenteis Open-mouthed smile

 

Saludos!

WinRT: Establecer un estilo Condicional #Metro #Win8

Introducción

Estoy realizando una pequeña app para Windows8 con WinRT y Metro.

Pese a que no soy ningun experto en WPF, creo que condicionar el estilo a un elemento de Binding era algo trivial en WPF o Silverlight, en WinRT, (espero que de momento) no lo es.

Solución que hemos hablado por Twitter

En una conversación mantenida con @Antiocool y con @CorsarioVasco, hablabamos de definir 2 bloques de texto, uno para cada estilo (puesto que el condicional era para un booleano) y cada uno tuviera el estilo correspondiente. Y jugar con la visibilidad del segundo con respecto de la visibilidad del primero. Pese a que es un poco “BADSMELL”, de momento es la “única” solución rápida que he encontrado.

1) Partiendo de un Converter BooleanToVisibility

   1: public class BooleanToVisibilityConverter : IValueConverter 

   2:  {

   3:      public object Convert(object value, Type targetType, object parameter, string language)

   4:      {

   5:          bool val = (bool)value;

   6:          return (val ? Visibility.Visible : Visibility.Collapsed);

   7:            

   8:      }

   9:  

  10:      public object ConvertBack(object value, Type targetType, object parameter, string language)

  11:      {

  12:          var val = (Visibility)value;

  13:          return (val == Visibility.Visible);

  14:      }

  15:  }

2) Definiremos un Visibility Inverter Converter:

   1: public class VisibilityInverterConverter : IValueConverter 

   2:     {

   3:         public object Convert(object value, Type targetType, object parameter, string language)

   4:         {

   5:             return ((Visibility)value == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible);

   6:         }

   7:  

   8:         public object ConvertBack(object value, Type targetType, object parameter, string language)

   9:         {

  10:             return ((Visibility)value == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible);

  11:         }

  12:     }

3) Escribiremos el xaml necesario para utilizarlo:

3.1) Definimos los converters como recursos:

   1: <UserControl.Resources>

   2:        

   3:        <!-- TODO: Delete this line if the key AppName is declared in App.xaml -->

   4:        <converters:BooleanToVisibilityConverter x:Name="BooleanConverter"/>

   5:        <converters:VisibilityInverterConverter x:Name="VisibilityConverter"/>

   6:    </UserControl.Resources>

   7: </UserControl.Resources>

3.2) Definimos los bindings necesarios:

   1: <TextBlock x:Name="tName" 

   2:     Text="{Binding Child.Name}" 

   3:     Visibility="{Binding Child.Gender,

   4:                 Converter={StaticResource BooleanConverter}}" 

   5:                 Grid.Row="0" Grid.ColumnSpan="3" 

   6:                 Style="{StaticResource ChildNameStyle}" d:LayoutOverrides="Margin"/>

   7: <TextBlock Text="{Binding Child.Name}" 

   8:             Visibility="{Binding ElementName=tName, 

   9:             Path=Visibility,Converter={StaticResource VisibilityConverter}}"

  10:              Grid.Row="0" Grid.ColumnSpan="3" 

  11:             Style="{StaticResource ChildNameStyleGirl}" d:LayoutOverrides="Margin"/>

  12:   

Como se puede observar cada TextBlock tiene el mismo texto asignado, y cambia el estilo.

La propiedad Visivility del segundo TextBlock está asignada a la misma propiedad del primer TextBlock aplicando el converter que hemos definido previamente.

 

Espero que os sea de utilidad y/o si conoceis otra alternativa, por favor comentarla!.

 

Saludos!!

Win8: Serializar y Deserializar con WinRT C#

Introducción

En este breve post vamos a ver como llevar a cabo la serialización de objetos dentro de una aplicación metro con WinRT y C#.

Código

Partiendo de una clase tipo:

 

   1: public class Employee

   2: {

   3:     public int Id { get; set; }

   4:     public string FirstName { get; set; }

   5:     public string LastName { get; set; }

   6:     public DateTime BirthDate { get; set; }

   7: }

Serializando un objeto:

   1: Employee obj;

   2: using (var fileStream = await ApplicationData.Current.RoamingFolder.OpenStreamForWriteAsync(String.Format("ci{0}{1}.xml",

   3:  obj.LastName, obj.FirstName), 

   4:                     CreationCollisionOption.ReplaceExisting))

   5:                 {

   6:                     var serializer = new XmlSerializer(typeof(ChildInfo));

   7:                     serializer.Serialize(fileStream, obj);

   8:                 }

Deserializando un objeto:

   1: Employee obj;

   2: sing(var fileStream = await ApplicationData.Current.RoamingFolder.OpenStreamForReadAsync(root))

   3:  

   4:    XmlSerializer serializer=new XmlSerializer(typeof(Employee));

   5:    obj = (Employee)serializer.Deserialize(fileStream);

Espero que os sirva.

 

Saludos!

MVC: Trabajando con campos con etiquetas HTML

Introducción:

En este post vamos a ver como trabajar con un modelo donde una de nuestras propiedades va a almacenar valores de tipo HTML, como por ejemplo el contenido del post de un blog:

   1: <p>Este el texto del post, con un enlace <a href='http://bing.com'>bing</a></p>

Abordando el problema:

Partiendo de un modelo sencillo:

   1: public class Post

   2: {

   3:     public Guid ID { get; set; }

   4:     public string Title { get; set; }

   5:     public string Content { get; set; }

   6: }

donde nuestra propiedad “Content” va a ser la que va almacenar el código HTML vamos a cualificarla con el atributo AllowHtml, para que en el momento de grabar nuestros post desde el explorador, permitirá evitar la validación de dicho campo sin tener que comprobar las etiquetas HTML introducidas en él.

Posteriormente para poder visualizar nuestro HTML con el formato HTML, vamos a hacer uso del método Raw del Helper HTML, por lo que el contenido de nuestra vista quedaría:

   1: @foreach (var c in Model)

   2: {

   3:     <article>

   4:         <h1>@c.Title</h1>

   5:         @Html.Raw(@c.Content)

   6:     </article> 

   7: }

 

Espero que os sea de utilidad.

Saludos!!

Convertir un IEnumerable<T> a DataTable

Introducción

En este post vamos a ver como llevar a cabo la exportación de un objeto IEnumerable<T> a un DataTable. Pero, espera!!! Ya existe un método extensor CopyToDataTable, que parece realizar esta acción.

Todo parece que sí, pero parece demasiado bonito. Si nos fijamos en la firma del método:

   1: public static DataTable CopyToDataTable<T>(

   2:     this IEnumerable<T> source

   3: )

   4: where T : DataRow

Veremos que este método, solo lo podremos utilizar en el caso de que T sea de tipo DataRow o implemente a DataRow.

Bueno, el porque del post es debido a una preguntaba que lanzó ayer en Twitter @Zpektrum, sobre porque no podía utilizar dicho método con una consulta Linq.

Código:

Para ilustrar el ejemplo vamos a ver una query linq contra un DataTable:

   1: var query = from t in dt1.AsEnumerable()

   2:                         select new

   3:                         {

   4:                             ID = t.Field<string>("ID"),

   5:                             Nombre = t.Field<string>("Name")

   6:                         };

Como podeís apreciar estamos realizando una consulta sobre las filas de la tabla dt1, y escogiendo las columnas ID y Nombre. El resultado de esta consulta va a devolver un IEnumerable<T> donde T va a ser un tipo anónimo, por lo que dicho tipo no va a ser DataRow y no vamos a tener disponible el método CopyToDataTable.

Bien, para construir nuestro nuevo método extensor, tendremos que definir una nueva clase estática y un método estático que retorne un objeto de Tipo DataTable, y haremos que el método sea genérico.

   1: public static class IEnumerableExtensions

   2:     {

   3:         public static DataTable CopyAnonymusToDataTable<T>(this IEnumerable<T> info)

   4:         {

   5:             var type = typeof(T);

   6:             if (type.Equals(typeof(DataRow))) 

   7:                 return (info as IEnumerable<DataRow>).CopyToDataTable();

   8:             DataTable dt = new DataTable();

   9:             DataRow r;

  10:             type.GetProperties().ToList().ForEach(a=>  dt.Columns.Add(a.Name));

  11:             foreach (var c in info)

  12:             {

  13:                 r = dt.NewRow();

  14:                 c.GetType().GetProperties().ToList().ForEach(a => r[a.Name] = a.GetValue(c,null));

  15:                 dt.Rows.Add(r);

  16:             }

  17:             return dt;

  18:         }

  19:         

  20:     }

Para que el método sea un método extensor es necesario que sea estático, que este contenido en una clase estática y que su primer parámetro tenga el modificador “this” y el tipo que va a extender.

Explicando el método:

El método es sencillo, en primer lugar comprobamos que si el tipo de T es DataRow que ejecute el método CopyToDataTable ya existente.

En caso contrario, a través de reflectión obtendremos las propiedades del Tipo T, e iremos definiendo nuevas columnas con el nombre de dichas propiedades en la tabla resultante.

Por último, iteraremos sobre el contenido de la colección e iremos agregando las filas para devolverlos.

Ejecución del método:

Continuando con el ejemplo anterior:

   1: var query = (from t in dt1.AsEnumerable()

   2:                         select new

   3:                         {

   4:                             ID = t.Field<string>("ID"),

   5:                             Nombre = t.Field<string>("Name")

   6:                         }).CopyAnonymusToDataTable();

De está manera query, será de tipo DataTable y ya podremos manejar dicha tabla a nuestro gusto.

 

Un saludo y espero que os sea de utilidad.

Usando Enumeraciones en Entity Framework 5.0

Introducción

Es bastante probable que en alguna de las tablas de vuestras bases de datos tengas alguna propiedad de tipo Integer para representar una clave ajena de una tabla que no suele cambiar.

¿Por qué no utilizar una enumeración en lugar de otra tabla en la Base de Datos?

Bien, con Entity Framework 5.0 Beta 1 podemos hacer uso de enumeraciones en nuestras entidades sin tener que hacer ninguna chapuza. Esta versión es para VS11 con .NET 4.5. El trabajo con Enums ya se pudo probar con una CTP que salio en Junio de 2011 con Database First y Model First, pero no con Code First.

En este post vamos a ver como realizarlo en los distintos enfoques existentes.

 

Database First y Model First

Ya que Database First y Model First son dos enfoques muy similares vamos a tratarlos en común.

Para empezar:

1) Definiremos un nuevo proyecto, por ejemplo: una aplicación de consola.

2) Agregaremos nuestro Entity Data Model indicando nuestra Base de Datos y tablas.

3) Dentro del explorador del modelo de nuestro diagrama, veremos una nueva carpeta “Enum Types”. Pulsaremos con el botón secundario del ratón, y elegiremos la opción “Add Enum Type”. Configuraremos las características: Nombre, tipo de dato, y los miembros:

 

 

4) Asignación de la enumeración a una propiedad escalar: Desde la ventana de propiedades

 

Code First

Para usarlo seguiremos estos pasos:

1) Definiremos nuestra enumeración:

   1: public enum Category

   2: {

   3:     Technology,

   4:     Computer,

   5:     Games

   6: }

2) Definiremos nuestra entidad:

   1: public class Products

   2: {

   3:     public int Id {get;set;}

   4:     public string Name {get;set;}

   5:     public Category Category {get;set;}

   6: }

3) Incluiremos la colección en nuestro contexto:

   1: public class Context : DbContext

   2: {

   3:     public DbSet<Product> Products {get;set;}

   4: }

4) En el momento de la definición de la Base de Datos va a definir una columna llamada Category de tipo Integer en nuestra Base de Datos.

 

Haciendo Consultas

Como las enumeraciones no estaban soportadas en versiones anteriores para poder utilizar la enumeración teniamos que obtener el código que nos interesaba.

En esta nueva versión podremos realizar la siguiente consulta:

   1: var query = context.Products.Where(a=> a.Category == Category.Games);

 

Saludos!

[TIP] Exportar Word a PDF desde Código

Mini artículo para exportar un fichero word a PDF desde código c# y VB.NET.

Al Lio

Para poder trabajar con documentos de Word en nuestro código es necesario que agreguemos la referencia “Microsoft.Office.Interop.Word.dll”.

Sin mas dilación el código:

VB.NET

   1: Dim app As New Microsoft.Office.Interop.Word.Application()

   2:  

   3:         Dim missing As Object = System.Type.Missing

   4:         Try

   5:  

   6:                 Dim document As Microsoft.Office.Interop.Word.Document = app.Documents.Open(RutaCarta)

   7:                 Dim nombre As String = String.Format("{0}TEMPName.doc", Application.StartupPath)

   8:  

   9:                 app.Visible = False

  10:                 

  11:                 app.ActiveDocument.ExportAsFixedFormat(String.Format("{0}Name.pdf", Application.StartupPath), & _

  12:                      Microsoft.Office.Interop.Word.WdExportFormat.wdExportFormatPDF, False, & _

  13:                         Microsoft.Office.Interop.Word.WdExportOptimizeFor.wdExportOptimizeForPrint, & _

  14:                     Microsoft.Office.Interop.Word.WdExportRange.wdExportAllDocument)

  15:                 document.Close()

  16:    

  17:         Catch ex As Exception

  18: 'Manejar la excepción....

  19:         Finally

  20:  

  21:             app.Quit()

  22:  

  23:         End Try

 

C#

 

   1: var app = New Microsoft.Office.Interop.Word.Application()

   2: var missing = System.Type.Missing

   3: try

   4: {

   5:     var document = app.Documents.Open(RutaCarta);

   6:     string nombre = String.Format("{0}TEMPName.doc", Application.StartupPath);

   7:     app.Visible = false;

   8:                 

   9:        app.ActiveDocument.ExportAsFixedFormat(String.Format("{0}Name.pdf", Application.StartupPath), 

  10:                      Microsoft.Office.Interop.Word.WdExportFormat.wdExportFormatPDF, False, 

  11:                         Microsoft.Office.Interop.Word.WdExportOptimizeFor.wdExportOptimizeForPrint, 

  12:                     Microsoft.Office.Interop.Word.WdExportRange.wdExportAllDocument);

  13:                 document.Close();

  14: }

  15: catch(Exception ex)

  16: {

  17: 'Manejar la excepción....

  18:  }

  19: finally

  20: {

  21:     app.Quit();

  22: }

Gracias al método ExportAsFixedFormat, podremos exportar nuestro fichero Word a formato PDF o XPS…

…PERO!!!:

Podremos encontrarnos una excepción que nos dirá algo así: “Esta funcionalidad no está instalada.”.

Para poder ejecutar de forma correcta este código, necesitamos instalar un addin de Office.

 

Espero que os sea de utilidad.

 

Saludos!!!