Sintoma
cuando quieres realizar una consulta de los registros del Forefront TMG te salta el error: se detuvo la consulta mientras se ejecutaba.
No aparece mas información en eventos o similar.
Solución definitiva
Instalar SP2 de Forefront TMG
Solución provisiona
Puede ser util para futuros problemas :-)
Sal de la consola de gestión
Borra el directorio: C:\Documents and Settings\%profile%\Application Data\Microsoft\MMC\msisa
Vuelve a entrar y es probable que esté resuelto
En caso contrario busca por: The query stopped because an error occurred while it was running."
martes, 7 de junio de 2011
miércoles, 1 de junio de 2011
Error al cargar el marco de trabajo de cliente ASP.NET AJAX y url-Rewrite
Sintoma:
No puedes cargar el modulo de trabajo de ASP.NET AJAX en los clientes.
Ocurre en las páginas que usan ToolScriptManager en lugar del Script manager.
El problema aparece al publicar en el servidor de producción.
Solución
En mi caso:
El servidor de producción utilizaba el modulo url-rewrite module 2.0 y tenía una regla de salida en el raíz sin precondiciones.
Ha bastado con añadirle una precondición del tipo RESPONSE_CONTENT_TYPE text/html para que todo funcione. El problema por lo visto no esta tanto por lo que hace la regla como por la ausencia de precondición.
No puedes cargar el modulo de trabajo de ASP.NET AJAX en los clientes.
Ocurre en las páginas que usan ToolScriptManager en lugar del Script manager.
El problema aparece al publicar en el servidor de producción.
Solución
En mi caso:
El servidor de producción utilizaba el modulo url-rewrite module 2.0 y tenía una regla de salida en el raíz sin precondiciones.
Ha bastado con añadirle una precondición del tipo RESPONSE_CONTENT_TYPE text/html para que todo funcione. El problema por lo visto no esta tanto por lo que hace la regla como por la ausencia de precondición.
martes, 31 de mayo de 2011
Reescritura de urls y webforms de ASP.NET
Existen distintas formas de reescribir una URL, un buen articulo es el el post en el Blog de Scott Guthrie donde se resumen las formas al que habría que añadir la existencia del modulo url-rewrite para iis7.
En el post de Scott Guthrie se recomienda el uso de modulos ya desarrollados, como el url-rewrite, pero mi experiencia es que estos modulos crean muchos problemas con referencias a estilos, imagenes, scripts.
Estos problemas se agravan cuando se usan webforms ASP.NET como adelanta la sección URL Rewriting for ASP.NET Web Forms en las páginas del modulo url-rewite para iis7.
Mi opinión es que el modulo url-rewrite es útil y lo recomiendocuando tienes que trabajar con código ajeno, pero si estas trabajando con un desarrollo propio y tu código está minimamente estructurado será mas eficiente implantar la reescritura de urls en tu codigo. Eficiente tanto en tiempo de ejecución como de desarrollo.
Recordemos que el problema es usar URL del tipo:
http://www.spaintiles.info/dirbeta/0-0-1-1-1-1-15-1-1-E-1/default.aspx
Cuando sabemos que a nuestras páginas les gusta mas del tipo:
http://www.spaintiles.info/dirbeta/default.aspx?P=0-0-1-1-1-1-15-1-1-E-1
El primer paso que equivale la regla de entrada (inbound rule) del Rewrite-module es transformar la URL primera en la segunda.
Para ello usamos el evento de aplicación beginRequest y el metodo rewritePath del contexto. Dicho en simple, en global.asax editamos el procedimiento Application_BeginRequest con un código similar al que sigue.
El siguiente paso es reescribir las url para navegación entre páginas. Outbound rule o regla de salida en un rewrite-module.
Aquí es donde puede depender de como estructuraste tu codigo. En mi caso todas las url se generaban en un único procedimiento url(). A efectos de depuración introduje un setting de aplicación que me permite controlar el tipo de url que quiero generar.
Un primer paso es disponer es generar un patrón de url:
http://www.spaintiles.info/dirbeta/{0}/default.aspx
Que nos será muy util para reemplazar con el valor del parametro:
En este momento podemos probar porque igual todo funciona directamente.
Es posible que surgan problemas:
A) Al hacer click en un botón o similar.
El problema es que hacemos un post del form asp.net y el path está mal escrito.
Solución:
En el evento Load de la página añadid:
B) No se cargan estilos o scripts.
En mi caso opté por cargarlos mediante código:
Puedes encontrar mas información sobre parchear los paths relativos en Fixing Relative Paths in C# ASP.NET When Using Url Rewriting.
Gracias a Walter Wang que me dió la última idea en http://www.eggheadcafe.com/software/aspnet/30412853/url-rewriting-and-file-paths.aspx (otro post interesante sobre el tema.
En el post de Scott Guthrie se recomienda el uso de modulos ya desarrollados, como el url-rewrite, pero mi experiencia es que estos modulos crean muchos problemas con referencias a estilos, imagenes, scripts.
Estos problemas se agravan cuando se usan webforms ASP.NET como adelanta la sección URL Rewriting for ASP.NET Web Forms en las páginas del modulo url-rewite para iis7.
Mi opinión es que el modulo url-rewrite es útil y lo recomiendocuando tienes que trabajar con código ajeno, pero si estas trabajando con un desarrollo propio y tu código está minimamente estructurado será mas eficiente implantar la reescritura de urls en tu codigo. Eficiente tanto en tiempo de ejecución como de desarrollo.
Recordemos que el problema es usar URL del tipo:
http://www.spaintiles.info/dirbeta/0-0-1-1-1-1-15-1-1-E-1/default.aspx
Cuando sabemos que a nuestras páginas les gusta mas del tipo:
http://www.spaintiles.info/dirbeta/default.aspx?P=0-0-1-1-1-1-15-1-1-E-1
El primer paso que equivale la regla de entrada (inbound rule) del Rewrite-module es transformar la URL primera en la segunda.
Para ello usamos el evento de aplicación beginRequest y el metodo rewritePath del contexto. Dicho en simple, en global.asax editamos el procedimiento Application_BeginRequest con un código similar al que sigue.
Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
' Se desencadena al comienzo de cada solicitud
Dim pathOriginal = Request.Url.ToString
Dim rg As New System.Text.RegularExpressions.Regex("(?http\://\w*(\.\w*)*(?:\:\d*)?)(?/\w*/)(?:(?\w-\w(?:-\w*)*))/(?default\.aspx)(?.*)", RegexOptions.IgnoreCase)
Dim captura = rg.Matches(pathOriginal)
If captura.Count = 1 Then
With captura(0)
Dim pagina = .Groups("app").Value + "/default.aspx"
If .Groups("queryString").Value.Length = 0 Then
pagina += "?P="
Else
pagina += .Groups("queryString").Value + "&P="
End If
pagina += .Groups("argumentos").Value
Context.RewritePath(pagina, False)
End With
End If
End Sub
Este código podría ser mas simple como el ejemplo de void Application_BeginRequest(object sender, EventArgs e) {
string fullOrigionalpath = Request.Url.ToString();
if (fullOrigionalpath.Contains("/Products/Books.aspx")) {
Context.RewritePath("/Products.aspx?Category=Books");
}
else if (fullOrigionalpath.Contains("/Products/DVDs.aspx")) {
Context.RewritePath("/Products.aspx?Category=DVDs");
}
}
Pero a mi me gustan las expresiones regulares y tenerlo todo bien identificado.| Importante: En mi código de ejemplo establezco a false el parametro rebaseClientpath: Context.RewritePath(pagina, False) Con esto se resuelven muchos de los problemas relacionados con el uso del simbolo ~ en las urls de imagenes y otros controles web para referenciar la raiz de la aplicación. |
El siguiente paso es reescribir las url para navegación entre páginas. Outbound rule o regla de salida en un rewrite-module.
Aquí es donde puede depender de como estructuraste tu codigo. En mi caso todas las url se generaban en un único procedimiento url(). A efectos de depuración introduje un setting de aplicación que me permite controlar el tipo de url que quiero generar.
Un primer paso es disponer es generar un patrón de url:
If tipoUrl = tiposDeUrl.caminoIzquierdaSimple Then
dim privpagina=My.Request.uri.Absoluteuri
Dim rg As New Regex( _
"(?http\://\w*(\.\w*)*(?:\:\d*)?/\w*/)" + _
"(?:(?\w-\w(?:-\w*)*)/)?" + _
"(?default\.aspx)(?.*)?", _
RegexOptions.IgnoreCase)
Dim capturas = rg.Matches(privpagina)
If capturas.Count = 1 Then
privpagina = capturas(0).Groups("raiz").Value + _
"{0}/" + _
capturas(0).Groups("pagina").Value
End If
End If
El resultado es que en privPagina tendremos algo asi como: http://www.spaintiles.info/dirbeta/{0}/default.aspx
Que nos será muy util para reemplazar con el valor del parametro:
Select Case tipoUrl
Case tiposDeUrl.parametros
resultado = String.Format("{0}?P={1}", pagina, camino)
Case tiposDeUrl.caminoIzquierdaSimple
resultado = String.Format(pagina, camino)
End Select
(recordar que por pruedencia tengo un setting para controlar el tipo de url que utilizo)En este momento podemos probar porque igual todo funciona directamente.
Es posible que surgan problemas:
A) Al hacer click en un botón o similar.
El problema es que hacemos un post del form asp.net y el path está mal escrito.
Solución:
En el evento Load de la página añadid:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
form1.Action = Request.RawUrl
.........
B) No se cargan estilos o scripts.
En mi caso opté por cargarlos mediante código:
Public Function RaizApp() As String
With me.Request
If .ApplicationPath.EndsWith("/") Then
Return .ApplicationPath
Else
Return .ApplicationPath + "/"
End If
End With
End Function
Sub CargaJava(ByVal nombre As String)
Dim sc As New HtmlGenericControl("script")
sc.Attributes("type") = "text/javascript"
sc.Attributes("src") = String.Format("{0}Scripts/{1}.js", raizapp, nombre)
me.Header.Controls.Add(sc)
End Sub
Sub CargaCSS(ByVal nombre As String)
Dim css As New HtmlLink
css.Href = String.Format("{0}estilos/{1}.css", RaizApp, nombre)
css.Attributes("type") = "text/css"
css.Attributes("rel") = "stylesheet"
css.Attributes("media") = "all"
me.Header.Controls.Add(css)
End Sub
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
'Event load de la página
form1.Action = Request.RawUrl
If Request.QueryString.AllKeys.Contains("_TSM_HiddenField") Then Exit Sub
ToolkitScriptManager1.Scripts.Add(New UI.ScriptReference(RaizApp + "scripts/dfc.js"))
CargaJava("jquery-1.3.2.min")
CargaCSS("estilocomun")
CargaCSS("estiloceramica")
CargaCSS("findyourCeramic")
..........
Con esto y algun que otro parche ocasional te funcionará la reescritura de URLs.Puedes encontrar mas información sobre parchear los paths relativos en Fixing Relative Paths in C# ASP.NET When Using Url Rewriting.
Gracias a Walter Wang que me dió la última idea en http://www.eggheadcafe.com/software/aspnet/30412853/url-rewriting-and-file-paths.aspx (otro post interesante sobre el tema.
martes, 10 de mayo de 2011
Explotar un PDF en sus paginas y extraer textos claves
Problema:
Tienes un PDF generado por tu programa de nomina (pongamos A3NOM). En un solo archivo tienes las nominas de todos los empleados. Los textos en el PDF son accesibles, puedes copiar por ejemplo el DNI del empleado y el NIF de la empresa.
Tu necesitas guardar cada página en un fichero que tenga por nombre DNI-NIF.PDF
Solución:
Descargas itext desde http://sourceforge.net/projects/itextsharp/
Luego construyes una rutina que vaya recorriendo todas las páginas.
En cada una extraes el texto con GetTextFromPage
Luego extraes el dni y el nif con las expresiones regulares correspondientes.
Finalmente extraes y guardas la página en un archivo con el nombre deseado.
Mejor verlo en código:
Imports iTextSharp.text.pdf, System.Text, System.IO, System.Text.RegularExpressions
Sub recorrePaginas(ByVal archivo As String)
Dim rgDNI = New Regex("\d{8}[A-Z]")
Dim rgNIF = New Regex("[A-Z]\d{8}")
Dim lectorPDF = New PdfReader(archivo)
Dim TotalPaginas = lectorPDF.NumberOfPages
For Pagina = 1 To TotalPaginas
Console.WriteLine(Pagina.ToString + "\" + TotalPaginas.ToString)
Dim texto = parser.PdfTextExtractor.GetTextFromPage(lectorPDF, Pagina)
texto = Encoding.UTF8.GetString (ASCIIEncoding.Convert (Encoding.Default,
Encoding.UTF8, Encoding.Default.GetBytes(texto)))
Dim DNI = rgDNI.Match(texto).Value
Dim NIF = rgNIF.Match(texto).Value
Dim nombreArchivo = String.Format("c:\pruebas\{0}-{1}.pdf", DNI, NIF)
If File.Exists(nombreArchivo) Then File.Delete(nombreArchivo)
Dim doc = New iTextSharp.text.Document(lectorPDF.GetPageSizeWithRotation(Pagina))
Dim escritor = New PdfCopy(doc, File.Create(nombreARchivo))
doc.Open()
Dim paginaPDF = escritor.GetImportedPage(lectorPDF, Pagina)
escritor.AddPage(paginaPDF)
doc.Close()
escritor.Close()
Next
End Sub
Comentario:
Hay que ver como nos complican la vida los programadores de gestiones nominas y demás.
Con lo sencillo que sería dar la opción de generar en PDF separados la nominas y exportar en texto la información mas basica asociada al PDF.
¡Pero que se puede esperar de una gente que siempre escribe lo nombres de los campos en mayúsculas
Tienes un PDF generado por tu programa de nomina (pongamos A3NOM). En un solo archivo tienes las nominas de todos los empleados. Los textos en el PDF son accesibles, puedes copiar por ejemplo el DNI del empleado y el NIF de la empresa.
Tu necesitas guardar cada página en un fichero que tenga por nombre DNI
Solución:
Descargas itext desde http://sourceforge.net/projects/itextsharp/
Luego construyes una rutina que vaya recorriendo todas las páginas.
En cada una extraes el texto con GetTextFromPage
Luego extraes el dni y el nif con las expresiones regulares correspondientes.
Finalmente extraes y guardas la página en un archivo con el nombre deseado.
Mejor verlo en código:
Imports iTextSharp.text.pdf, System.Text, System.IO, System.Text.RegularExpressions
Sub recorrePaginas(ByVal archivo As String)
Dim rgDNI = New Regex("\d{8}[A-Z]")
Dim rgNIF = New Regex("[A-Z]\d{8}")
Dim lectorPDF = New PdfReader(archivo)
Dim TotalPaginas = lectorPDF.NumberOfPages
For Pagina = 1 To TotalPaginas
Console.WriteLine(Pagina.ToString + "\" + TotalPaginas.ToString)
Dim texto = parser.PdfTextExtractor.GetTextFromPage(lectorPDF, Pagina)
texto = Encoding.UTF8.GetString (ASCIIEncoding.Convert (Encoding.Default,
Encoding.UTF8, Encoding.Default.GetBytes(texto)))
Dim DNI = rgDNI.Match(texto).Value
Dim NIF = rgNIF.Match(texto).Value
Dim nombreArchivo = String.Format("c:\pruebas\{0}-{1}.pdf", DNI, NIF)
If File.Exists(nombreArchivo) Then File.Delete(nombreArchivo)
Dim doc = New iTextSharp.text.Document(lectorPDF.GetPageSizeWithRotation(Pagina))
Dim escritor = New PdfCopy(doc, File.Create(nombreARchivo))
doc.Open()
Dim paginaPDF = escritor.GetImportedPage(lectorPDF, Pagina)
escritor.AddPage(paginaPDF)
doc.Close()
escritor.Close()
Next
End Sub
Comentario:
Hay que ver como nos complican la vida los programadores de gestiones nominas y demás.
Con lo sencillo que sería dar la opción de generar en PDF separados la nominas y exportar en texto la información mas basica asociada al PDF.
¡Pero que se puede esperar de una gente que siempre escribe lo nombres de los campos en mayúsculas
lunes, 9 de mayo de 2011
SQL server, problema con las politicas si al crear un usuario las dejas activadas
Sintomas:
Creas un usuario en sql server 2008, le pones nombre y contraseña. Pero dejas activadas las politicas por defecto.
Resultado no te deja hacer login ni cambiar las opciones CHECK_POLICY ni CHECK_EXPIRATION mientras tengas activado MUST_CHANGE
Solución:
Cambia la contraseña de las siguiente forma:
Creas un usuario en sql server 2008, le pones nombre y contraseña. Pero dejas activadas las politicas por defecto.
Resultado no te deja hacer login ni cambiar las opciones CHECK_POLICY ni CHECK_EXPIRATION mientras tengas activado MUST_CHANGE
Solución:
Cambia la contraseña de las siguiente forma:
ALTER LOGIN [LoginName]
WITH PASSWORD = 'newpassword',unlockgoALTER LOGIN [LoginName]
WITH PASSWORD = 'newpassword',unlock,CHECK_POLICY = OFF,CHECK_EXPIRATION = OFFjueves, 28 de abril de 2011
Maquina virtual con una instantanea inexistente
Descripción del problema:
Necesitas compactar el disco de una maquina virtual hyper-V, pero no te deja porque dice que tiene instaneas (snapshots).
Tu no las ves y por tanto no puedes eliminarlas.
Cuando vas al directorio donde se almacena el disco ves un archivo .VHD y otro .AVHD
Solución:
Debes unir ambos archivos en un unico disco y luego crear una maquina virtual nueva que use ese disco.
Es recomendable guardar una copia de los dos archivos por si pasara algo.
Luego le cambias la extensión al .AVHD por .VHD.
Lo editas con el editor de discos (al que has renombrado) y lo combinas (merge) con su disco primario.
Finalmente creas una maquina virtual con ese disco y te olvidas de la otra.
(por supuesto ahora puedes compactar)
Esta descrito con muchas ilustraciones en:http://www.networkfoo.org/server-infrastructure/recovering-your-virtual-machine-how-manually-merge-hyper-v-snapshots-back-one-
Necesitas compactar el disco de una maquina virtual hyper-V, pero no te deja porque dice que tiene instaneas (snapshots).
Tu no las ves y por tanto no puedes eliminarlas.
Cuando vas al directorio donde se almacena el disco ves un archivo .VHD y otro .AVHD
Solución:
Debes unir ambos archivos en un unico disco y luego crear una maquina virtual nueva que use ese disco.
Es recomendable guardar una copia de los dos archivos por si pasara algo.
Luego le cambias la extensión al .AVHD por .VHD.
Lo editas con el editor de discos (al que has renombrado) y lo combinas (merge) con su disco primario.
Finalmente creas una maquina virtual con ese disco y te olvidas de la otra.
(por supuesto ahora puedes compactar)
Esta descrito con muchas ilustraciones en:http://www.networkfoo.org/server-infrastructure/recovering-your-virtual-machine-how-manually-merge-hyper-v-snapshots-back-one-
martes, 26 de abril de 2011
No puedes comprimir (editar) un disco virtual hyper-V Windows 7
Sintoma:
Tienes una maquina virtual hyper-v con windows 7 y quieres reducir el tamaño de su disco virtual. El asistente te dice que la operración actual no puede hacerse por limitaciones del sistema operativo.
Solución:
Probablemente tengas copias sombra, shadow copies, instaneas, puntos de recuperación del sistema, o como quieras llamarlos. Cuidado no digo en hyper-v sino en la misma maquina windows 7.
Eliminalos con el mandato
vssadmin delete shadows /all
En consola de administrador.
Tienes una maquina virtual hyper-v con windows 7 y quieres reducir el tamaño de su disco virtual. El asistente te dice que la operración actual no puede hacerse por limitaciones del sistema operativo.
Solución:
Probablemente tengas copias sombra, shadow copies, instaneas, puntos de recuperación del sistema, o como quieras llamarlos. Cuidado no digo en hyper-v sino en la misma maquina windows 7.
Eliminalos con el mandato
vssadmin delete shadows /all
En consola de administrador.
Suscribirse a:
Entradas (Atom)