Mostrando entradas con la etiqueta asp.net. Mostrar todas las entradas
Mostrando entradas con la etiqueta asp.net. Mostrar todas las entradas

miércoles, 20 de octubre de 2010

Crystal Report en ASP.NET: Se ha alcanzado el límite máximo de tareas de procesamiento de informes configuradas por el administrador del sistema

El amigo JoseMa ya encontró la solución a este problema:

"Se ha alcanzado el límite máximo de tareas de procesamiento de informes configuradas por el administrador del sistema"

En resumiendo:

a) o bien es un problema de liberar los objetos crystal que has creado, haciendo un close y un dispose en el form_unload

b) o bien, si lo del punto a) lo tienes resuelto, tu aplicación web recibe tantas peticiones simultáneas de impresión que llegas al límite de objetos crystal que el server puede tener en memoria, que son 75 por defecto. Para ampliarlo (usando vs2005):
HKEY_LOCAL_MACHINE\SOFTWARE\Crystal Decisions\10.2\Report Application Server\Server\PrintJobLimit

En el 2008 creo que cambia a
HKEY_LOCAL_MACHINE\SOFTWARE\BUSINESS OBJECTS\SUITE 12.0\REPORT APPLICATION SERVER\SERVER\Printability

viernes, 12 de febrero de 2010

Escribir en un archivo de log la cadena XML que recibe un webservice

Dim httpStream As Stream = Context.Request.InputStream

Dim longitud As Integer = httpStream.Length
Dim buffer(longitud) As Byte

httpStream.Seek(0, 0)
httpStream.Read(buffer, 0, longitud)

Dim cad As String = System.Text.ASCIIEncoding.ASCII.GetString(buffer)

Dim path As String = Server.MapPath(".") + "\log2.txt"

Dim sw As StreamWriter = New StreamWriter(path, True)
sw.WriteLine("->" & Date.Now.ToString & cad)
sw.Close()


Evidentemente debes tener permiso de escritura sobre el directorio donde quieras guardar el log.

jueves, 11 de febrero de 2010

VB y C# juntos en APP_CODE

Juntos pero no revueltos. Ese es el truco.

Si intentas tener en la carpeta APP_Code clases escritas en dos lenguajes diferentes el compilador te dice que na nay. Más concretamente, "The files 'xxx.cs' and 'xxx.vb' use a different language, which is not allowed since they need to be compiled together"

Para poder hacerlo debes ubicar el código escrito en un lenguaje en una carpeta, dejando el escrito en el otro en la raíz (o lo metes en otro directorio, lo que veas mejor). En mi caso dejo el VB en la raíz y meto las clases escritas en C# en el directorio APP_Code\APP_Code_CS. Una vez hecho esto, sólo hay que decirle al compilador que compile de manera separada la carpeta APP_Code_CS. Nos vamos al webconfig, a la sección "<compilation>" y escribimos:

<codeSubDirectories>
<add directoryName="App_Code_CS"/>
</codeSubDirectories>


Y a correr.

lunes, 6 de octubre de 2008

ASP.NET. Añadir meta "refresh" desde código

Una manera de redireccionar a otra página pasados n segundos, y poder establecer la url de manera dinámica:

En el page_load de la página inicial ponemos:

Dim urlTmp as string="nuevaPagina.aspx?id=" & _
Request.QueryString("id")

Dim mt As New HtmlMeta
mt.Attributes.Add("http-equiv", "refresh")
mt.Attributes.Add("content", "5;url=" & urlTmp)

Me.Header.Controls.Add(mt)

De esta manera, a los 5 segundos seremos redireccionados directamente a nuevaPagina.aspx, pasándole como id el mismo que tuviésemos en la página inicial.

Si nuestra página tiene masterpage, hay que usar
Me.Master.Page.Header.Controls.Add(mt)

Hale!

jueves, 24 de enero de 2008

Averiguar último identificador insertado en una tabla

Cuando en una base de datos SQL Server se inserta un campo en un tabla de tipo int y se le especifica la propiedad indentidad a Sí, en ocasiones es necesario averiguar cuál fue el último valor.

Para ello, un ejemplo vale más que mil palabras.


Dim CadenaConexion As String
Dim cmd As SqlCommand
Dim x As Integer
Dim
cnn As SqlConnection = New SqlConnection()
Dim sqlStr As
String
CadenaConexion =
ConfigurationManager.ConnectionStrings("micadenilladeconexion").ConnectionString
cnn.ConnectionString
= CadenaConexion
sqlStr = "INSERT INTO PERSONA (Nombre) VALUES (@nombre);"
& _
"SELECT @UltimoId=SCOPE_IDENTITY() FROM PERSONA"
cmd = New
SqlCommand(sqlStr, cnn)
cmd.Parameters.Add("@nombre",
SqlDbType.NVarChar).Value = "Diego"
cmd.Parameters.Add("@UltimoId",
SqlDbType.Int).Direction =
ParameterDirection.Output
cnn.Open()
Try
cmd.ExecuteScalar()
x =
CType(cmd.Parameters("@UltimoId").Value, Integer)
Response.Write("VALOR
ULTIMO ID: " & x & " <==") Catch Excepcion As Exception Throw New Exception("Error al insertar datos", Excepcion) Finally cnn.Close() End Try

martes, 18 de diciembre de 2007

Dar formato a los datos usando una clase

Lo que se pretende es poder llegar a dar formato a información usando una clase, que no instanciaremos.
Para ello se necesita que nos creemos en la carpeta App_Code de nuestro proyecto un archivo de clase que llamaremos Funciones.vb o lo que nos parezca.
El código de dicha clase:

Imports Microsoft.VisualBasic

Public Class Funciones
Public Shared Function FormatoCadena(ByVal Valor
As String, ByVal Formato As String) As String
Dim ValorFormato As
Double
Dim Cadena As String
ValorFormato = Valor
Cadena =
ValorFormato.ToString(Formato)
Return Cadena
End Function
End
Class

Esta clase podrá ser llamada sin ser instanciada desde cualquier parte del proyecto. Así si deseamos que se puede llamar desde un FormView, cómo fue el caso que a mí me ocupó, accederemos a través de la etiqueta inteligente a la plantilla donde esté el campo al que aplicaremos formato, y accederemos a través de su etiqueta inteligente a "Editar DataBinding ...".
Activaremos "Personalizar enlace" y en la expresión de código pondremos:
Funciones.FormatoCadena(Eval("Telefono1"), "### ## ## ##")

También se podría evitar poner Funciones haciendo un Imports o agregandolo convenientemente en web.config.

Páginas de ayuda con información de formatos:

http://authors.aspalliance.com/aspxtreme/sys/globalization/demos/DateTimeFormatInfoGetAllDateTimePatterns.aspx
http://msdn2.microsoft.com/es-es/library/az4se3k1(VS.80).aspx
http://msdn2.microsoft.com/es-es/library/dwhawy9k(VS.80).aspx
http://msdn2.microsoft.com/es-es/library/0c899ak8(VS.80).aspx

Nada más.

lunes, 17 de diciembre de 2007

LLamar a un procedimiento almacenado que devuelve valor a través de RETURN

Como sabemos una de las maneras de que un procedimiento almacenado de SqlServer nos devuelva un valor (entero) es usando el RETURN:

CREATE PROCEDURE nombreProc
@Parametro nvarchar(50)
AS
BEGIN
  IF EXISTS (SELECT Id from Tabla where campo=@Parametro)
    begin
      RETURN 1
    end
    else begin
      RETURN 0
    end
END

Para llamar a este procedimiento desde el .net y obtener el valor devuelto hay que crearle un parámetro específico del tipo ReturnValue, aparte de los definidos en el procedimiento:

cmd.CommandType = Data.CommandType.StoredProcedure
cmd.CommandText = "nombreProc"
cmd.Parameters.Clear()
cmd.Parameters.Add(New SqlParameter("@Parametro", "valor"))
Dim retValue As New SqlParameter("@RETURN_VALUE", Data.SqlDbType.Int)
retValue.Direction = Data.ParameterDirection.ReturnValue
cmd.Parameters.Add(retValue)
cmd.ExecuteScalar()
Dim resultado As Integer = Convert.ToInt32(retValue.Value)
If resultado = 1 Then
  ...
  ...
Else
  ...
  ...
End If

jueves, 13 de diciembre de 2007

Gridview: recuperar el índice de la fila desde un template field

Caso práctico: para cada fila de un GridView quieres poner un enlace/botón que realice cierta operación (llamémosle "pitufar") con el registro de esa fila. Sin problemas: editas las columnas del GridView y le metes un ButtonField con:

text="Pitufar"
CommandName="Pitufar"

Luego en el evento RowCommand del GridView te marcas un bonito:
If e.CommandName = "Pitufar" Then
  GridView1.SelectedIndex = Convert.ToInt32(e.CommandArgument)
  pitufeame(GridView1.SelectedValue)
  GridView1.DataBind()
End If

Y ya lo tienes.

Pero... ¿Y si necesitas convertir ese ButtonField a TemplateField? Mala cosa, porque entonces el código del RowCommand dejará de funcionar por la sencilla razón de que en e.CommandArgument ya no tendrás el índice de la fila que han clickeado.

Solución: En la propiedad CommandArgument del TemplateField hay que poner:



Y todo vuelve a funcionar.

miércoles, 12 de diciembre de 2007

Campo de GridView con enlace a valor del campo

Lo que se pretende es poder tener un GridView pero que uno de los campos se comporte como un enlace, con la peculiaridad de que el valor que se mostrará será de un campo, y el valor al que enlazará será de otro.

Esto que en ASP 3.0 parecía sencillo en ASP.NET no es complejo, sólo es necesario conocer las propiedades que se han de tocar para esta acción. Aunque a mí me he llevado mi tiempo.

Primeramente se deberá disponer de un sqlDataSource u otro origen de datos similar y que esté correctamente configurado.

A continuación agregaremos un GridView y lo enlazaremos con el control sqlDataSource a través de la propiedad DataSourceId o usando la etiqueta inteligente del control GridView.

Una vez lo tengamos, deben de aparecer los campos en el GridView, y es momento de acceder a "Editar columnas ..." a través de la etiqueta inteligente del control GridView.

En la caja campos disponibles, agregaremos uno denominado "Campo HyperLink", y los valores que tocaremos serán:

-DataNavigateUrlFields: Será el campo que contiene el valor con el que pretendemos enlazar.
-DataTextField: Será el campo que contiene el valor que deseamos sea visto en el GridView.
-DataNavigateUrlFormatString: Será la que contenga el formato de cómo deberá se referenciará al campo contenido en DataNavigateUrlFields. Sería el caso de establecer la ruta relativa, o componer una dirección. Ejemplo: ../../Repositorio/{0}
{0}, sustituirá al valor del campo por cada registro de DataNavigateUrlFields.

Otros valores opcionales:
-SortExpresion: Se establecerá el campo por el que se ordenará la columna.
-Target: El modo en que se abrirá la ventana, en la misma ventana, una nueva, etc.

Nada más.

martes, 11 de diciembre de 2007

Limitando el tamaño de los ficheros (UploadFile)

El control UploadFile nos permite subir ficheros del cliente al servidor de una manera pasmosamente fácil. Tan pasmosamente que si no se limita dicha subida las consecuencias, en forma de consumo de ancho de banda y de posibles problemas de seguridad, no tardarán en llegar.

En el artículo del FileUpload del MSDN se citan estrategias para asegurar tu subida de ficheros: de parte del cliente poner validadores sobre la extensión del fichero, y de parte del servidor comprobar el tamaño del archivo subido y su ContentType. El problema, como ellos mismos dicen, es que lo primero es demasiado vulnerable y lo segundo no te evita que el archivo viaje al servidor, en donde será rechazado si no cumple tu validación pero nadie te devolverá el ancho de banda consumido. Para evitar esta última situación, podemos limitar el tamaño máximo de transferencia de las páginas estableciendo el maxRequestLength en el web.config.


httpRuntime maxRequestLength="512"

Así nos aseguramos de que no podrán viajar más de 512kbs al servidor. El problema: que si el tamaño del request supera el límite, lo que obtendremos es un error de servidor diciendo que "Se ha reiniciado la conexión"... Poco descriptivo. Pues bien, aquí se explica cómo capturar el error desde .net, para poder decirle al usuario de una manera elegante que se meta ese divx de 2 gigas por donde le quepa.

jueves, 6 de diciembre de 2007

Encriptar secciones del web.config

Encriptar sección indicando la ruta física del web.config:

cd C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727
aspnet_regiis -pef "Seccion" "RutaFisica"


Si queremos hacerlo indicando directorio virtual:

aspnet_regiis -pe "Seccion" -app "RutaVirtual"


Para desencriptar, cambiar "pe" por "pd".

Más info, como siempre, en el MSDN.

miércoles, 24 de octubre de 2007

Diversos ejemplos del uso del parámetro "e" en eventos de actualización

En el evento ItemInserted de un FormView, para acceder al valor de un campo del registro recién insertado:

e.Values.Item("NombreCampo").ToString()


En el evento RowUpdating de un GridView, o en el ItemUpdating de un FormView, para hacer comprobaciones de validez de datos:

'no permitir dejar vacío el primer campo
If e.NewValues().Item(0) Is Nothing Then
   darAviso("No puede dejar vacío el campo X")
   e.Cancel = True
   Exit Sub
End If
'obligar a que el nuevo valor sea diferente al viejo
If (e.NewValues().Item(0).ToString = e.OldValues().Item(0).ToString) Then
   darAviso("Debe cambiar el valor del campo X")
   e.Cancel = True
   Exit Sub
End If


También a través de "e" se puede acceder a la colección Keys definida en el control para establecer los campos que conforman la clave de nuestro conjunto de datos. Por ejemplo en un RowDeleting de un GridView podemos hacer comprobaciones de integridad antes de cargarnos la fila:

If hayRegistrosDependientes(e.Keys.Item("Id").ToString()) Then
   e.Cancel = True
   darAviso("Imposible borrar. Dejas la BD hecha un solar")
End If


Los ejemplos son un poco simples, pero que cada uno los complique tanto como quiera, o como necesite.

Hale!

viernes, 19 de octubre de 2007

Subida de archivos con FTP usando .NET

Está claro que el componete FileUpload, que se puede encontrar en la barra Estándar de Visual Studio 2005, permite subir ficheros a la web remoto, pero no cubre todas las expectativas deseadas o al menos no las mías.

Por eso es interesante conocer cómo se puede atacar a un servidor en concreto y hacer un ftp que copie el fichero deseado a la ubicación remota que quedamos.

Para ello:

/1/ En declaraciones generales establecer la clase que usaremos.

Imports System.Net


/2/ Crear un botón y en el evento Click escribir el código siguiente:

Dim Servidor As Uri
Dim ClienteFtp As WebClient

Servidor = New Uri("ftp://miservidor/LosNarejos.jpg")
ClienteFtp = New WebClient()

ClienteFtp.Credentials = New NetworkCredential("diego", "xxx")

ClienteFtp.UploadFile(Servidor, c:\Inetpub\wwwroot\marmenor\Repositorio\LosNarejos.jpg")

Response.Write("¡¡ Correcto !!")

No necesita mucho comentario. Sólo una mejora, claro que esto no será hoy, la subida de archivos es síncrona, lo que cual hace que tengamos que esperar mientras sube el archivo al servidor establecido. Lo suyo sería asíncrono, pero eso será otro día.

Nos vemos.

miércoles, 17 de octubre de 2007

Establecer color dependiendo de una condición en un GridView

Habitualmente mostramos los datos en un gridview más o menos "tuneados" que dirían, usando las propiedades de dicho control.

Hasta aquí todo bien. El problema, cuando en función a un determinado valor se debía cambiar cierta propiedad.

En el caso que me ocupaba, si obtenía del registro de la tabla o vista que mostraba en el gridview, una E, debía escribir una E y establecer la propiedad BackColor de tal modo que fuese Amarillo. Y si obtenía una P, pues escribiría el valor P y el color Rojo.

Para ello:

/1/ "Editar Columnas" de las opciones de la etiqueta inteligente del GridView.
/2/ Seleccionar el campo sobre el que deseamos proceder y convertirlo en template, para ello nos posicionamos y "Convertir este informe en TemplateField". Y Aceptar.
/3/ "Editar Plantillas" de las opciones de la etiqueta inteligente del GridView. Debemos estar en la plantilla ItemTemplate.
/4/ Seleccionar el Label de la plantilla, y "Editar DataBinding ..." de las opciones de la etiqueta inteligente del Labek.
/5/ En la propiedad Text, establecer "Con enlace a" y seleccionamos nuestro campo, es este caso el mío era Estado.
/6/ Activamos "Mostrar todas las propiedades"
/7/ Nos desplazamos a la propiedad BackColor.
/8/ Activamos "Personalizar enlace", y escribimos:

IIf(Eval("Estado")="E",System.Drawing.Color.Yellow,
    System.Drawing.Color.Red)


O dicho de otro modo, si el valor del campo de Estado es E entonces, fondo amarillo y si no fondo rojo.

También se puede establecer el color en modo hexadecimal, debiendo sustituir lo que proceda por:

System.Drawing.Color.FromName("#FFFF80")


Al final, el entorno Visual Studio genera esta línea por si puede ser más claro todo (click para ampliar):



Nada más.

martes, 16 de octubre de 2007

Inicializar campos al insertar nuevo registro en FormView

Se puede hacer en otros eventos, pero yo lo tengo en el evento ItemCreated del Formview, comprobando que se está en modo insercción.

Por ejemplo, para inicializar a "0" un textbox llamado "TBAntiguedad" en el templated de inserción del FormView1:

Protected Sub FormView1_ItemCreated(ByVal sender As Object, ByVal e As System.EventArgs) Handles FormView1.ItemCreated

If (FormView1.CurrentMode = FormViewMode.Insert) Then
 Dim txtBox As TextBox = CType( FormView1.Row.FindControl("TBAntiguedad"), TextBox)
 If Not (txtBox Is Nothing) Then
  txtBox.Text = "0"
 End If
End If
End Sub


lunes, 15 de octubre de 2007

¿Dónde estoy en mi web remota?

Uno de los problemas que nos topamos cuando subimos nuestra web a un servidor que encima de todo no es nuestro, vaya que no lo administramos, es que no conocemos la estructura de directorios.

Por tanto no conocemos donde está nuestra ruta local c:\inetpub\wwwroot\miweb\imagenes, así al menos la tengo yo (e imagino que tú también).

Para ello, Bill creó una clase que viene de otra, bueno al final el método es MapPath, y el chorizo si no se hace un imports ahí va:

System.Web.HttpContext.Current.Server.MapPath()


Muy útil para hacer referencia a base de datos Access, o a ubicaciones de archivos de imágenes en servidor remoto, etc.

Posicionar dinámicamente un panel o un div

Para establecer de manera dinámica las dimensiones o la posición de un panel:

panelNombre.Attributes("style") = "POSITION: absolute; TOP: " & posArriba & "px; LEFT: " & posDerecha & "px; WIDTH: " & ancho & "px; HEIGHT: " & alto & "px"


También se puede hacer lo mismo con un div, convirtiéndolo previamente en un control de servidor (agregándole runat="server" a su definición)

jueves, 11 de octubre de 2007

Compilar ASP.NET desde consola

Útil si se desarrolla con la versión Express del Visual Studio, que no cuenta con el compilador integrado en el entorno de desarrollo.

Abrir ventana ms-dos y ejecutar las siguientes dos instrucciones:

cd C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727

Aspnet_compiler -u -f -v /nombreSitioWeb -p rutaFuentesAsp rutaGeneracionBinarios

Así obtendremos nuestro código compilado y no tendremos que subir los .vb al servidor.

ORA-01036: número/nombre de variable no válido

Aunque sea un problema específico de Oracle, es perfectamente extrapolable a SqlServer. Creo.

El problema es el siguiente: cuando lanzas una operación de actualización de datos desde un FormView te lanza el error ORA-01036: número/nombre de variable no válido.

Lo obvio es que el problema esté en el SQLDataSet, por una incongruencia en la definición de los parámetros del UpdateQuery o el InsertQuery (diferencias de número o nombre entre los parámetros definidos y los incrustados en la sentencia SQL). También hay que recordar que en Oracle los parámetros incrustados en la sentencia SQL deben empezar por ":"

Pero el error también puede aparecer debido a algo menos obvio: introducir en el template de edición del formView un control enlazado a un campo que NO figura en la sentencia del UpdateQuery, (por ejemplo, un textbox donde se muestra decodificada una clave ajena) y dejar marcado al hacer el databinding de ese campo la opción "enlace de datos birideccional" . Al lanzar el Update intentará enlazar ese campo con un parámetro de la UpdateQuery, y como no existe lanzará la excepción.

Una gilipollez que me ha hecho perder mucho tiempo, reinstalación del cliente Oracle incluida.

Hale!

miércoles, 10 de octubre de 2007

Accesibilidad en ASP.NET

Ver esta página del MSDN. Ignoro si existe versión en castellano.