Currently Browsing

Posts Tagged ‘ asp.net ’

Ajax Control Toolkit – Setembro 2011

O Ajax Control Toolkit foi actualizado, e foram incluidas algumas novas funcionalidades como por exemplo o controlo para o Twitter, Gravatar, e a possibilidade de definir intervalos de datas no Calender Extender para limitar a escolha do utilizador.

Podem ver no blog do Stephen Walther o anúncio desta nova versão, e exemplos de como utilizar estas novas funcionalidades.


ASP.NET Mobile Framework

Project Description
ASP.NET Mobile Framework (AMF) is a framework for making web application for most-used tablet and smartphone web browsers.

 

Mais em http://amf.codeplex.com/

SpecExpress : A Fluent Validation Framework

Project Description
SpecExpress is a fluent validation framework and container for .Net that makes it easier to write validation rules and validate your objects. SpecExpress also offers integration with ASP.NET WebForms, eliminating duplication of your validation rules.

Features

  • The SpecExpress DSL provides developers with a Fluent Interface for quickly composing rules that are also easy to read. See a Sample
  • Generates error message from your validation rules, but allows for easy overriding and customization of individual messages. Support for localization of error messages.
  • Validation Catalog allows:
    • Auto discovery of specifications means the developer isn’t required to resolve which validation rules to use
    • Programatically add or change validation rules at runtime
    • Validation Contexts
  • Support for rich, complex object types and graphs
  • Built with extension and customization in mind
  • Easy to integrate into your existing code because there are no Base Classes or Attributes to inject into your code
  • ASP.NET WebForms support
  • ASP.NET MVC support
  • Silverlight support
  • A rich set of Validators

Página do projecto no Codeplex em http://specexpress.codeplex.com/

Sentinel – a lightweight monitoring system

sentinel

Sentinel is a lightweight monitoring system for reporting, analyzing, and automatically diagnosing application performance.

  • Lightweight server monitoring with no agents.
  • See data online in minutes.
  • Instantly diagnose errors, hangs, and slowdowns.
  • Detailed, intuitive, fully historical track record of application performance.
Podem ver mais informações em http://leanserver.com/sentinel

jQuery Menubar e web.sitemap

Após o HTML 5 Microsoft WebCamp Portugal, surgiu-me algum interesse em explorar o plugin Menubar.

Este plugin transforma uma lista num menu bastante agradável, e como tal, gostava de o implementar num projecto em que utilizo o web.sitemap.

Para tal, precisei de recorrer a um XLST para transformar o web.sitemap, que não é mais que um XML, numa lista no formato que o Menubar necessita.

Segue então um exemplo do web.sitemap:

<?xml version="1.0" encoding="utf-8"?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0">
    <siteMapNode url="~/" title="Home" description="Home">
        <siteMapNode url="" title="Menu 1" description="Menu 1" >
            <siteMapNode url="http://www.google.pt" title="Submenu 1" description="Submenu 1" />
        </siteMapNode>
        <siteMapNode url="" title="Menu 2" description="Menu 2">
            <siteMapNode url="http://www.microsoft.com" title="Submenu 2" description="Submenu 2" />
            <siteMapNode url="http://www.apple.com" title="Submenu 3" description="Submenu  3" />
        </siteMapNode>
    </siteMapNode>
</siteMap>

Para transformar o XML numa lista, usei o seguinte XSLT

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:map="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0"
                exclude-result-prefixes="map">
  <xsl:output method="xml" encoding="utf-8" indent="yes"/>

  <xsl:template match="map:siteMapNode">
    <li>
      <a href="{@url}" title="{@description}">
        <xsl:value-of select="@title"/>
      </a>
      <xsl:if test="map:siteMapNode">
        <ul>
          <xsl:call-template name="mapNode"/>
        </ul>
      </xsl:if>
    </li>
  </xsl:template>

  <xsl:template name="mapNode" match="/*/*">
    <xsl:apply-templates/>
  </xsl:template>
</xsl:stylesheet>

Desta forma, irei obter uma lista igual à seguinte:

<?xml version="1.0" encoding="utf-16" ?>
        <li><a href="" title="Menu 1">Menu 1</a>
            <ul>
                <li><a href="http://www.google.pt" title="Submenu 1">Submenu 1</a></li>
            </ul>
        </li>
        <li><a href="" title="Menu 2">Menu 2</a>
            <ul>
                <li><a href="http://www.microsoft.com" title="Submenu 2">Submenu 2</a></li>
                <li><a href="http://www.apple.com" title="Submenu  3">Submenu 3</a></li>
            </ul>
        </li>

Por fim, basta-nos adicionar um controlo XML que irá fazer o render da lista.

<ul id="bar1" class="menubar">
        <asp:Xml runat="server" ID="xmlSiteMapViewer" DocumentSource="~/web.sitemap" TransformSource="~/sitemap.xslt" />
    </ul>

A inserção do controlo entre uma “unordered list” foi propositado, pois só assim é que teremos o menu a funcionar correctamente e teremos um resultado identico ao que está no seguinte site:

http://view.jqueryui.com/master/demos/menubar/default.html

ASP.NET Membership Lock User

Visto que não temos uma forma directa de indicar que determinado utilizador irá estar bloqueado, a única forma que arranjei para o fazer foi forçar o erro no login múltiplas vezes, até atingir o valor máximo de tentativas definidas no atributo “maxInvalidPasswordAttempts”.

Quando usamos o Membership do ASP.NET, no web.config teremos algo como:

<add name="AspNetSqlMembershipProvider"

type="System.Web.Security.SqlMembershipProvider"

connectionStringName="MyAppConnectionString"

enablePasswordRetrieval="false"

enablePasswordReset="true"

requiresQuestionAndAnswer="false"

requiresUniqueEmail="false"

maxInvalidPasswordAttempts="5"

minRequiredPasswordLength="6"

minRequiredNonalphanumericCharacters="0"

passwordAttemptWindow="10" applicationName="MyAppName" />

O código que utilizo é então o seguinte:

public static bool LockUser(MembershipUser user)
{
    try
    {
        for (int i = 0; i < Membership.MaxInvalidPasswordAttempts; i++)
            Membership.ValidateUser(user.UserName, "thisisandummypasswordonlytolocktheuser");

        return user.IsLockedOut;
    }
    catch (Exception)
    {
        throw;
    }

}

Espero que seja util.

Project Silk

Project Silk provides guidance for building cross-browser web applications with a focus on client-side interactivity. These applications take advantage of the latest web standards like HTML5, CSS3 and ECMAScript 5 along with modern web technologies such as jQuery, Internet Explorer 9, and ASP.NET MVC3.

To illustrate this guidance, the project includes a reference implementation called Mileage Stats that enables its users to track various metrics about their vehicles and fill-ups. Much of the effort in building Mileage Stats was applied to the usability and interactivity of the experience. Animations were included to enhance the enjoyment of the site and AJAX is used to keep the interface responsive and immersive. A great deal of care was also taken to ensure the client-side JavaScript facilitates modularity and maintainability. To accomplish these design goals, the JavaScript code was structured into “widgets” that benefit from the jQuery UI Widget Factory.

Mais informações em http://silk.codeplex.com/

Controlar Menus visiveis com o web.sitemap

Uma maneira rápida de ter um menu a funcionar no nosso website, é recorrer ao controlo Menu e associá-lo a um web.sitemap usando o SiteMapDataSource.

Exemplo do ficheiro web.sitemap:

<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
    <siteMapNode  url="~/" title="Home"  description="Home" >
        <siteMapNode url="" description="Menu 1" title="Menu 1">
            <siteMapNode url="" description="SubMenu 1" title="Sub Menu 1"/>
        </siteMapNode>
        <siteMapNode url="" description="Menu 2" title="Menu 2"/>
        <siteMapNode url="" description="Menu 3" title="Menu 3"/>
    </siteMapNode>
</siteMap>

Exemplo do código para adicionar na página o menu:

<asp:Menu ID="NavigationMenu" runat="server" CssClass="menu" 
    EnableViewState="False" IncludeStyleBlock="False" Orientation="Horizontal" 
    DataSourceID="SiteMapDataSource1" onmenuitemdatabound="NavigationMenu_MenuItemDataBound">
</asp:Menu>
<asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server"  ShowStartingNode="false" />

Correndo a aplicação, iremos ter algo como a próxima imagem:

Para mostrar ou esconder os menus, consoante o tipo de acesso de cada utilizador, podemos definir as Roles em cada SiteMapNode.

Outra forma de controlar os menus visiveis, é adicionar um atributo em cada SiteMapNode e consoante o seu valor, irá ou não mostrar cada um dos menus.

Para isso, o web.sitemap será algo como:

<?xml version="1.0" encoding="utf-8"?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0">
  <siteMapNode url="~/" title="Home" description="Home" visible="true">
    <siteMapNode url="" description="Menu 1" title="Menu 1" visible="true">
      <siteMapNode url="" description="SubMenu 1" title="Sub Menu 1" visible="true" />
    </siteMapNode>
    <siteMapNode url="" description="Menu 2" title="Menu 2" visible="False" />
    <siteMapNode url="" description="Menu 3" title="Menu 3" visible="true" />
  </siteMapNode>
</siteMap>

O atributo “visible” é que nos vai indicar se o menu é ou não mostrado, e para isso vamos adicionar ao evento MenuItemDataBound do Menu o seguinte código:

protected void NavigationMenu_MenuItemDataBound(object sender, MenuEventArgs e)
{
    SiteMapNode node = e.Item.DataItem as SiteMapNode;
    if (!string.IsNullOrEmpty(node["visible"]))
    {
        bool isVisible;
        if (bool.TryParse(node["visible"], out isVisible))
        {
            if (!isVisible)
            {
                if (e.Item.Parent != null)
                    e.Item.Parent.ChildItems.Remove(e.Item);
                else
                    ((Menu)sender).Items.Remove(e.Item);
            }
        }
    }
}

Desta forma, teremos o nosso menu a mostrar todos os nós cujo valor do atributo Visible seja igual a True.

Para podermos controlar directamente os menus que irão estar ou não visiveis, utilizei uma Treeview para carregar o ficheiro web.sitemap, definir que todos os items mostrarão uma checkbox, que irá indicar o estado do atributo Visible.

<asp:TreeView runat="server" ID="tvMenus" AutoGenerateDataBindings="False" DataSourceID="XmlDsSiteMap"
    OnTreeNodeCheckChanged="tvMenus_TreeNodeCheckChanged" ShowCheckBoxes="All" ShowLines="True"
    OnTreeNodeDataBound="tvMenus_TreeNodeDataBound">
    <DataBindings>
        <asp:TreeNodeBinding DataMember="siteMapNode" SelectAction="None" ShowCheckBox="True"
            TextField="title" />
        <asp:TreeNodeBinding DataMember="siteMapNode" TextField="title" />
        <asp:TreeNodeBinding DataMember="siteMapNode" TextField="title" />
        <asp:TreeNodeBinding DataMember="siteMap" />
    </DataBindings>
</asp:TreeView>
<asp:XmlDataSource ID="XmlDsSiteMap" runat="server" DataFile="~/Web.sitemap" XPath="/*/*/*">
</asp:XmlDataSource>
    <p>
        <asp:Button runat="server" ID="btn" Text="gravar" OnClick="btn_Click" /></p>

 

protected void tvMenus_TreeNodeDataBound(object sender, TreeNodeEventArgs e)
{
    XmlElement node = e.Node.DataItem as XmlElement;
    if (node.Attributes["visible"] != null)
    {
        if (!string.IsNullOrEmpty(node.Attributes["visible"].Value))
        {
            bool isVisible;
            if (bool.TryParse(node.Attributes["visible"].Value, out isVisible))
            {
                e.Node.Checked = isVisible;
            }
            else
                e.Node.Checked = true;
        }
        else
            e.Node.Checked = true;
    }
}

Por fim, para gravarmos as alterações do atributo consoante o estado da checkbox, adicionamos ao evento TreeNodeCheckChanged da Treeview o seguinte código:

protected void tvMenus_TreeNodeCheckChanged(object sender, TreeNodeEventArgs e)
{
    XmlDsSiteMap.GetXmlDocument().SelectSingleNode(e.Node.DataPath).Attributes["visible"].Value = e.Node.Checked.ToString();
}

E ao botão que adicionamos para gravar as alterações o seguinte código:

protected void btn_Click(object sender, EventArgs e)
{
    XmlDsSiteMap.Save();
}

Agora é só activar e desactivar os items ao nosso gosto.

GridView ShowHeaderWhenEmpty

Até à versão 3.5 da .NET Framework, para mostrarmos os cabeçalhos de uma gridview quando esta não iria conter qualquer resultado, teriamos que recorrer a soluções como esta por exemplo:

List<string> rows = new List<string>(
    new string[] { "line1", "line2", "line3" });

rows.Clear();
if (rows.Count > 0)
{
    gv.DataSource = rows;
    gv.DataBind();
}
else
{
    rows.Add("");
    gv.DataSource = rows;
    gv.DataBind();
    gv.Rows[0].Visible = false;
}

Como é obvio, isto vai sempre executar a condição “else”, mas é apenas para exemplificar como forçar a apresentação do Header na GridView mesmo que o Datasource não contenha qualquer registo.

Na versão 4.0, foi introduzida uma nova propriedade que faz com que o Header seja sempre apresentado sem recorrer a este tipo de truques. A propriedade é a ShowHeaderWhenEmpty.

<asp:GridView runat="server" ID="gv" ShowHeaderWhenEmpty="true">
</asp:GridView>

EISK–Employee Info Starter Kit 5.0

Employee Info Starter Kit is an open source project that is highly influenced by the concept ‘Pareto Principle’ or 80-20 rule, where it is targeted to enable a web developer to gain 80% productivity with 20% of effort with respect to learning curve and production.
It is intended to address different types of real world challenges faced by web application developers when performing common CRUD operations. Using a single database table ‘Employee’, the current release illustrates how to utilize Microsoft ASP.NET 4.0 Web Form Data Controls, Entity Framework 4.0 and Visual Studio 2010 effectively in that context.

 

Mais informações no site do projecto no codeplex.

Blogroll