Archivo de la etiqueta: ASP.NET

Posts relacionados con la tecnología de sitios y aplicaciones Web de .NET Framework

Detectar por código C# o Visual Basic si una página ASP.NET se muestra en un móvil

Pues eso… aunque he leído por ahí que no es conveniente detectar si se está navegando en un dispositivo móvil… eso era porque lo hacía con código duro (hard-code) es decir, detectar según el valor devuelto por userAgent de window.navigator, que sí, que puede producir resultados no deseados… pero… si usas Request.Browser.IsMobileDevice la cosa cambia.

Y hacer esa comprobación es bien simple.
¿Dónde hacerla?
En cualquier parte del código «script» de tu página ASP.NET (de .NET Framework), ya sea que estés usando Visual Basic o C# (o incluso otros lenguajes que soporten las páginas web asp.net de .net framework).

Un par de ejemplos, por favor

Esta es una página .aspx con código para C#:

<%@ Page Language="C#" AutoEventWireup="true" %>

<script runat="server">
    protected void Page_Load(object sender, EventArgs e)
    {
        if (Request.Browser.IsMobileDevice)
        {
            LabelDesktop.Visible = false;
            LabelMobile.Visible = true;
        }
        else
        {
            LabelDesktop.Visible = true;
            LabelMobile.Visible = false;
        }
    }
</script>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body style="font-family:Consolas">
    <form id="form1" runat="server">
        <div>
            <asp:Label runat="server" ID="LabelMobile"  Visible="false"
                Font-Size="xx-Large" Font-Bold="true"
                Text="Estas viendo esto en el navegador de un dispositivo móvil." />
            <asp:Label runat="server" ID="LabelDesktop"  Visible="false"
                Font-Size="xx-Large" Font-Bold="true"
                Text="Estas viendo esto en el navegador de escritorio." />
        </div>
    </form>
</body>
</html>

Esta es una página .aspx con código para Visual Basic:

<%@ Page Language="VB" AutoEventWireup="true"  %>

<script runat="server">
    Protected Sub Page_Load(sender As Object, e As EventArgs)
        If Request.Browser.IsMobileDevice Then
            LabelDesktop.Visible = False
            LabelMobile.Visible = True
        Else
            LabelDesktop.Visible = True
            LabelMobile.Visible = False
        End If
    End Sub
</script>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body style="font-family:Consolas">
    <form id="form1" runat="server">
        <div>
            <asp:Label runat="server" ID="LabelMobile"  Visible="false"
                Font-Size="xx-Large" Font-Bold="true"
                Text="Estas viendo esto en el navegador de un dispositivo móvil." />
            <asp:Label runat="server" ID="LabelDesktop"  Visible="false"
                Font-Size="xx-Large" Font-Bold="true"
                Text="Estas viendo esto en el navegador de escritorio." />
        </div>
    </form>
</body>
</html>

Nota:
Puedes tener las dos páginas en una misma aplicación o proyecto WEB de Visual Studio sin necesidad de hacer nada especial, solo tener las páginas en un sitio que acepte .NET Framework.

A tener en cuenta

Si muestras la páginas en un dispositivo móvil, es posible que el navegador te permita ver la página como «escritorio», en ese caso, el valor que devuelve es escritorio, no que es móvil.
En las siguientes capturas tienes la demostración.
En esas capturas estoy usando el Edge para Android en un Google Pixel 4a.

En la figura 1 estoy mostrando la página versión de Visual Basic en el móvil, que si quieres la puedes probar usando el enlace mostrado (está alojada en mi sitio: elguille.info/WebFormVB.aspx).

Figura 1.

 

En la figura 2 te muestro la versión para C# antes de cambiarla a modo escritorio.
También puedes probarla usando este enlace en mi sitio: elguille.info/WebFormCS.aspx.

Figura 2. Mostrando la página como móvil y queriendo cambiar a versión para ordenador

 

Figura 3. Mostrando la página como si estuviese en escritorio y queriendo cambiar a versión apra sitio móvil.

 

Nota:
También puedes probarlo en el navegador de escritorio usando las herramientas de desarrollador, que en Edge y Chrome se pueden acceder usando Ctrl+Shift+I.
Y desde esas herramientas puedes indicar que se muestre como si fuese en un móvil (ver la figura 4).

Figura 4. Usando las herramientas de desarrollador puedes ver en el escritorio cómo sería usarlo en un móvil… o casi.

Espero que te sea de utilidad 😉

Nos vemos.
Guillermo

Acceder a la página maestra (Master page) desde una página en ASP.NET para .NET Framework (con C# y VB)

Pues eso… el otro día estaba escribiendo código para un nuevo sitio web de un colega (ConservasYoga.com.es) y me decidí a hacerlo en C# , por aquello de que creía que ya no existen plantillas (o eso creo ) en Visual Studio 2019 para ASP.NET con Visual Basic, pero sí existen, de las que no existen es para usar ASP.NET Core.

La cuestión es que quería acceder a ciertas propiedades (y/o métodos) de la master page y lo hice (o lo intenté) tal como lo hago con Visual Basic, es decir, usando Master.Propiedad, pero nada… daba error… después de muchas pruebas lo conseguí… algo rebuscado, pero… probando, probando… lo pude encontrar, y es que en C# para acceder a las cosas definidas en una página maestra hay que usar el nombre de la página maestra (en minúsculas) seguida de un guón bajo y la palabra master (también en minúsculas), es decir, si la página maestra se llama Site.master para acceder al código desde C# hay que usarlo de esta forma: site_master.

Un ejemplo de sitio usando Master Page en VB y C#

Para este ejemplo he optado por seleccionar un sitio en blanco: ASP.NET Empty Web Site (ver figura 1), ya que si se elige el tipo ASP.NET Web Forms Site te añade un montón de código y página, etc., que… en los hosting de ASP.NET que hay por esta zona no funcionan… y si intento que sea de ASP.NET Core ya ni te digo, ninguna de las empresas de hosting con las que he probado (Axarnet, IONOS, acens) lo soportan, incluso una de ellas me dijo que como es código abierto por eso no lo soportan… pero sí venden servidores con Linux, WordPress, PHP… que… ¡lo mismo no son de código abierto! 😉

En fin…

Figura 1. Crear un nuevo proyecto de C# (Empty Web Site)

Cuando trabajo con sitios de ASP.NET no me gusta usar el code behind, si no que prefiero que cada página tenga su código, de esa forma no es necesario compilar la aplicación, si no que se usa el código directamente en el sitio hospedado y ya está… el ASP.NET de IIS se encarga de compilar las páginas y el código a usar. Y lo mejor es que si haces cambios, solo tienes que subir la página o el fichero de código modificado y ya está… ¡a compilarlo tocan! pero… ¡que lo compile otro! 😉

En el segundo tipo de proyecto todo lo que añade el Visual Studio usa el code behind, mientras que en el proyecto vacío, cuando añadas una nueva página (maestra o normal) puedes indicar que no se incluya el código de forma separada (que es lo que viene a significar el code behind o separación entre el diseño y el código).

Si elegimos añadir una nueva página con el código incrustado en la propia página tendremos que hacer algo como lo mostrado en la figura 2.

Figura 2. Añadir nueva página con el código separado de la página aspx

En ese caso, se indica también seleccionar una página maestra para esa página aspx.

Y si decidimos que el código esté separado lo haremos como se muestra en la figura 3.

Figura 3. Nueva página con el código en la propia página.

Es decir, quitamos la marca de la casilla Place code in separate file.

Al añadir una página de esa forma tendremos esto en la página:

<% @ Page Title="" Language="VB" MasterPageFile="~/MasterPage.master" AutoEventWireup="false" 
    CodeFile="Prueba.aspx.vb" Inherits="Prueba" %>

Donde CodeFile indica qué página es la que tiene el código y el Inherits es el nombre de la clase.

Si esto lo has hecho por error… puedes arreglarlo.
¿Cómo?
Simplemente quitando todo lo que se indica en CodeFile y en Inherits y poniendo el código aparte, tal como te muestro a continuación:

<% @ Page Title="" Language="C#" MasterPageFile="~/MasterPage.master"  %>

<script runat="server">

</script>

Nota:
Por cierto, esa página la he añadido al proyecto de C#, pero está usando el código de VB, y es porque yo, por error, he seleccionado una página de Visual Basic (tal como ves en la figura 3).
Pero en el código mostrado lo he cambiado a C#.

Decir o aclarar que en un sitio web hecho con ASP.NET para .NET Framework podemos usar tanto código de VB como de C#, aunque no revueltos.

En este sitio que he creado, en el proyecto de C# uso una página con código de VB y otras dos con el código de C#.

En la página maestre he definido una propiedad con el título de la aplicación.
En C# quedaría de esta forma:

<script runat="server">

    public static string AppName { get; set; } = "Web Site Master C#";

</script>

En la de Visual Basic, esa misma propiedad la definimos como te muestro a continuación:

<script runat="server">

    Public Shared Property AppName As String = "Web Site Master VB"

</script>

Como es una propiedad compartida, en C# se utiliza static y en VB se usa Shared.

Y para usarla desde C# lo haríamos de esta forma, por ejemplo para poner el título de la página 2:

<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
    <h2>Prueba2 en C# para <%= masterpage_master.AppName  %> </h2>
</asp:Content>

Como dije al principio, en VB podemos usar Master para acceder al código de la página maestra, en C# no sepuede.
Lo que también se puede en VB es usar la clase de la página maestra, es decir, tal como se hace en C#.
Decirte que esto último hará que en VB no te muestre un warning que sí muestra cuando se accede a la página maestra usando Master (ver la figura 4).

Nota:
No sé porque ahora me muestra ese warning, ya que siempre lo he usado así (con Master.Propiedad) y nunca había salido esa advertencia, pero bueno… si queremos compatibilidad entre los dos lenguajes, podemos hacerlo usando el nombre de la clase.

Figura 4. Desde C# no se puede usar Master si no el nombre de la clase de la página maestra

Resumiendo el acceso a las páginas maestras desde código

Mejor usar el nombre de la clase, tanto en C# (que es la única forma de ahcerlo, al menos que yo sepa) como en VB.

Te iba a comentar que, aparte de lo que ya hemos visto, desde un sitio web de asp.net con .NET Framework se puede usar tanto código de VB y de C# en conjunto, solo hay que poner dicho código en carpetas diferentes e indicarlo en el fichero Web.Config.

Esto ya lo expliqué cuando salió ASP.NET 2.0 y por tanto las páginas maestras.
Este es el enlace en elguille.info: Usar clases de VB y C# en una misma aplicación Web.

Pero te lo resumo brevemente.

Usar código de VB y C# en un mismo sitio de ASP.NET Framework

Crea la carpeta de código App_Code, decide qué lenguaje será el que use las clases puestas en esa carpeta (normalmente el lenguaje con el que has creado el proyecto), crea una nueva carpeta (dentro de App_Code) para poner las clases del otro lenguaje.

Por ejemplo, si queremos que en la carpeta App_Code estén las clases de VB y en la carpeta c-sharp (App_Code\c-sharp), pondremos esto en el fichero web.config:

<compilation debug="true" strict="true" explicit="true" targetFramework="4.7">
    <codeSubDirectories>
        <add directoryName="c-sharp" />
    </codeSubDirectories>
 </compilation>

Este código estará dentro de la rama: <configuration><system.web>.

Para acceder a las clases o el código se hace de la forma habitual, en este ejemplo, he definido una propiedad estática/compartida para que se pueda acceder desde el código ASP.

Hay que tener en cuenta que C# distingue entre mayúsculas y minúculas, mientras que a VB le da igual como la escribamos.

<p>Usando el código definido en la carpeta <b>App_Code</b></p>
<p>Acceso al código de C# (class1.Nombre):  <% = Class1.Nombre  %> </p>
<p>Acceso al código de VB (class2.Nombre): <% = Class2.Nombre %> </p>
<p>En C# hay que usar correctamente el nombre: Class1 y Class2 (no class1/class2 como en VB).</p>

Y esto es todo… este es el código en GitHub por si le quieres echar un vistazo.

 

 

Cambios en el código de C# para que compile con C# 5.0

Al limpiar el proyecto de los «packages» que añade el Visual Studio, empiezan los errores, uno de ellos es que C# 5.0 no permite asignar valores a las auto-propiedades, por tanto, el código mostrado antes hay que sustituirlo por este otro:

El de la clase Class1.cs: (tanto en el proyecto de VB como en el de C#)

public static string Nombre 
{ 
    get { return "¡Hola Mundo de C#!"; }
} 

El de la página maestra:

<script runat="server">

    public static string AppName 
    { 
        get {return "Web Site Master C#"; } 
    }

</script>

El código de VB no hay que modificarlo, se ve que el compilador usado reconoce la autodefinición de propiedades con asignación de valores.

En el código de GuitHub ya está rectificado.

Nos vemos.
Guillermo

Cómo enviar cambios de línea usando mailto (html/script)

Pues eso… llevo unos días creando un nuevo sitio usando ASP.NET (con C#) para un colega al que le ayudo a vender sus productos por internet (Conservas Yoga) y probando el envío de emails desde el sitio usando una cuenta de gmail, me ha estado dando problemas y al final no he conseguido que funcione, no creo que sea por los permisos de gmail, ya que en la aplicación de gsNotasNET.Android me ha estado funcionando bien (o en su día en foros.elguille.info, pero en este nuevo sitio no había forma… así que… he hecho lo que suelo hacer cuando las cosas no funcionan: ¡cortar por lo sano y usar lo que siempre funciona!

Y lo que siempre funciona es usar mailto para enviar mensajes.

¿Cómo indicar el asunto al usar mailto?

Una de las cosas que siempre he usado es indicar el asunto cuando se pulse en el enlace de mailto (ahora te muestro el código), en ese caso, lo que hay que hacer es indicar un parámetro con la palabra clave subject el signo igual e indicar el texto del asunto.

Según desde que navegador se use habrá que indicar de forma distinta los espacios en el asunto, normalmente la forma más segura de hacerlo (válido para todos los navegadores, más viejos o más recientes) es usar %20 (equivalente en valor hexadecimal a un espacio).

Pero como te digo puedes usarlo con espacios y casi siempre funciona.

El código para enviar un email a la cuenta tuemail2021@gmail.com con el asunto «Comentario desde el guille mola» sería el siguiente:

Pulsa en este enlace para enviar un mensaje con el asunto: Comentario desde el guille mola.

El código de esa línea sería el siguiente:

<p>Pulsa en este enlace para enviar un mensaje con el asunto: 
    <a href="mailto:tuemail2021@gmail.com?Subject=Comentario desde el guille mola">
        Comentario desde el guille mola</a>.</p>

Si quisieras asegurarte de que no dará problemas, puedes cambiar los espacios por %20, pero creo que así debería funcionar (si no pruebas y te da error o algún mensaje fuera de lo común, por favor lo comentas en la sección de comentarios de este post, gracias).

Y ahora vamos a la parte principal de este artículo… Sí, podría haber empezado por aquí, pero… antes había que sentar los precedentes 😉

¿Cómo indicar el cuerpo del mensaje usando mailto?

Esto ya lo había hecho yo antes, pero el otro día necesitaba añadir cambios de líneas al texto del cuerpo del mensaje y no daba con la forma de hacerlo… menos mal que en internet siempre hay alguien que te lo explica 😉

En mi caso fue en este sitio: HTML mailto link.

Y el truco para añadir cambios de línea es (ahora parece tan obvio) usar los códigos de cambio de línea (LF o Line Feed) y retorno de carro (CR o Carriage Return) cuyos valores en decimal son: LF = 10, CR = 13, que en hexadecimal son: x0A y x0D, por tanto añadiendo esos valores en cada cambio de línea (normalmente se hace al revés, primero el CR y después el LF, pero creo que dará lo mismo).

Así que… si queremos usar el asunto del ejemplo anterior y queremos poner el siguiente mensaje (el body del email):

Hola Guille, perdón Tu Email 2021,

Este mensaje es una prueba desde post del blog.

¡Hasta la próxima!
<Indica tu nombre>

El enlace sería este: Enviar un mensaje con el texto arriba indicado.

El código quedaría de la siguiente forma:

<p>El enlace sería este: <strong>
    <a href="mailto:tuemail2021@gmail.com?Subject=Comentario desde el guille mola
        &Body=Hola Guille, perdón Tu Email 2021,%0D%0A%0D%0AEste mensaje es una prueba desde post del blog.%0D%0A%0D%0A¡Hasta la próxima!%0D%0A---Indica tu nombre---
        Enviar un mensaje con el texto arriba indicado</a></strong>.</p>

Nota:
Hay que tener cuidado con los editores de sitios WEB, como este de WordPress, ya que para indicar el asunto se hace con ? (?Subject=) después del nombre de la cuenta de correo (el ? es porque es el primer parámetro) y el cuerpo se usa con &Body=, es decir, cada parámetro o argumento que no sea el primero debe indicarse con el signo & (ampersand). Y los editores de código HTML lo sulen cambaiar pro &amp; (de ampersand).
Así que… si al pulsar en el enlace anterior no funciona, es que el editor de WordPress lo ha modificado… pero creo que aún así, seguirá funcionando.

Es decir, para usar el asunto se indica co ?Subject= y para indicar el cuerpo o texto del mensaje se hace con &Body=.

Si inviertes el orden, primero indicas el Body y después el Subject, la cosa quedaría así:
?Body=Cuerpo del mensaje%0D%0ACon cambio de línea.&Subject=Asunto del mensaje.

Si pulsas en este enlace, el orden está invertido (tal como muestro arriba).

Y ya solo nos queda repasar lo comentado:

Recordando que en Subject y Body dan igual las mayúsculas o minúsculas.

  1. Para indicar el asunto se usa Subject (o subject)
  2. Para indicar el cuerpo (o texto) del mensaje se usa Body (o body)
  3. Para indicar espacios tanto en el asunto como en el texto del mensaje puedes usar %20
  4. Para indicar cambios de líneas (normalmente en el cuerpo del mensaje) usa: %0D%0A

Y esto es todo… espero que te sea de utilidad… y si no te sirve, al menos a mí me servirá algún día (ya que seguro que me olvidaré de este truco si pasa un tiempo sin usarlo).

Nos vemos.
Guillermo

Asignar el foco a un control al cargar una página web aspx (ampliación y recapitulación)

Pues eso… que lo de "ampliación" es por no poner "revisited" o algo similar que eso ya está muy visto, jeje y lo de "recapitulación" por el chasco/descubrimiento/formas diferentes de funcionar con el que me he encontrado al hacer pruebas en VB y en C#, ya verás, ya…

Pero en realidad esto es una aclaración o más bien un añadido (o ampliación) del otro artículo que publiqué el pasado 11 de octubre sobre este mismo tema, es decir, cómo asignar el foco a un control al cargar una página web aspx, en ese caso el código era con Visual Basic .NET pero lo importante no era el código si no lo explicado, es decir la forma de conseguir eso que indica el título.

La aclaración es porque en ese ejemplo el código y el diseño está todo en un mismo fichero (archivo) en lugar de tener el código por un lado y el diseño por otro, que es como el Visual Studio se empeña que lo hagamos, aunque en mi caso particular me gusta más (o prefiero) tener todo junto, ya que así es más fácil de actualizar la página en concreto, al menos para mí, que todo puede ser que a tí te venga mejor compilar el código y publicarlo cada vez que hagas una modificación por pequeña que sea… ¡hay gustos para todo! 😉

 

Vamos a lo que vamos.

Si utilizas el código por separado del diseño de la página web entonces no es necesario asignar un valor true a la propiedad AutoEventWireup, ese valor verdadero sólo debes asignarlo si el código a usar está "incrustado" en la página web ASPX y no en un fichero separado (el cual hay que compilar y publicar en el sitio web).

 

La forma de indicar si tienes el código "incrustado" o por separado es usando (lo que se llama "code behind"), esto lo puedes indicar al crear un nuevo fichero en el proyecto web tal como puedes ver en la figura 1 en la que he resaltado la parte que le indica a Visual Studio si quieres usar el código en un fichero separado o no (en este ejemplo SI se usa por separado).

orden_tabulacion_fig1
Figura 1. Indicar si queremos el código por separado o no

 

Esto creará dos ficheros uno con la extensión .aspx (el diseño de la página web) y otro con la extensión del lenguaje usado, en este ejemplo al indicar que el código es de C# la extensión del fichero de código es: .aspx.cs.

En este caso, el código de "enfoque" del control que queremos que sea el primero en recibir el foco lo pondremos dentro del evento Page_Load tal como podemos ver en los dos listados (el del diseñador y el código).
(Ver el comentario de la nota).

 

Listado 1 (el código del diseñador .aspx):

 

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default3.aspx.cs" Inherits="Default3" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Default3 - con el código por separado (en C#)</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
        <asp:TextBox ID="TextBox1" runat="server">uno</asp:TextBox><br />
        <asp:Label ID="Label2" runat="server" Text="Label"></asp:Label>
        <asp:TextBox ID="TextBox2" runat="server">dos</asp:TextBox><br />
        <asp:Label ID="Label3" runat="server" Text="Label"></asp:Label>
        <asp:TextBox ID="TextBox3" runat="server">tres</asp:TextBox><br />
        <asp:Button ID="Button1" runat="server" Text="Button" />    
    </div>
    </form>
</body>
</html>

 

Listado 2 (el código de C# .aspx.cs):

 

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class Default3 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        this.TextBox1.Focus();
    }

 

 

Nota:

Es curioso, pero al hacer la prueba con C# para "demostrar" todo esto que estoy explicando, si no uso un valor verdadero (true) en la propiedad AutoEventWireup de la página de C# no se ejecuta ese código del evento Page_Load, sin embargo (de ahí lo de curioso) en el código de Visual Basic da igual el valor que tenga esa propiedad… ¡jum!

 

 

Conclusión:

Que no tengo ni idea de por qué pasa esto con una página de C#… así que… sigue usando AutoEventWireup = "true" y así seguro que siempre te funciona…

Como te he dicho antes (en la nota) en Visual Basic .NET si va bien, uses true o false en AutoEventWireup, eso sí, siempre que el código esté por separado, si el código está en la misma página, si hay que indicar el valor true.

En cualquier caso, lo cierto es que al añadir la página de C# el valor de la propiedad AutoEventWireup tiene el valor true, mientras que en Visual Basic es false.

Todo esto (no solo que el valor sea verdadero/falso) es otra demostración de que a los de Visual Basic nos tratan de forma diferente…

En fin…

 

Espero que te sea de utilidad.

 

Nos vemos.

Guillermo

El inherit de los CSS no funciona igual en todos los navegadores

Pues eso… o al menos en el Internet Explorer y el Chrome que son los que suelo utilizar en mi portátil… (en el móvil utilizo el Opera Mini).
Al menos en lo que al ancho (width) se refiere.

No me voy a enrollar pero te explico brevemente:

Tengo una serie de estilos (tanto en ficheros CSS como en bloques <style>) y en algunos de ellos simplemente quiero "heredar" el ancho que ya está previamente definido en otro de los estilos, por tanto, simplemente utilizo esto:

width: inherit;

Y supuestamente debería utilizar el ancho "heredado" es decir, el que tenga el bloque (normalmente un <div>) que contiene al que le aplico el nuevo estilo (para algunas páginas en concreto), pero resulta que no es así…

Con Internet Explorer se muestra bien, pero cuando utilizo el Chrome me lo muestra mal, de hecho el ancho heredado es más grande y se "sale" de su sitio…

Hoy me he puesto a "juguetear" con la opción que tiene el Chrome (supongo que el IE también) de "Inspeccionar elemento", que te vale para ver el "elemento" de la página web actual en la que pulsas con el ratón (mouse) y poder modificarla, de forma que puedas ver cómo quedaría con los cambios que realices.

 

Para mostrar la opción Inspeccionar elemento de Chrome:

Esto se consigue pulsando con el botón secundario del ratón (normalmente el botón derecho) sobre el "elemento" a inspeccionar de una página web.
Te muestra una ventana con el código HTML, los estilos, etc. de forma que los puedes modificar sobre la marcha y ver el resultado.

 

Lo que te decía que me he puesto a probar y al quitar esa línea de código en la que le digo width: inherit; se ha solucionado el "desborde" que tenía del div con el título en algunas partes de las páginas… en fin…

Así que… me he puesto a buscar en los ficheros de estilos (.css) y en los modificados en algunas de las páginas maestras (.master) que utilizo en mi sitio y parece ser que ya no están esos desbordes… mejor así ¿no? po ezo

 

Espero que te sea de utilidad.

Nos vemos.
Guillermo

Saber si navegamos en un móvil

Pues eso… que estoy haciendo pruebas para saber si estoy usando el código de una página Web en un móvil o no… y buscando en mi sitio me encontré con este truco de la sección de HTML:
1.- Detectar el navegador

No es el navegador lo que quiero detectar, pero sí me sirve usar el mismo "informador", es decir navigator.userAgent.

Por medio de esa propiedad podemos averiguar muchas cosas, algunas más enrevesadas que otras, y para el caso que quiero probar me sirve… aunque no al 100% ya que en realidad la comprobación que hago no es para saber si estoy usando el código en un dispositivo móvil si no en ciertos "modelos" de dispositivos móviles.

En mi caso compruebo los siguientes: Android, iPhone, iPod, iPad, BlackBerry y Symbian.

El código a usar sería algo así en JavaScript:

 

<script type="text/javascript">

    var uAg = navigator.userAgent.toLowerCase();
    var isMobile = !!uAg.match(/android|iphone|ipad|ipod|blackberry|symbianos/i);

    if (isMobile)
        document.write("navegando desde un dispositivo móvil");

</script>

 

Como puedes ver en el código se comprueban varias cadenas que suelen (o pueden) aparecer en el valor devuelto por el navegador, y esa comprobación se hace por medio de una expresión regular, sabiendo esto, si necesitas añadir más "valores" a esa comprobación, por ejemplo, para saber si es un Nokia simplemente tendrías que poner antes del "/i" el separador y la cadena a añadir en minúsculas "|nokia", haciendo eso, la cadena de comprobación quedaría de esta forma:

 

var isMobile = !!uAg.match(/android|iphone|ipad|ipod|blackberry|symbianos|nokia/i);

 

Nota:

Si a alguien se le ocurre que comprobando si está la palabra "mobile" en la cadena devuelta por navigator.userAgent, decirle que a lo mejor antes era así y puede que en muchos de los navegadores siga siendo así, pero da la casualidad que en el navegador Opera Mini que tengo en mi Samsung Galaxy S no aparece la palabra "mobile" por ningún sitio, así que… a mí no me vale.

 

Y si quieres hacer esa misma comprobación usando Visual Basic para .NET, puedes hacerlo de esta forma:

 

<%

Dim uAg As String = Request.ServerVariables("HTTP_USER_AGENT")
Dim regEx As New Regex("android|iphone|ipad|ipod|blackberry|symbianos", RegexOptions.IgnoreCase)
Dim isMobile As Boolean = regEx.IsMatch(uAg)
    
If isMobile Then
    Response.Write("navegando desde un dispositivo móvil")
End If

%>

 

Esto mismo en C# puedes hacerlo, pero en la página ASPX tendrías que indicar que estás usando código de C# y hacer una importación del espacio de nombres System.Text.RegularExpresions:

 

<%@ Page Language="C#" %> 
<%@ Import Namespace="System.Text.RegularExpressions" %>

 

Y el código para comprobar si estamos usando el navegador en un dispositivo móvil en C# será este:

 

<%
string uAg = Request.ServerVariables["HTTP_USER_AGENT"];
Regex regEx = new Regex(@"android|iphone|ipad|ipod|blackberry|symbianos", RegexOptions.IgnoreCase);
bool isMobile = regEx.IsMatch(uAg);

if(isMobile)
    Response.Write("navegando desde un dispositivo móvil");

%>

 

Nos vemos.

Guillermo

Asignar el foco a un control al cargar una página web aspx

Pues eso… que con la cabeza que tengo (se me olvidan las cosas o lo mismo mi disco duro ya está lleno, a saber) me he decidido a publicar este "truco" para ASP.NET usando páginas web ASPX, ya que hoy lo he necesitado y no me acordaba cómo había que hacerlo… o casi… ahora te explico el casi.

 

Asignar el foco a un control de una página web ASPX al cargarla

La idea es que hay que "darle el foco" al control en cuestión y aquí no vale eso de asignar un valor cero (0) a la propiedad TabIndex del control, que es lo que haríamos en una aplicación de escritorio (y casi me atrevería a decir que a una de XAML).

Otra cosa que se te puede ocurrir es asignar el foco al cargar "el formulario" (en este caso la página web), y por ahí iríamos bien… pero en el caso de las páginas web ASPX el evento Load (en realidad Page_Load) no se produce o al menos no podemos interceptarlo salvo que indiquemos en la directiva @Page que queremos hacerlo, esto lo conseguimos asignando un valor "true" a la propiedad AutoEventWireup (el valor predeterminado o por defecto, es "false").

 

Y uniendo todo lo dicho tendríamos algo así:

<%@ Page Language="vb" AutoEventWireup="true" Strict="true" %>

<!DOCTYPE html>
<script runat="server">

    ' Para que se ponga el foco en el control indicado
    ' en @Page hay que indicar AutoEventWireup="true"
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
        If IsPostBack = False Then
            txtTotal.Focus()
        End If
    End Sub
    
</script>

 

Espero que te pueda ser útil

Nos vemos.

Guillermo

P.S.

Nota del 28/Oct/2012:

Mira esta actualización que seguro que te interesa también:

Asignar el foco a un control al cargar una página web aspx (ampliación y recapitulación)

Consultado en mi sitio: Acceder al contenido de una página Web

La batallita del agüelo

Debido a que me he propuesto actualizar más a menudo este blog (mi blog) que mi sitio (elguille.info), lo que no quisiera es que la gente que visita mi sitio (por aquello de la costumbre que da todos los años que lleva funcionando o simplemente porque se lo han encontrado en Google o Bing (o como quiera que se llame el buscador de Microsoft, que ya llevan 3 nombres en menos de 5 años, así pasa lo que pasa, que la gente se lía: voy a buscar con MSN search, que no, que ahora se llama Live search, pos no estás desfasado tú, que se llama bing, pero si en la barra del Internet Explorer muestra windows live, pos que quieres que te diga, le habrán vuelto a cambiar el nombre, ya van 4 nombres en menos de 5 años y eso que sólo habré tardado en escribir este párrafo unos 2 minutos… si es que…).
A lo que iba, que si alguien entra en mi sitio, quisiera que tuviera a mano los últimos posts (entradas, artículos, cosas que he escrito, decide cómo llamar a los posts) y como en todas las páginas del blog se muestra una lista con los posts más recientes (por medio de un widget en el que yo le indico cuántos quiero que se muestren, a día de hoy se muestran 7, pero puedo poner hasta un máximo de 15), así que… mirando el código de la página generada, he pensado en extraer (aquí lo más fácil hubiera sido decir "coger", pero… no quiero que algunos de los que viven al otro lado del charco me hagan un chiste fácil… y es que los españoles no agarramos nada, lo cogemos todo, hasta la gripe la cogemos… en fin…).

Buscar un texto en una página web

Bien, sabiendo lo que quiero hacer: buscar un texto en el contenido de una página web.
Lo que necesito es: un código que haga eso.
Y eso está publicado en mi sitio publicado en Abril de 2008. concretamente en:

En particular lo que me interesa es este trozo: el mostrado en el listado 1.

Por supuesto, esto hay que modificarlo un poco, ya que lo voy a usar en una página Web.

Aunque habitualmente uso el Expression Web para editar las páginas de mi sitio (a día de hoy, estoy usando la versión 3), y con idea de no complicarme la vida (porque voy a usar código), lo que hago es abrir mi sitio web (la copia local de mi equipo) en Visual Studio 2008, de esa forma podré escribir el código de forma más sencilla que con el Expression Web, ya que el EW sabrá mucho de páginas y sitios Web, pero de Visual Basic .NET no sabe ni que existe la instrucción End.

Editar mi sitio con Visual Studio 2008

Abro mi sitio en el Visual Studio 2008 y modifico la página principal que es en la que quiero incluir esa lista de las cosas más recientes de este blog.
Me posiciono en la parte de la página que tengo para el código y pego el procedimiento del listado 1.
Por suerte, el Visual Studio 2008 detecta los fallos incluso de las páginas web como esta en la que tengo en el mismo fichero tanto la parte del código como la presentación (código HTML) y en este caso, los errores que me da es porque las clases WebRequest, WebResponse y StreamReader no están definidas, pero ya sabes que pulsando en el mismo error te da la posibilidad de arreglarlo, y en este caso es añadiendo las importaciones a los espacios de nombres System.Net y System.IO, que en código ASP.NET se hace como te muestro en el listado 2:

<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Net" %>

Listado 2

Convertir el Sub en Function y detectar errores

Como no voy a usar la función Console y lo que me interesa es obtener una cadena de texto, convierto ese procedimiento Sub en una función y hago que devuelva la cadena leída (lo que está en la variable res).

Pero como se pueden producir errores, incluyo todo el código dentro de un bloque Try/Catch de forma que si se produce un error se devuelva una cadena con el error que se ha producido, si todo va bien, se devuelve la cadena con el texto leído de la página web generada por el acceso a (en este caso) el directorio raíz del blog (el IIS ya se encarga de mandar la página HTML que corresponda).

En el listado 3 tienes esta función modificada.

Llamar a la función desde otro método

Esa función necesita que se le indique qué página queremos leer y después tendremos que leer el contenido y buscar la parte que nos interese, en mi caso, después de haber "analizado" lo que genera el blog, detecto que necesito encontrar la cadena "widget widget_recent_entries" y una vez hallada, debo tomar todo lo que haya a partir del encabezado (<H2) que le da el título a ese bloque de links. Y como es un bloque de links, deben estar incluidos entre <ul> y </ul>, por tanto necesito el trozo de cadena (que haya después de la cadena esa del widget) desde el siguiente <h2 hasta encontrarse con </ul>.

Y eso es lo que hace el código del listado 4.

En ese listado verás que se modifica el contenido de pBlogGuille, es más, lo que se hace es asignar a la propiedad InnerHtml el texto obtenido. pBlogGuille es un div que hay en la página y que, como es de esperar, contendrá los links de los artículos recientes.

La variable divBlogGuille es otro div que contiene al anterior y que lo hacemos invisible de forma predeterminada (en el código HTML) y para que resulte evidente, también al principio de este último procedimiento. De esa forma, si se produce un error o no se obtiene lo que se espera, no se mostrará nada, ya que se oculta todo el div, que por supuesto debe ejecutarse en el lado del servidor. Para que lo tengas claro, en el listado 5 tienes ese código de la página .aspx en la que está todo este código.

Llamar al método desde el evento Page_Load de la página

Finalmente tenemos que saber desde dónde llamar al método mostrado en la sección anterior, y como lo que queremos es que esos links se muestren al cargar la página, hacemos una llamada en el evento Page_Load de la página (yo ya tengo ese método de evento declarado, si no, tendría que definirlo).

Aquí simplemente hacemos la llamada al método, es decir, incluimos esto en cualquier parte de ese método de inicio:

leerUltimosBlogGuille()

Y esto es todo, espero que te sea de utilidad y si tienes dudas sobre algo de lo aquí comentado, por favor haz lo siguiente:

-Primero busca en Internet sobre lo que tienes la duda, lo más fácil es buscar en Google o en Bing escribiendo la frase completa de lo que quieres saber.

-Segundo (si buscando no encuentras lo que quieres) pregunta en los foros (ya sean los míos o los de otros, por ejemplo los de MSDN/Microsoft)

-Si después de preguntar no tienes la solución, tienta a la suerte y pregunta en este mismo hilo, pero procura que sea algo relacionado con lo explicado y como no me creeré que tengas dudas después de dar los dos pasos anteriores, tendrás que decirme qué has preguntado y cómo has buscado 😉 y adema´s debes estar registrado ene este blog… jejeje, que no, que no tienes que explicarme nada, y menos justificar que has hecho los deberes, pero procura buscar antes de preguntarme, porque seguramente yo sabré si has buscado o no, y si detecto que vas buscando lo fácil  cómodo (que otro haga tu trabajo) pues… no te digo lo que haré o diré… ¡imagínatelo!

Nos vemos.

Guillermo

P.S.

Para que todo esto sea posible (para las pruebas que he hecho) he tenido que buscar otra cosa en mi sitio: Configurar un sitio Web en local con Windows Vista


Código

Listado 1

' Acceder a una página Web usando WebRequest y WebResponse
Sub leerPaginaWeb(ByVal laUrl As String)
 
    ' Cear la solicitud de la URL.
    Dim request As WebRequest = WebRequest.Create(laUrl)
 
    ' Obtener la respuesta.
    Dim response As WebResponse = request.GetResponse()
 
    ' Abrir el stream de la respuesta recibida.
    Dim reader As New StreamReader(response.GetResponseStream())
 
    ' Leer el contenido.
    Dim res As String = reader.ReadToEnd()
 
    ' Mostrarlo.
    Console.WriteLine(res)
 
    ' Cerrar los streams abiertos.
    reader.Close()
    response.Close()
End Sub

Listado 3

' Acceder a una página Web usando WebRequest y WebResponse
Private Function strPaginaWeb(ByVal laUrl As String) As String
    Dim res As String = ""
    
    Try
        ' Cear la solicitud de la URL.
        Dim request As WebRequest = WebRequest.Create(laUrl)

        ' Obtener la respuesta.
        Dim response As WebResponse = request.GetResponse()

        ' Abrir el stream de la respuesta recibida.
        Dim reader As New StreamReader(response.GetResponseStream())

        ' Leer el contenido.
        res = reader.ReadToEnd()

        ' Mostrarlo.
        'Console.WriteLine(res)

        ' Cerrar los streams abiertos.
        reader.Close()
        response.Close()
        
    Catch ex As Exception
        res = "ERROR:<br/>" & ex.Message
    End Try
    
    Return res
End Function

Listado 4

Private Sub leerUltimosBlogGuille()
    divBlogGuille.Visible = False

    ' La URL a examinar
    Dim laUrl As String = "http://www.elguillemola.com/"
    ' Leemos el contenido
    Dim res As String = strPaginaWeb(laUrl)
    ' Salir si es una cadena vacía o dio error
    If String.IsNullOrEmpty(res) Then Exit Sub
    If res.StartsWith("ERROR:") = True Then Exit Sub
    
    ' Buscar el texto 
    Dim sTarget As String = "widget widget_recent_entries"
    ' Si la posición es -1 es que no existe ese texto
    Dim i As Integer = res.LastIndexOf(sTarget)
    If i = -1 Then Exit Sub
    
    ' El formato de lo que quiero será:
    '  <h2 con el título><ul> y los <li> con las entradas
    ' por tanto, tomar desde el <h2 hasta el siguiente </ul>
    ' y recemos porque no se aniden posts en un <li>
    Dim j, k As Integer
    ' La posición del <h2
    j = res.ToLower().IndexOf("<h2 ", i + 1)
    If j = -1 Then Exit Sub
    ' La posición del </ul>
    k = res.ToLower().IndexOf("</ul>", j + 1)
    If k = -1 Then Exit Sub
    
    ' Usar el trozo entre j y k para mostrar una lista con los posts más recientes del blog
    ' el + 5 es para los caracteres del final: </ul>
    Dim listaPosts As String = res.Substring(j, k - j + 5)
    
    ' Para probar si no se accede
    'listaPosts = ""
    
    If String.IsNullOrEmpty(listaPosts) Then Exit Sub
    
    pBlogGuille.InnerHtml = listaPosts
    divBlogGuille.Visible = True
End Sub

Listado 5

<div id="divBlogGuille" runat="server" visible="false" class="NotaClaroMargin">
<div class="tdTituloPeq"><b>En el blog www.elguillemola.com</b></div> 
<div id="pBlogGuille" runat="server"></div>
</div>
</div>