[ASPNET] Nueva versión Ajax Control Toolkit v15.1 … Mejorado: aterrizando al mundo de apps modernas

Si trabajas, trabajaste o manipulaste ASP.NET Webforms en algún momento te topaste con AjaxControlTookit (alguien recordara el nombre clave Atlas) donde en el mundo antes de jQuery era lo que nos acercaba a controles “ajax” del lado del servidor con riqueza del lado del cliente en webforms.

Este componente todos utilizábamos día a día, y hasta el día de hoy hay varias preguntas en los foros de MSDN y que por nos daba dolores de cabeza en este mundo cada vez mas HTML5… desde la instalación, actualización o referencia de los controles…  que ofuscaba su utilización y no se actualizaba a tags especiales, mejoras que el mundo web iba corriendo mes tra mes (Su ultima actualización fue hace 15 meses)

Por eso en Sep/2014 “tomo la posta” la gente de @DevExpress para “enchufarlo con energía moderna de Javascript”  y poder utilizarlo en apps modernas … (hoy en día que estamos inundados de frameworks javascript y librerias like-bootstrap)  Lo mantiene actualmente y vemos la luz la versión 15.1 (mas info aquí)

Mejoras…

  • Instalación: Ahora cuando se instala el paquete se inserta en las barra de de herramientas de todas las versiones de VS (hay que probar si esta incluida la Community, porque las versiones Express no es soportado con el instalador, hay que realizarlo manualmente al agregado de los controles a la barra de herramientas)
  • Un solo assembly, ahora solo se tiene un solo archivo para versiones mayores a .NET 3.5 (no soporta 3.5!)
  • Sin dependencias externas: Antes… en la versión 7.1213.0 las que se tenían era:
    SNAGHTML1978e27f
    Ahora la funcionalidad que “dependían” de otras se extrajeron en otro componentes (ASP.NET AJAX Control Toolkit.StaticResources, ASP.NET AJAX Control Toolkit.HtmlEditor.Sanitizer)
  • Se removio el “doloroso” ToolkitScriptManager para usar ScriptManager: en versiones anteriores se utilizaba para agrupar o minificar y con el actual manera de optimización (System.Web.Optimization) ya no es necesario (pero andemas era necesario para instanciar scripts utilizado por los controles (Mas info)
  • Apps Modernas: Ahora lo podemos utilizar en las plantillas web predefinidas en VS2013 o cualquier app moderna html sin morir en el intento (con mejoras en HTML5 y como no… con Bootstrap)

 

Algunas particularidades

  • ¿Nuget?

    No todavía no se encuentra “oficialmente”. Ahora si lo buscas es la versión 7.1213.0 (que deberas agregarlo a la barra de herramientas
    SNAGHTML197fd05c

  • Nuevos componentes satélites “utiles”

    En Nuget no esta todavía la versión 15.1 … Pero si están los componentes que fueron separados por las dependencias
    SNAGHTML19844ab9

 

  • Instalador

    El instalador es 21Mb en esta version con una ui renovada…. y para mi gusto con mucha publicidad de @DevExpress (pero bueno no nos podemos quejar fue tiempo de ellos resolver varios errores y proponer mejoras)

    SNAGHTML19b3a567
    NOTA: ¿Donde se instala?
    C:Users{usuario}AppDataLocalMicrosoftVisualStudio12.0Extensionsevrkjtzw.z0p

    SNAGHTML19c6cd75


  • Barra de Herramientas

    Además el instalador ya agrega a la barra de herramientas los controles – con iconos mas like-VS2013 monocromáticos -  (antes lo teníamos que agregar manualmente)
    SNAGHTML19bf0cf5

 

Fuentes

 

Enlaces

[ASPNET] Error al deshabilitar roleManager enabled=false (quitar enableSimpleMembership o Remover módulos nativos o administrados)

Si quieres deshabilitar en ASP.NET 4.0 el módulo de RoleManager seguramente habrás configurado el atributo enabled=false simplemente! y te arroja este mensaje:

Error: No se pudo encontrar el proveedor de roles predeterminado.

SNAGHTML19efdcde

Y lo quieres deshabilitar porque no lo vas a utilizar… y si quitas el proveedor de Membreship el error prosigue. ¿Por qué ? Es porque el mensaje es que quiere utilizar la configuración del machine.config  que tiene la sección pre-configurada System.Web.Configuration.RoleManagerSection que tiene como proveedores lo que muestro en esta imagen, que son utilizados por SimpleMembership:

SNAGHTML1a05d08f

 

 

La soluciones…

OPCION 1: Deshabilitar Simple Membership (lo mas acertado si no lo utilizaras)

En nuestro appSettings agregamos esta key/value enableSimpleMembership = false

SNAGHTML1a6fe1c2

OPCION 2: (Mas drástica) Removemos el modulo de RoleManager de la aplicación web

Una opción que tenemos es a través de la seccion system.webServer/modules y allí remover el nombre del modulo que lo tenemos “tratando de obtener configuraciones”

SNAGHTML19f1ddcf

 

Enlaces

[ASPNET] Proveedor de Session State con Azure Redis Cache: RedisSessionStateProvider

 

imageSi tienes una suscripción de Azure lo puedes utilizar ya que se encuentra en modo Preview. Esta en modo solo podemos tener dos cache por suscripción de Azure.

Hace un par de meses se lanzo, como se hizo largo el post lo divide en dos,

1) Proveedor de Session State con Azure Redis Cache: RedisSessionStateProvider
Que es el tema del presente articulo, que lo hice paso a paso… (asi también me queda de referencia)

2) Compartir Session entre diferentes app con RedisSessionStateProvider 

 

¿Qué es Redis?

“…Redis is an open source, BSD licensed, advanced key-value cache and store. It is often referred to as a data structure server since keys can contain strings, hashes, lists, sets, sorted sets, bitmaps and hyperloglogs…”

SNAGHTML2ac0e196

Si quieres puedes darte una vuelta por temas:

Lo podemos utilizar como objeto Cache de nuestra app o también como proveedor de SessionState para ASP.NET

También claro, puedes descargar e instalar el Redis en tu servidor local y configurar la conexión, pero en este ejemplo veremos desde Azure.

Entonces aquí va los pasos para configurar…

 

Configurando Azure Redis Cache (Preview)

Para configurarlo en Azure, simplemente lo agregamos…  dentro de nuestro portal de Azure (que por cierto se renovó!)

SNAGHTML1efbfc9f

Una de las primeras configuraciones es el nombre DNS para el endpoint (por lo menos 6 caracteres y hasta 20)

SNAGHTML1efef444

Luego las opciones de costos! (mas info de precios… ), grupo de Recursos, cual suscripción utilizar y la localización de nuestra cache…

SNAGHTML1f1348cb

Creando….

image

 

Lo podremos ver en la sección de Cache (o pinneado en el panel principal)

SNAGHTML207494a4

SNAGHTML2075f1b4

 

Empezando a utilizarlo…

Para utilizarlo como objeto cache en nuestra app .NET debes utilizar el componente StackExchange.Redis (que lo puedes descargar desde NuGet)… puedes ver un articulo en MSDN aquí

Para mas conectores: http://redis.io/clients

Pero a lo que respecta este presente post… era el proveedor de Session State para ASP.NET (y para compartir entre varias aplicaciones)

 

Proveedor de estado de sesión de Azure Redis Cache (vista previa) para ASP.NET

Nuevamente en NuGet el paquete Microsoft.Web.RedisSessionStateProvider, pero por ahora lo debemos buscar como pre-release

SNAGHTML1f0f3b23

Hay una transformación del web.config que tiene la configuración para la sección sessionState, que sino la realizo al descargar el paquete deberias configurarla manualemente…  se encuentra dentro del paquete en la carpeta:

…packagesMicrosoft.Web.RedisSessionStateProvider.0.3.0.0-Pre-63contentnet40web.config.install.xdt

Que el contenido es el siguiente:

<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<system.web>
<sessionState mode="Custom" customProvider="MySessionStateStore" xdt:Transform="Replace">
<providers>
<!--
<add name="MySessionStateStore"
host = "127.0.0.1" [String]
port = "" [number]
accessKey = "" [String]
ssl = "false" [true|false]
throwOnError = "true" [true|false]
retryTimeoutInMilliseconds = "0" [number]
databaseId = "0" [number]
applicationName = "" [String]
connectionTimeoutInMilliseconds = "5000" [number]
operationTimeoutInMilliseconds = "5000" [number]
/>
-->
<add name="MySessionStateStore" type="Microsoft.Web.Redis.RedisSessionStateProvider"
host="127.0.0.1"
accessKey=""
ssl="false" />
</providers>
</sessionState>
</system.web>
</configuration>
 
En nuestro caso quedaría en mi app demo de este modo configurada:
  • host: El nombre del endpoint configurado
  • port: El puerto (dependiendo si seleccionado en la propiedad ssl)
  • accessKey: alguna de las claves primera o secundaria (si quieres hacer porque hay dos key… )

    SNAGHTMLb9c2ea9

<sessionState mode="Custom"
customProvider="YodaNetAzureRedisCacheDemoProvider">
<providers>
<clear />
<add name="YodaNetAzureRedisCacheDemoProvider"
type="Microsoft.Web.Redis.RedisSessionStateProvider"
host="yodanet.redis.cache.windows.net"
port = "6379"
ssl="false"
accessKey="xxxxxxxxxxxxxxxx" />
</providers>
</sessionState>
 
Y ya tenemos disponible la session en Azure Redis

Algunos parámetros …

  • throwOnError: Arrojaun excepción por algún problema en nuestro proveedor, por default es true.
  • retryTimeoutInMilliseconds : Si hay una falla es el tiempo de “reintento”, por default es

    0

 

Y para compartir variables de Session entre diferentes app web a través de RedisSessionStateProvider ¿?

Algunas opciones anteriores salieron de este post

Pero darle una mirada al atributo applicationName de la configuración del session state del web.config)

  • applicationName: Para proveer de un grupo de ítems de cache (muy útil para transiciones de aplicaciones, o para compartir session entre aplicaciones)

    Pero en este caso otro post.

 

Recursos

Prueba Azure Free por 1 mes http://azure.microsoft.com/en-us/pricing/free-trial/

image

 

 

Enlaces

[ASPNET] Nuevo proveedor de Session State para SQL Server 2014 In-Memory OLTP : SqlInMemoryProvider

Si estas utilizando SQL Server 2014 en proyectos ASP.NET (Webforms/MVC) y necesitas que el Estado de Sesión deba ser guardado en la DB, existe una mejora para el proveedor nativo de SQL Server para utilizar In-Memory OLTP para mejor rendimiento y escalabilidad, que básicamente es un proveedor personalizado realizado por el mismo equipo de SQL Server que utiliza esta característica propia de SQL Server 2014.

Vemos los pasos y artefactos que necesitamos

  • SQL Server 2014 que soporte In-Memory OLTP (Ver requisitos)
  • Crear la DB para guardar las “sesiones de nuestra app” con características de MEMORY_OPTIMIZED_DATA para que las tablas creadas tengan esta propiedad habilitada MEMORY_OPTIMIZED=ON
  • Modificar nuestro web.config para que utilice el proveedor personalizado
  • Crear una tarea en el SQL para limpiar las sessiones expiradas con el procedimiento dbo.DeleteExpiredSessions

Para todo existe un paquete de Nuget que nos provee cada parte

SNAGHTML45a7787

Al descargar

  1. El assembly Microsoft.Web.SessionState.SqlInMemory.dll (v 12.0.4100.301) en esta versión de Nuget que es la 1.0.1
    image
    Ya referenciado en nuestro proyecto
    SNAGHTML4b97249
  2. El script de creación de la DB y objetos necesarios (tablas, procedimientos)
    NOTA: Lo agrega en la carpeta raiz del proyecto acuérdate de luego eliminarlo ASPStateInMemory.sql
    Pero también se encuentra disponible en la carpeta de paquetes de Nuget del proyecto/solución packagesMicrosoft.Web.SessionState.SqlInMemory.1.0.1content

    SNAGHTML4bb08a8
    El contenido
    SNAGHTML4be3363
    Que lo que tiene de particular que se crea un grupo de archivos para MEMORY_OPTIMIZED_DATA y las tablas con creadas con la propiedad MEMORY_OPTIMIZED=ON

  3. La transformación para el web.config para la sección de sessionState
    Que cuando lo modifica a nuestro web.config debemos ir a cambiar el connectionString 
    NOTA: Una mejora que soporte connectionStringName (para indicar ya una conexión existente y no replicarla/mantenerla)
    Lo que puedes ver aquí:
    <?xml version="1.0" encoding="utf-8"?> 
    <configuration>
    <system.web>
    <sessionState mode="Custom" customProvider="SqlInMemoryProvider">
    <providers>
    <add name="SqlInMemoryProvider"
    type="Microsoft.Web.SessionState.SqlInMemoryProvider"
    connectionString="data source=sqlserver;initial catalog=ASPStateInMemory;User ID=user;Password=password;" />
    </providers>
    </sessionState>
    </system.web>
    </configuration>

  4. Limpiar periódicamente las sessiones que expiran

    Debes también crear una tarea en el SQL para limpiar las sessiones expiradas con el procedimiento dbo.DeleteExpiredSessions

 

Fuente

Mas información

 

 

[ASPNET] Como actualizar/refrescar UpdatePanel via javascript

Por una pregunta en los foros de MSDN sobre ASP.NET y UpdatePanel arme este post para que quede registro de futuras referencias.

Si bien hace varios años estoy trabajando en proyectos ASP.NET MVC, en los foros y preguntas de consultas personales de alumnos o clientes que trabajan con Webforms es común encontrar varios UpdatePanel (incluso anidados) y dicha necesidad.

Que es lo que se necesita? Disparar la actualización de un UpdatePanel desde Javascript

 

Opciones…

  1. Tener un control “oculto” para disparar el trigger (puede ser via un Timer)
  2. Realizar el postback vía javascript
    1. Postback de un control oculto
    2. Postback del mismo UpdatePanel

Bueno, si estas leyendo hasta aquí conoces el UpdatePanel, ese elemeento que es muy bueno pero que requiere una gran responsabilidad para no “sobreutilizarlo”

 

Ejemplo, sencillo…

Un formulario con un UpdatePanel, y un LinkButton… se configura un un Trigger con PostBackTrigger o AsyncPostBackTrigger para que se dispare en el evento click del LinkButton.

Una de las preguntas a veces es: ¿cuando utilizar AsyncPostBackTrigger?

  • Cuando el control a enlazar esta fuera del UpdatePanel

  • Esta dentro del UpdatePanel, pero se definió la propiedad ChildrenAsTriggers es false (en este ejemplo no es)

  • En los controles que están dentro de UpdatePanel hijos (anidados), y disparar la actualización de UpdatePanel superiores

 

Pero en nuestro ejemplo,

   1: <form id="form1" runat="server">

   2:         <asp:ScriptManager ID="sm1" runat="server"></asp:ScriptManager>

   3:         <h1>Gridview - Update Panel via Modal Popup</h1>

   4:     <div>

   5:         <asp:UpdatePanel ID="UpdatePanel1" runat="server" OnLoad="UpdatePanel1_Load">

   6:             <ContentTemplate>

   7:                 

   8:                

   9:                 <asp:LinkButton ID="linkActualizar" runat="server" OnClick="linkActualizar_Click">Actualizar</asp:LinkButton> | 

  10:                 <a href="#" onclick="abrirVentanaModal(); return false;">Abrir Ventana Modal</a>

  11:                     <br/>

  12:                 <asp:GridView ID="GridView1" runat="server"

  13:                     CssClass="grillaJedis" 

  14:                     AutoGenerateColumns="False">

  15:                 <Columns>

  16:                  ...

  17:                 </Columns>

  18:                 </asp:GridView>

  19:          </ContentTemplate>

  20:             <Triggers>

  21:                 <asp:AsyncPostBackTrigger ControlID="linkActualizar" EventName="Click" />

  22:             </Triggers>

  23:         </asp:UpdatePanel>

  24:     </div>

  25: </form>

Se puede crear una función en Javascript, que realice el postback como si fuera el LinkButton que disparara el update del UpdatePanel

   1: <script>

   2:  function actualizarDemo1() {

   3:    __doPostBack('<%=linkActualizar.ClientID%>', '');

   4:  }

   5: </script>

Pero también se puede hacer postback directamente del updatePanel

   1: <script>

   2:  function actualizarDemo2() {

   3:    __doPostBack('<%=UpdatePanel1.ClientID%>', '');

   4:  }

   5: </script>

La única aclaración, que se desprende de la opcion 2, es que  el evento no es mas el click del botón.. y en el codebehind tendrias que realizar la accion necesaria en el evento Load del UpdatePanel

   1: protected void UpdatePanel1_Load(object sender, EventArgs e)

   2: {

   3:    //Acciones a realizar

   4: }

No Intrusivo

Se podria también dispara si función, escribiendo en el evento onClick o registranndo via addEventListener

Ejemplos simples de onlick

   1: <input id="btnHtmlDemo3" type="button" 

   2:     value="Actualizar via onClick"

   3:     onclick="__doPostBack('<%=UpdatePanel1.ClientID%>', '');" />

   4:     

   5:  

   6: <a id="btnHtmlDemo4" 

   7:     href="__doPostBack('<%=UpdatePanel1.ClientID%>', '');return false;" />

   8:     Actualizar via enlace</a>

o menos intrusivo addEventListener (en este caso el código cliente js seria bueno que se cargara en el load de la pagina)

   1: <input id="btnHtmlDemo3" type="button" 

   2:     value="Actualizar via onClick" />

   3:     

   1: <script>

   2:     var btnHtmlDemo3 = document.getElementById('btnHtmlDemo3'); 

   3:     btnHtmlDemo3.addEventListener('click', 

   4:         function(){

   5:             __doPostBack('<%=UpdatePanel1.ClientID%>', '');

   6:         }, 

   7:         false);         

   8: </script>

 

 

Espero que te sirva de ayuda o guía

 

[jQuery] Autocomplete: Cómo agregar un item “al final” sobrescribiendo el método renderMenu

La idea simple, de los resultados que obtenemos en el widget Autocomplete de jQueryUI se necesitaba agregar un ítem al final del listado (ul/li) que renderiza dicho control.
La idea en imagen:

SNAGHTML5695f55a

Para verlo y jugar un poco en el editor online JSFiddle http://jsfiddle.net/fernandezja/bjLtX/

 

¿Como nos ayudamos para insertar un item? Método _renderMenu

Si bien hace un par dos años esto estaba un poco perdido… ahora que reflote esto veo que en la documentación  del Autocomplete ya tenemos los métodos documentados, ya que son método “privados”

SNAGHTML569db05b

En este caso nos ayudamos de _renderMenu

El método _renderMenu

Lo puedes ver en el repositorio de Autocomplete que lo tenemos disponible en GitHub
Recibe la lista html ul y los items a renderizar, por cada uno llama al método _renderItemData (que también en otra oportunidad nos puede ser útil, dale una mirada)

SNAGHTML56a6b7e1

Entonces solo debemos sobrescribir dicho método y al finalizar realizar un append en ul

Ejemplo simple

Un poco de código simple para ejemplificar http://jsfiddle.net/fernandezja/bjLtX/

SNAGHTML56ba1594

 

Espero que les sirva de ayuda o guía

 

[ASPNET] Como actualizar/cambiar en un website la versión de NET Framework

Para realizar esta tarea en los sitios web (websites) se encuentra en disponible en el cuadro de dialogo de Pagina de Propiedades

Como me preguntaron dejo por aquí para tenerlo de referencia

En el menu contextual website…

SNAGHTMLbc1b4ac

Y allí en la sección de Build (o Compilación)

SNAGHTML55e3e6d5

SNAGHTMLbc2bc59

A tener en cuenta

  • Dependiendo de la “complejidad” de nuestro web.config tendríamos que ir a actualizar algunos componentes, ya que no todo es “automatizado en esta vida” 
    (lease complejidad por  los componentes que utilizamos en el proyecto)

 

Más info

Tags:

[ASPNETMVC5] Template de proyectos MVC5 en VS2012 (y versiones Express)

En estos días estaba trabajando en VS2013, pero forzosamente necesariamente tuve que llevar el mismo proyecto a VS2012. Además nuevos proyectos en MVC5 tenia que crearlos desde VS2012… y las plantillas? Bien… no la tenemos disponible. Salvo que instalemos un Update (el motivo del post), pero incluso asi no tendremos disponible el wizard de proyectos like “One ASP.NET” de VS2013… pero algo es algo.

image

Si bien podremos crear proyectos de MVC4 y luego mediante Nuget actualizarlo… quería tener los templates de proyectos y algunos templates de Scaffolding (y otros que los personalice)

Hay que instalar un update.. que nos trae elementos de MVC5, WebApi2 (templates, scaffolding) pero además también para EF6… entre otras cosas.

 

Para poder trabajar así tienes que instalar

Y allí si podrás tener…

SNAGHTML5f47608SNAGHTML5f48969

El template es basico… pero por lo menos no estamos actualizando via Nuget y tenemos los elementos principales (además me sirve para cuando doy clases). Pero si quieres puedes crear tus propio template de proyecto con todo lo que necesitas.

 

Mas info

[ASPNET] Bug: Path incorrecto utilizando IncludeDirectory en nuestro ScriptBoundle (en modo debug). Solo en templates VS2013

Ayer en un proyecto MVC5 (VS2013) con el template de proyecto por default encontré un problema utilizando el método IncludeDirectory de Microsoft ASP.NET Web Optimization Framework (v 1.1.1), en modo debug no “armaba” correctamente el path de los archivos de los subdirectorios

Bueno… se resuelve fácil:

  1. Actualizando desde Nuget el paquete Microsoft.Aspnet.Web.Optimization a la versión mas reciente (v1.1.2)
  2. Si no quieres tener que hacerlo cada vez que creas un proyecto nuevo, actualiza el template de proyecto también

NOTA: También sucede con el template de Webforms en VS2013

 

Pero dejo aquí la descripción del problema

El problema: Path incorrecto en modo debug

Si tenemos una jerarquía en carpetas de archivos JavaScript algo así:

image

Uno los agruparía en un solo bundle utilizando IncludeDirectory que tiene una sobrecarga para incluir la búsqueda del patrón en todos los subdirectorios, algo así:

SNAGHTMLe083358

En modo debug renderiza el path así Y debería renderizar asi (con las carpetas)
image image

En solo cuando debugeamos porque en modo release cuando agrupa obtiene los archivos correctamente

image

 

Es sucede solo en la versión 1.1.1 del componente Microsoft ASP.NET Web Optimization Framework (Assembly System.Web.Optimization.dll)

…y es justo la versión que viene en el template de solución de MVC5 de VS2013 (tanto MVC como en WebForms).

y en MVC4? En los templates de MVC4 se utiliza la versión 1.1.1 (tanto de VS2013 como VS2012)

 

Solución

O escribimos un código que arme los IncludeDirectory de cada subdirectorio que colocamos o mas simple actualizamos los paquetes necesarios

Actualizamos vía Nuget Microsoft.AspNet.Web.Optimization.1.1.2 (que nos instala el Assembly System.Web.Optimization.dll v 1.1.31028.0)

Si ya sabes actualizar vía Nuget enhorabuena… o te cuento las dos formas:

  • Vía el administrador de Paquetes
    SNAGHTMLe6cae53
  • o vía la Consola del Administrador de Paquetes
    SNAGHTMLe755d19

Enlaces que te pueden ayudar

 

[IIS/ASPNET] Como establecer valores por default de nuestros app pool… Ejemplo target de .NET Framework/CLR (pre configurando)

Esto me preguntaron ayer así que lo dejo por aquí para referencias.

Si estas creando en el IIS varios sitios web, cuando se crea el correspondiente grupo de aplicaciones lo hace con valores por default y la mayoría de las veces no con las que deseamos (Target .NET Framework, Seguridad, Optimizaciones varias, etc), así que seria muy bueno asignar valores por default (bueno si se puede para todos los nuevos que vayamos creando)

Por ejemplo si estamos en el IIS 7.0 y creamos un sitio el app pool creado tiene el target de .NET Framework con la versión 2.0 (la versión del CLR)

SNAGHTML8991cb0
Si bien podemos cambiarla sin mucho escuerzo (Especificar una versión de .NET Framework para un grupo de aplicaciones (IIS 7) ya sea por línea de comandos o por la UI, seria bueno que pre-configuremos!

Bueno, esto lo podemos hacer gracias a la utilidad en acciones de “Establecer valores predeterminados de grupos de aplicaciones..” (Set Application Pool Defaults…)
(lo comento por si no lo viste todavía)

SNAGHTML8a3fec5

SNAGHTML8a0cf1e

 

Enlaces que te pueden ayudar