Archive for septiembre, 2015

The base class includes the field ‘X’, but its type is not compatible

Si recibimos el error siguiente después de copiar nuestra web precompilada a nuestro directorio virtual donde tenemos la aplicación:

The base class includes the field ‘XXXXX’, but its type
(XXXXXXX) is not compatible with the type of control
(ASP.XXXXXX_ascx).

Es decir, hay un control de usuario que da error, sin embargo, en local nos funcionaba.
Pasa porque la caché no se ha borrado, se sigue haciendo referencia en algún sitio a una dll temporal anticuada.

SOLUCIÓN:

La mejor opción para que ni siquiera olamos este error es utilizar la opción de Build Website, y si no, borremos antes de pegar el nuevo contenido.
¿Por qué Build Website?
Esta opción te pregunta si existen archivos, y si es así, antes de copiar a la carpeta lo borra todo:

Añade el archivo app_offline ( para ver más sobre app_offline, mira mi artículo sobre el temaEste enlace abre una nueva ventana), mientras se genera la web:

Cuando termina de generar la web, borra el archivo app_offline y deja sólo el resultado.

En este post, dan otras soluciones:
http://www.velocityreviews.com/forums/t91323-user-control-codebehind-type-not-compatible-with-asp-type.htmlEste enlace abre una nueva ventana

Anuncios

septiembre 25, 2015 at 3:38 pm Deja un comentario

Control Adapters en .NET 2

Los controles de .NET son una maravilla porque te facilitan la tarea de programar y ha supuesto para el concepto de programación web un antes y un después. Con .NET te olvidas casi por completo que existen los comandos Request.Form o Request.QueryString porque se ven sustituidos por los controladores de eventos.

No obstante, tienen un handicap a primera vista en la versión 1.1 e incluso en la 2, que el renderizado ya venía con el sello de fábrica Microsoft y con el marcado (HTML) que ellos han decidido. Para los que trabajamos con niveles de accesibilidad AAEste enlace abre una nueva ventana esto supone una torturaporque la doble AA por ejemplo no te permite incluir inline el width o dejar etiquetas style etc…

Entonces llega el programador listillo y dice .NET me da la posibilidad de crear un control que herede del control original de .NET , le hago un render con un override y “p’alante”. Al estilo de esto:

    public class AccessibleImageButton : System.Web.UI.WebControls.ImageButton

{

protected override void Render(HtmlTextWriter output)

{

System.Text.StringBuilder sb = new System.Text.StringBuilder();

 

System.IO.StringWriter sw = new System.IO.StringWriter(sb, System.Globalization.CultureInfo.CurrentCulture);

 

HtmlTextWriter mywriter = new HtmlTextWriter(sw);

 

base.Render(mywriter);

 

mywriter.Close();

 

sw.Close();

 

string s = sb.ToString();

 

s = s.Replace(“style=\”border-width:0px;\””, String.Empty);

 

output.Write(s);

 

}

 

 

}

Desde luego este tipo de código es totalmente válido e inevitable si además queremos añadirle funcionalidades nuevas al control. Por ejemplo, si queremos que las rutas de una imagen vaya a una carpeta determinada dependiendo si una sesión “contraste” se ha activado, y si no, a otra para imágenes normales.

Sin embargo: en .NET 2 se ha creado un nuevo mecanismo built-in y que han venido a llamar “control adapters“.
Estos controladores te permite crear, digamos, un plug-in para cualquier control de servidor, y modificarlo para cambiar su lógica de renderizado.

¿Cuál es la ventaja?
Así a bote pronto, es menos engorroso y sobre todo, se hace a un nivel global dentro de la web.

¿Cómo funcionan los control adapters?
Se utiliza un nuevo tipo de archivo de extensión “.browser” que se coloca en la carpeta “App_browsers” que hará que se produzca el override de los controles que se especifique automáticamente para todo el sitio web:

appbrowsers

El código necesario por ejemplo para reescribir el renderizado de un ImageButton sería el siguiente: Archivo “.browser” dentro de carpeta App_Browsers:

<browsers>

 

<browser refID=”Default”>

<controlAdapters>

 

<adapter controlType=”System.Web.UI.WebControls.ImageButton”

adapterType=”ImageButtonControlAdapter” />

 

</controlAdapters>

</browser>

 

</browsers>

Clase para el Adaptador que referenciamos en el “.browser” y que normalmente puede ir en App_Code pero también se puede poner en un proyecto aparte:

public class ImageButtonControlAdapter : System.Web.UI.Adapters.ControlAdapter

{

protected override void Render(System.Web.UI.HtmlTextWriter output)

{

System.Text.StringBuilder sb = new System.Text.StringBuilder();

 

System.IO.StringWriter sw = new System.IO.StringWriter(sb, System.Globalization.CultureInfo.CurrentCulture);

 

HtmlTextWriter mywriter = new HtmlTextWriter(sw);

 

base.Render(mywriter);

 

mywriter.Close();

 

sw.Close();

 

string s = sb.ToString();

 

s = s.Replace(“style=\”border-width:0px;\””, String.Empty);

 

output.Write(s);

 

}

}

 

En este caso lo que estamos haciendo es buscar un estilo que se inserta automáticamente en los ImageButton y que no podemos dejar si queremos cumplir el nivel AA de accesibilidad web.

septiembre 25, 2015 at 3:31 pm Deja un comentario

App_offline.htm

El app_offline.htm  (cuidado ni .aspx ni html): una página que colocada en la raíz de un dominio, hace que toda la web se redirija a dicho archivo.
Una forma cómoda y “unexpensive” de actualizar una web sin que uno reciba errores porque aún no se han terminado de copiar los archivos de una actualización al servidor.
http://weblogs.asp.net/scottgu/archive/2005/10/06/426755.aspxEste enlace abre una nueva ventana

septiembre 25, 2015 at 3:27 pm Deja un comentario

MaintainScrollPositionOnPostback

Muchas veces nos habremos visto en la necesidad de volver a un punto de la página después de hacer un postback para que el usuario no tuviera que utilizar el scroll lateral.

Normalmente yo suelo utilizar un focus() en javascript si se trata de un formulario y lo añado con ClientScript.RegisterClientScriptBlock. El problema es cuando no hay ningún elemento al que hacer foco (un input o textarea por lo general).

Esto funciona. Quizás no es elegante. Al mismo tiempo hay que meterlo por código y quizás no va en la filosofía de .NET de automatizar con un código además optimizado.

Actualmente esto que yo hacía por código en .NET se haría con <control >: .Focus().

No obstante, puede optimizarse más, y para eso viene en nuestra ayuda el atributo MaintainScrollPositionOnPostback que podemos añadir a la directiva Page de nuestro html. Esto hará que se guarde la posición exacta en píxeles en unos hidden y se restaurará automáticamente mediante javascript.

Con esto se genera lo siguiente en el html:

<input type=”hidden” name=”__SCROLLPOSITIONX” id=”__SCROLLPOSITIONX” value=”0″ />

<input type=”hidden” name=”__SCROLLPOSITIONY” id=”__SCROLLPOSITIONY” value=”257″ />

theForm.oldSubmit = theForm.submit;

theForm.submit = WebForm_SaveScrollPositionSubmit;

theForm.oldOnSubmit = theForm.onsubmit;

theForm.onsubmit = WebForm_SaveScrollPositionOnSubmit;

theForm.oldOnLoad = window.onload;

window.onload = WebForm_RestoreScrollPosition;

// –>

Si queréis alternar el comportamiento de la página para que a veces lo haga y otras no, en vez de desactivar este comportamiento, Scott Mitchell nos lo explica para que funcione a las mil:
http://aspnet.4guysfromrolla.com/articles/111407-1.aspxEste enlace abre una nueva ventana

septiembre 25, 2015 at 3:26 pm Deja un comentario

DropDownList y AppendDataBoundItems

Ejemplo:
<asp:DropDownList ID=”ddlSector” runat=”server” ></asp:DropDownList>

Partimos de un DropDownList, ahora queremos poblar un DataSource con datos de una base de datos (utilizo una colección List por simplificar, lo óptimo es una colección propia del objeto que estemos tratando):
List<string> list=new List<string>();
list=getSectores();

El problema que se nos plantea es que queremos que la opción “Selecciona sector” aparezca en primer lugar.

Hay 2 maneras:

1.-AppendDataBoundItems es la fácil, lo que haremos es lo siguiente
<asp:DropDownList ID=”ddlSector” runat=”server” AppendDataBoundItems=”true”>
<asp:ListItem Value=”0″ Text=”Selecciona un sector”></asp:ListItem>
</asp:DropDownList>

Si no colocamos el atributo AppendDataBoundItems, al hacer DataBind, el valor inicial se borrará.

2.-Podremos insertar el elemento dentro de la lista que hemos poblado de datos:
list.Insert(0,”Selecciona Sector”);
Y después hacerle el DataBound.

septiembre 25, 2015 at 3:25 pm Deja un comentario

DropDownlist and InitialValue

He visto muchas veces implementar una lógica innecesaria para validar un DropDownList para que sea válido el valor si no es igual al valor 0 que normalmente pertenece a la opción del selectbox: “Selecciona una opción”.
Por ejemplo he visto esto:
<asp:CustomValidator ID=”ctvDdlCampo” runat=”server” ControlToValidate=”ddlTCampo” OnServerValidate=”ctvDdlCampo_ServerValidate”></asp:CustomValidator>

Y en el método ctvDdlCampo_ServerValidate implementar lo siguiente:
public void ctvDdlTipoNoticia_ServerValidate(object sender, ServerValidateEventArgs e)
{
if (ddlAgrupaciones.SelectedIndex > 0)
{

}}

Se hace así porque nos hemos saltado una solución más elegante.
En fin ¿cómo lo hubiéramos hecho? simplemente con un RequiredFieldValidator que indique el atributo InitialValue a 0 que es el valor del “Selecciona campo”:

<asp:RequiredFieldValidator ID=”rfvddlCampo” runat=”server”

ControlToValidate=”ddlCampo” InitialValue=”0″></asp:RequiredField>

septiembre 25, 2015 at 3:24 pm Deja un comentario

Subdominios, dominios y sesiones

Para aquellos a los que manejáis sesiones entre dominios y subdominios, existe un problema con .NET y asp, las sesiones propias del lenguaje, es decir, las establecidas con el objeto Session se realizan utilizando el dominio o subdominio en el que se crea la sesión.
Hasta ahí parece todo bien, pero en realidad, esto provoca que por ejemplo prueba.midominio.com y http://www.dominio.com tengan sesiones diferentes. Si por ejemplo, para hacer búsquedas enviara a un usuario logeado a search.midominio.com, perdería la sesión.
Afortunadamente los colegas de Redmond han pensado en ello, para compartir el mismo dominio entre ambos subdominios, tenemos que indicarle bajo qué dominio se van a crear las sesiones así:

Response.Cookies[“ASP.NET_SessionId”].Value = Session.SessionID;

Response.Cookies[“ASP.NET_SessionId”].Domain = “midominio.com”;

septiembre 25, 2015 at 3:22 pm Deja un comentario

Entradas antiguas


Categorías

septiembre 2015
L M X J V S D
« Ene    
 123456
78910111213
14151617181920
21222324252627
282930  

Entradas recientes

Mis links en del.icio.us

Feeds