OnDeserialized/OnSerialized Attributes

In .NET we can serialize and deserialize objects for saving state from memory to storage or for transfering complex structures through the Internet.
DataContractAttribute and SerializableAttribute are the options that we have to achieve this goal. The basic differences between them are that DataContract is WCF technology and Serialization is older than DataContract. A great feature of DataContract is that it can serialize private fields. (FYI : In Windows Phone it cannot)
Private fields or private properties or non-serializable fields could be a problem for us. Fortunately, we have OnDeserializedAttribute / OnDeserializingAttribute and OnSerializedAttribute / OnSerializingAttribute that when applied to a method, specifies that the method is called immediately after / during  deserialization or serialization of an object.
Here, there are the examples from MSDN


[OnSerializing()] internal void OnSerializingMethod(StreamingContext context) {

member2 = "This value went into the data file during serialization.";

}

[OnSerialized()] internal void OnSerializedMethod(StreamingContext context) {

member2 = "This value was reset after serialization.";

}

[OnDeserializing()] internal void OnDeserializingMethod(StreamingContext context) {

member3 = "This value was set during deserialization";

}

[OnDeserialized()] internal void OnDeserializedMethod(StreamingContext context) {

member4 = "This value was set after deserialization.";

}

More information

OnDeserializingAttribute Class

OnDeserializedAttribute Class

OnSerializingAttribute Class

OnSerializedAttribute Class

System.Runtime error en WP8 y librerías portables

Un caso raro es cuando usamos librerías portables y Microsoft.Bcl no da un error de compilación System.Runtime. En un primer momento no tenemos muy claro de que se trata y tampoco nos da ninguna pista de que puede ser.

Después de buscar y buscar resulta ser un bug de NuGet en que te pone una redirección en el archivo app.config

 

<dependentAssembly>

<assemblyIdentity name=”System.Runtime” publicKeyToken=”b03f5f7f11d50a3a” culture=”neutral” />

        <bindingRedirect oldVersion=”0.0.0.0-2.6.3.0″ newVersion=”2.6.3.0″ />

</dependentAssembly>

 

De modo que debes eliminar esa línea para que todo funcione correctamente otra vez.

<dependentAssembly>

<assemblyIdentity name=”System.Runtime” publicKeyToken=”b03f5f7f11d50a3a” culture=”neutral” />

</dependentAssembly>

Ajax i download file

descarga

Amb .Net utilitzar Ajax és super senzill, tant sols hem de col·locar un control UpdatePanel i tota la resta és el mateix.

Però hi ha un cas que no deixa de ser curiós. Quan un postback retorna una cadena binaria que representa un fitxer els UpdatePanels fan que no funcioni adequadament. Normal, hem de tenir present que els UpdatePanel serveixen perquè el contingut del seu interior s’actualitzi i no pas per descarregar fitxers. Hi hi algunes tècniques que ho poden fer però no deixa de ser alternatives sobre les eines que disposes.

Una de les maneres més senzilles és dir-l’hi a l’UpdatePanel que al accionar el botó de descarrega executi un Postback enlloc de un AsyncPostback. Per això té el triggers, per assignar controls de la pàgina per tal de que provoquin un postback complet de la pàgina.

Però en el cas de tenir un ListView o qualsevol altre control que encapsuli controls la unica manera és fer-ho des de codi. Però els update panels no els hi agrada massa que els hi toquis els triggers per codi. Que no et fa cas vaja.

Llavors ens queda una opció que per mi és molt fina i neta. Utilitzar ScriptManager per indicar que l’event click del botó es fagi per Postback i no pas per AsyncPostback
ScriptManager.GetCurrent(this.Page).RegisterPostBackControl(this.lnkDownload);

Posa aquest tros de codi en l’event DataBound del teu control ListView. Fàcil i funciona.

 

Més informació:

Download feature not working within update panel in asp.net

Simple way to do File download with UpdatePanel and overlay ProgressIndicator

 

Añadir eventos propios en controles y que generen postback

descarga

El otro día trabajando en un proyecto con Sharepoint necesité capturar eventos que existen en el control HTML y que no se capturan des de servidor como por ejemplo la perdida del foco en el control (onBlur). Buscando como podía hacerlo me encontré con estas páginas que explican como crear controles que puedan capturar el evento onBlur en questión. Pero que además ya puedes exportarlo a poder crear cualquier otro tipo de evento que ahora no se captura. Me ha sorprendido lo senzillo que es.

Consultalo tu mismo:

Extending the asp.net textbox to have an OnBlur server side event.

ASP.NET TextBox LostFocus event

Entity Framework Complex Type i ADO.NET Data Services

Dues tecnologies molt interessant en opinió meva i molt utils per un ràpid desenvolupament que et permeti poder crear serveis amb accés a bases de dades.

Entity Framework ens permet mapejar les bases de dades en entitats per tal de que podem aplicar LINQ per poder consultar els valors de la base de dades. També ens permet poder gestionar la base de dades sense entrar per res en llenguatge natiu de la base de dades.

Amb EF sovint trobem la necessitat de tenir Complex Types ja sigui perquè volem tenir una estructura auxiliar dins el nostre entorn o perquè important un Stored Procedure de la base de dades aquesta com a sortida té una estructura complexa.

ADO.NET Data Services ens permet poder crear serveis WCF simples que estan orientats a les dades i no pas als mètodes. Aquests serveis es configuren per un EF i per tant és en el client del servei que s’utilitza els contexte creat per poder accedir a les dades com si estiguessin en local.

Però de moment sembla ser que els Complex Types tenen un problema de compatibilitat i no es poden utilitzar per ADO.NET Data Services. Per tant qualsevol Stored Procedure o Web Method que poguem tenir dins el servei no actuarà correctament.

El problema és unicament al moment de serialitzar l’estructura i per tant una manera de solucionar-ho seria tu mateix recorrer a una serialització pròpia.

L’altre és crear un servei WCF normal que puguis consultar aquest tipus de informació.

És per això que ADO.NET Data Services està orientat a les dades i no pas als mètodes com si el servei WCF.

Per més informació:

The closed type does not have a corresponding element settable property

EF4: The closed type ‘xxxx’ does not have a corresponding element settable property

Issues with using Silverlight 4, WCF Data Service Service Operation with Entity Framework 4.0

Lambda

Si ja sé que es el famoso logotipo de Half-life, pero aqui de la expresión lambda de C# y VB.NET y el simbolo a parte de traerme buenos recuerdos me gusta.

Es una expresión que aparece en el .Net 3.5 que te permite indicar el tipo FUNC en una sola linea. La expresión Lambda se caracteriza por tener el símbolo “=>” en C# o Function(…) en Visual Basic.

C# 
IEnumerable<string> cincoCaracs=nombres.Where<String>(s=>s.Length==5);

Vb.Net 
cincoCaracs=nombres.Where(Function(s) s.Length=5)

La expresión lambda se lee de la siguiente manera: La parte izquierda de la expresión (entiéndase la parte izquierda de => o lo que esta entre los paréntesis de la palabra Function(…)) son las variables que vamos a utilizar y que su tipo es inferido por los tipos genéricos del FUNC. La parte derecha es la implementación necesaria para devolver el tipo expresado como tipo de retorno en el FUNC. Por tanto, según el ejemplo, Where necesita un Func que devuelva un boolean (s.Length=5) y un parámetro que viene determinado por el genérico (en el caso de C#) o por los elementos de la lista en el caso de Visual Basic aunque no sea siempre así (“s” es tipo String) En .Net 3.5 las expresiones lambda solo podían tener una linea de implementación. En .Net 4 ya pueden tener más de una tal y como puedes ver en el siguiente ejemplo:

C# 

lista.Where<int>(c=>
{
  var x = c + 3;
  x = x * 4;
  return x==3;
 }).Select<int,int>(c=>c);

Vb.Net 

lista.Where(Function(c)
  Dim x = c + 3
  x = x * 4
  Return x = 3
 End Function).Select(Of Integer)(Function(c) c)

Entiendo y así me ocurre en todos los cursos que cuesta un poco entenderlo a primer vista, pero ten en cuenta que es muy fácil, lo único que necesitas es practicarlo un poco, yo te pongo unos ejemplos para que te ayuden a practicar.

C# 

//Buscar los enteros que sean mayor a tres
lista.Where<int>(c=>c>3);

//Buscar los mayores a tres ordenados de mayor a menor
lista.Where<int>(c=>c>3).OrderByDescending<int,int>(c=>c);

//De la lista de enteros recuperar otra lista con un tipo personalizado
lista.Select<int,ElEntero>(c=>new ElEntero {ElValor=c});

//De la lista de enteros recuperar otra lista con un tipo anónimo
lista.Select(c=>new {ElValor=c});

Vb.Net 

//Buscar los enteros que sean mayor a tres
lista.Where(Function(c) c>3)

//Buscar los mayores a tres ordenados de mayor a menor
lista.Where(Function(c) c>3).OrderByDescending(Of Integer)(Function(c) c)

//De la lista de enteros recuperar otra lista con un tipo personalizado
lista.Select(Of ElEntero)(Function(c) new ElEntero With {.ElValor=c})

//De la lista de enteros recuperar otra lista con un tipo anónimo
lista.Select(Function(c) new With {.ElValor=c});

FUNC (El delegado genérico)

FUNC se define como un delegado que devuelve un valor y genérico.

C#
public delegate TResult Func<T,TResult>(T arg)
public delegate TResult Func<T1,T2,TResult>(T1 arg1,T2 arg2)
public delegate TResult Func<T1,T2,T3,TResult>(T1 arg1,T2 arg2,T3 arg3)
public delegate TResult Func<T1,T2,T3,T4,TResult>(T1 arg1,T2 arg2,T3 arg3,T4 arg4)
public delegate TResult Func<TResult>()

Vb.Net
Public Delegate Function Func(Of T,TResult)(arg as T) As TResult
Public Delegate Function Func(Of T1,T2,TResult)(arg1 as T1,arg2 as T2) As TResult
Public Delegate Function Func(Of T1,T2,T3,TResult)(arg1 as T1,arg2 as T2,arg3 as T3) As TResult Public Delegate Function Func(Of T1,T2,T3,T4,TResult)              (arg1 as T1,arg2 as T2,arg3 as T3,arg4 as T4)              As TResult Public Delegate Function Func(Of TResult)              ()              As TResult

Tal y como puedes ver en las definiciones siempre se sigue la misma regla: El ultimo tipo declarado en el genérico es el tipo devuelto por la función que implemente este delegado. Muchas de los métodos LINQ que extienden toman como parámetro un FUNC. Como por ejemplo:

C#
Where<TSource>(Func<TSource,bool> predicate)
Where<TSource>(Func<TSource,int,bool> predicate)
Select<TSource,TResult>(Func<TSource,int,TResult> selector)
Select<TSource,TResult>(Func<TSource,TResult> selector)

Vb.Net
Where(predicate as Func(Of TSource, Boolean))
Where(predicate as Func(Of TSource, Integer, Boolean))
Select(Of TResult)(selector as Func(Of TSource,Integer,TResult))
Select(Of TResult)(selector as Func(Of TSource,TResult))

Para poder utilizar este tipo de métodos con esos parámetros debes crear primero la función que implementa el FUNC, para ello debes crear una función con la misma signatura que el definido por el FUNC.

C# 
Func<string,bool> filtro=delegate (string s)
{
   return s.Length==5;
}
IEnumerable<string> cincoCaracs=nombres.Where<String>(filtro);

Vb.Net 
Function FiltroCaracs(i As String) As Boolean        
  Return i.Length=5
End Function
Dim filtro as Func(Of String,Boolean) filtro = AddressOf FiltroCaracs
Dim cincoCaracs as IEnumerable(Of String) cincoCaracs=nombres.Where(filtro)

En el siguiente post vas a ver como puedes indicar un tipo FUNC más fácilmente.

LINQ como extensión de método

Ya he hablado de las extensiones de método y ya sabes como se crean. LINQ es una extensión de método de un IEnumerable. Eso significa que dentro de una clase que implemente un IEnumerable existe el método Where, OrdeBy y Select. Estos métodos y otros son extensiones de método que hacen LINQ. Miralo con un ejemplo:

C#
IEnumerable<Customer> customquery =
    from cust in customers
    where (cust.City == “London” && cust.Balance > 500)
    select cust;
Vb.Net
Dim customquery as IEnumerable(Of Customer)
customquery =
    From cust In customers
    Where (cust.City = “London” and cust.Balance > 500)
    Select cust

Es lo mismo que:

C#
IEnumerable<Customer> customquery =
    customers.Where<Customer>(c=>c.City==”London” && c.Balance > 500 ).Select<Customer>(c=>c);
Vb.Net
Dim customquery as IEnumerable(Of Customer)
customquery = customers.Where(Function(c) c.City=”London” and c.Balance > 500).Select(Function(c) c)

Aunque a primera vista parece que todo se complica mucho no lo es, lo único que tienes que entender es que es un FUNC y la expresión Lambda. Después verás que es muy, pero que muy fácil.

En otro post te voy a explicar los FUNC.

Empezamos con LINQ

Explicadas algunas de las novedades en los lenguajes en la versión 3.0 del Framework

Inicialización de objetos, Tipos inferidos, Tipos anonimos, Extensión de métodos

ya podemos mirarnos una sentencia LINQ y comprenderla paso a paso.

C#
var customquery =
from cust in customers
where (cust.City == “London” && cust.Balance > 500)
orderby cust.Balance descending
select new {Details=cust.Name + “:” + cust.Phone,
cust.Balance};
foreach(var custItem in customerQuery){
  Console.WriteLine(custItem.Details);
  Console.WriteLine(custItem.Balance);
}

Vb.Net
Dim customquery =
From cust In customers
Where (cust.City = “London” and cust.Balance > 500)
Order By cust.Balance Descending
Select new With {Details=cust.Name + “:” + cust.Phone,
cust.Balance}
For Each custItem In customerQuery
  Console.WriteLine(custItem.Details)
  Console.WriteLine(custItem.Balance)
Next

LINQ es la instrucción que empieza por From y termina en Select y como puedes ver es una sintaxis muy parecida a SQL estándard y su objetivo es buscar o filtrar listas de elementos. Más adelante verás que las listas no tienen porque ser colecciones en memoria, también pueden ser bases de datos.

Desmontando la sentencia

  • customquery : Tipo inferido por el resultado de la instrucción LINQ. En este caso un IEnumerable de un tipo anónimo tal y como puedes ver en la parte del Select.
  • cust : tipo inferido por los elementos de la colección customers. En el ejemplo se puede deducir que es algún tipo Customer.
  • Where : Expresión booleana para determinar que elementos queremos
  • Order By : Determina el orden en el resultado
  • Select : Tipo que queremos devolver en la instrucción LINQ. En este caso se trata de un tipo anónimo. No es necesario siempre devolver tipos anónimos, fijate que una instrucción como la siguiente devuelve los mismos elementos de la lista ordenados.
C#
var customquery =
from cust in customers
orderby cust.Balance descending
select cust;

Vb.Net
Dim customquery =
From cust In customers
Order By cust.Balance Descending
Select cust

Donde se aplica LINQ
LINQ es una extensión de método de la interfaz IEnumerable, por tanto, podemos aplicar LINQ en todas las colecciones que implementen esta interfaz que son prácticamente todas.

Que devuelve LINQ
Toda expresión LINQ devuelve un IEnumerable genérico, es decir un IEnumerable<T>, con una excepción, si devolvemos tipos anónimos entonces seria un IEnumerable de anónimos, pero como no puedo declarar una variable de ese tipo se trata con var o Dim tal y como has visto en el primer ejemplo. Ahora puedes ver como definimos el tipo devuelto en el segundo ejemplo:

C#
IEnumerable<Customer> customquery =
from cust in customers
orderby cust.Balance descending
select cust;

Vb.Net
Dim customquery as IEnumerable(Of Customer)
customquery =
From cust In customers
Order By cust.Balance Descending
Select cust

Extensión de métodos

Las extensiones de métodos nos permiten añadir funciones o métodos en tipos ya existentes.

C#
namespace StringExtensionMethodStringExtensionMethods{
 public static class Extension{
  public static int CountWords(this string s){
   return s.Split(new Char() {" "c,"."c).Lenght;
  }
 }
}
Vb.Net
Namespace StringExtensionMethods
 public Module StringExtensions
  <Extension>
  Public Function CountWords(s as string) as Integer
   Return s.Split(new Char() {" "c,"."c).Lenght
  End Function
 End Module
End Namespace

En el ejemplo puedes comprobar como creamos un método que cuenta las palabras del string. Es un método que extiende el tipo string.
Las condiciones que se deben cumplir para crear un método de extensión son:
1. Declaración de un espacio de nombres
2. C# Clase estática / Visual Basic Modulo
3. C# Método estático / Visual Basic Método con atributo Extension
4. C# Primer parámetro con this

Sea cual sea su declaración posibilita usarlo en el tipo string tal y como puedes ver aquí:

C#
using StringExtensionMethods;
string message = "Hi there delegates"
int i = message.CountWords();
Vb.Net
Imports StringExtensionMethods
Dim message = "Hi there delegates"
Dim i = message.CountWords()