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.