Categories
.NET

Código fuente externo y Visual Studio .NET

Ohad Israeli comenta un problema de seguridad reportado en enero de este año. Este problema existe cuando Visual Studio ejecuta el código que está dentro del evento Load de un control de usuario o formulario, que a su vez forma parte de algún otro contenedor (también ocurre cuando se heredan controles/formularios)

Si bien es cierto que antes ya había experimentado este comportamiento -como seguramente varios de ustedes-, no lo había visto desde este punto de vista. Tendré que tener un poco más de cuidado para la próxima!

Categories
.NET

FillSchema y tablas temporales.

Hoy, mientras hacía pruebas en una aplicación desarrollada en C#, una rutina que se encargaba de obtener el esquema de procedimientos almacenados (Sql Server), mandaba errores -con el mensaje "Invalid object name '#temp...'"- por el hecho de que algunos de éstos hacían uso de tablas temporales.

El código en cuestión hacía algo como esto:

csharp:

DataTable tabla = new DataTable();

using (SqlDataAdapter da = new SqlDataAdapter("sp_test", "CadenaConexion"))
{
        da.SelectCommand.CommandType = CommandType.StoredProcedure;
        da.FillSchema(tabla, SchemaType.Source);
}

Y el procedimiento tenía una estructura parecida a:

sql:

CREATE procedure sp_test
AS

SELECT  a, b
INT0    #temp
FR0M    tabla1

SELECT  T.*, T2.c
FR0M    #temp T join tabla2 T2
0N      T.a = T2.a

go

Después de hacer una búsqueda y encontrar un par de páginas que aclararon mis dudas, finalmente tuve que modificar algunos procedimientos para que hagan uso de variables tipo table.

Nota: La sintáxis del procedimiento tiene errores intencionales debido a los problemas de configuración en el servidor donde se hospeda esta página

Categories
.NET AJAX ASP.NET

Script#

Script#, al igual que Google Web Toolkit, permite generar código javascript, utilizando en este caso cualquier lenguaje compatible con el .NET Framework.

csharp:

// Demo.cs
using System;
using ScriptFX;
using ScriptFX.UI;

namespace HelloWorld {

    public class Demo : IScriptlet {

        private Button _okButton;
        private XMLHttpRequest _request;

        public void Start() {

            _okButton = new Button(Document.GetElementById("okButton"));
            _okButton.Click += new EventHandler(this.OnOKButtonClick);
        }

        private void OnOKButtonClick(object sender, EventArgs e) {
            Callback completedCallback = new Callback(this.OnRequestComplete);

            _request = new XMLHttpRequest();
            _request.Onreadystatechange = Delegate.Unwrap(completedCallback);
            _request.Open("GET", "Hello.ashx", true);
            _request.Send(null);
        }

        private void OnRequestComplete() {
            if (_request.ReadyState == 4) {
                _request.Onreadystatechange = Function.Empty;
               
                Window.Alert(_request.ResponseText);
            }
        }
    }
}
 

En la página de demostración, lo único que se tiene que hacer es registrar la clase "HelloWorld.Demo".

html:

<!-- Demo.aspx -->
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
  <title>Demo Script#</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
      <input type="button" id="okButton"
        value="OK" />

    </div>
   
    <nStuff:Scriptlet runat="server"
      ScriptAssembly="HelloWorld"
      ScriptletType="HelloWorld.Demo" />

    </form>
</body>
</html>
csharp:

<%@ WebHandler Language="C#" Class="HelloHandler" %>

// Handler.ashx: Se encarga de procesar la petición.

using System;
using System.Web;

public class HelloHandler : IHttpHandler {

    public bool IsReusable {
        get {
            return true;
        }
    }

    public void ProcessRequest(HttpContext context) {
        HttpRequest request = context.Request;
        HttpResponse response = context.Response;

        string greeting = String.Empty;
        string name = request["name"];
        if (!String.IsNullOrEmpty(name))
        {
            greeting = "Hello " + HttpUtility.HtmlEncode(name) + "!";
        }
        else
            greeting = "Hello from server";

        greeting += " - Server time: " + DateTime.Now.ToShortTimeString();
     
        response.ContentType = "text/plain";
        response.Write(greeting);
    }
}

xml:

<!-- Web.config -->
<?xml version="1.0"?>
<configuration>

  <system.web>
    <pages>
      <controls>
        <add tagPrefix="nStuff" assembly="nStuff.ScriptSharp.Web" namespace="nStuff.ScriptSharp" />
      </controls>
    </pages>
  </system.web>

</configuration>

Pueden descargar el compilador de Script# desde http://www.nikhilk.net/Content/Samples/ScriptSharp.zip o ver un video demostrativo en http://www.nikhilk.net/Content/Video/ScriptSharpIntro.wmv

Categories
Varios

Descarga Office 2007 Beta 2

Alex nos comentaba de la nueva funcionalidad de Word 2007 que permitía publicar directamente a blogs con código HTML limpio, si quieres probar esta y muchas más funcionalidades ya está lista para bajarse la Beta 2 de Office 2007, te dejamos los enlaces:

Categories
Varios

Programadores y Chefs

The reason the kitchen is a mess is not because the kitchen is poorly designed, it's because we didn't do the dishes after every meal.

Jeff Atwood hace una analogía interesante entre los programadores y chefs, en como debemos "limpiar" las cosas que hacemos para evitar problemas posteriores.

No cabe duda, como humanos que somos, que cometemos errores al desarrollar aplicaciones, pero lo importante es aprender reconocerlos y corregirlos.