En esta oportunidad mediante un ejemplo, vamos a implementar la funcionalidad de selectores en cascada.  “Si el siguiente error, alguna vez se te atravesó  en el camino!, estás en el lugar indicado :D.”

“Invalid postback or callback argument. Event validation is enabled using in configuration or in a page. For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them. If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.”

Entonces, es necesario tomar medidas y no dejarnos llevar del pánico.

El error indica que estas intentando saltarte un paso en la seguridad del WebForm, por qué? Este comportamiento se debe a que inicialmente estás usando controles de ASP.NET, en nuestro caso DropDownList, hasta este punto todo claro, pero que ocurre al momento de dotar dicho control con funcionalidad asíncrona? .NET restringe  la posibilidad que un usuario técnicamente entrenado pueda manipular el html en el cliente para enviar datos maliciosos al servidor. Por lo tanto la validación que arroja en este caso .NET.

Veamos el code-behind de este ejemplo:

Simulación Capa Datos

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SimpleCascadingDrops
{
    public class SimulateDataBase
    {
        public List<TipoVehiculo> GetTipoVehiculos()
        {
            List<TipoVehiculo> list = new List<TipoVehiculo>();
            list.Add(new TipoVehiculo { Id = 1, NombreTipo = "Moto" });
            list.Add(new TipoVehiculo { Id = 2, NombreTipo = "Carro" });
            list.Add(new TipoVehiculo { Id = 3, NombreTipo = "Bicicleta" });
            return list;
        }

    }
    public class TipoVehiculo
    {
        public int Id { get; set; }
        public string NombreTipo { get; set; }
    }
}

Code Behind que aplica para los dos ejemplos de WebForm siguientes


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Web.Services;

namespace SimpleCascadingDrops
{
    public partial class SimpleCascadingDrop : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }
        /// <summary>
        /// Retorna una lista de tipo de vehículo
        /// </summary>
        /// <returns></returns>
        [WebMethod]
        public static List<TipoVehiculo> GetTiposVehiculo()
        {
            SimulateDataBase data = new SimulateDataBase();
            var list = data.GetTipoVehiculos();
            //Valor por defecto
            list.Insert(0, new TipoVehiculo { Id = -1, NombreTipo = "--Seleccione--" });
            return list;
        }
    }
}

ASPX Incorrecto,  en este primer Web Form vemos como al implementar  unos selectores en cascada de .NET exige el registro de los elementos en este caso ListItems(options en html puro) esten registrados. Debido a que la carga de el control DropDown será mediante ajax, .NET nos dirá que esto infringe las reglas y qué bien podemos des habilitar  la validación, cosa que no sería muy recomendable.


<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="SimpleCascadingDrop.aspx.cs"
    Inherits="SimpleCascadingDrops.SimpleCascadingDrop" %>

<!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>Prueba Error CascadingDrops</title>
    <script type="text/javascript" language="javascript" src="Scripts/jquery-1.6.1.min.js"></script>
    <script type="text/javascript" language="javascript">
        $(document).ready(function () {
            $("#DDLAction").change(function () {
                $("#DDLTipoVeiculo").html("");
                $("#DDLVehiculo").html("");
                if ($(this).val() != "-1") {
                    $.ajax({
                        type: "POST",
                        url: "SimpleCascadingDrop.aspx/GetTiposVehiculo",
                        data: {},
                        dataType: "json",
                        contentType: "application/json; chartset=utf-8",
                        success: function (result) {
                            if (result.d) {
                                if (result.d.length > 0)
                                    $("#DDLTipoVeiculo").attr("disabled", false);
                                $(result.d).each(function () {
                                    $("#DDLTipoVehiculo").append($("<option></option>").attr("value", this.Id).text(this.NombreTipo));
                                });

                            }
                        },
                        error: function (xmlHttpError, err, desc) {
                            alert(xmlHttpError.responseText)
                        },
                        async: true
                    });
                }
            });
        });
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <table>
            <tr>
                <td>
                    Qué hacer?
                </td>
                <td>
                    <asp:DropDownList ID="DDLAction" Style="width: 150px" runat="server">
                        <asp:ListItem Text="--Seleccionar--" />
                        <asp:ListItem Text="Comprar" />
                        <asp:ListItem Text="Vender" />
                    </asp:DropDownList>
                </td>
            </tr>
            <tr>
                <td>
                    Vehículos
                </td>
                <td>
                    <asp:DropDownList ID="DDLTipoVehiculo" Style="width: 150px" Enabled="false" runat="server">
                    </asp:DropDownList>
                </td>
            </tr>
        </table>
        <br />
        <asp:Button ID="BtProbar" runat="server" Text="Probar Error" />
    </div>
    </form>
</body>
</html>

ASPX Correcto, en este echamos  mano de los tags html ‘<select>’ y ciertamente de unas controles de servidor tipo HiddenField, para mantener los valores respectivos al SelectedValue y SelectedText.


&lt;%@ Page Language=&quot;C#&quot; AutoEventWireup=&quot;true&quot; CodeBehind=&quot;CorrectSimpleCascadingDrop.aspx.cs&quot; Inherits=&quot;SimpleCascadingDrops.CorrectSimpleCascadingDrop&quot; %&gt;

&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;

&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
&lt;head id=&quot;Head1&quot; runat=&quot;server&quot;&gt;
    &lt;title&gt;Prueba Error CascadingDrops&lt;/title&gt;
    &lt;script type=&quot;text/javascript&quot; language=&quot;javascript&quot; src=&quot;Scripts/jquery-1.6.1.min.js&quot;&gt;&lt;/script&gt;
    &lt;script type=&quot;text/javascript&quot; language=&quot;javascript&quot;&gt;
        $(document).ready(function () {
            //Carga el control luego del postback
            if ($(&quot;#HFSelectedValue&quot;).val() != &quot;-1&quot; &amp;&amp; $.trim($(&quot;#HFSelectedValue&quot;).val()) != &quot;&quot;) {
                $(&quot;#DDLTipoVehiculo&quot;).attr(&quot;disabled&quot;, &quot;&quot;);
                $(&quot;#DDLTipoVehiculo&quot;).html(&quot;&quot;);
                $(&quot;#DDLTipoVehiculo&quot;).append($(&quot;&lt;option value='-1'&gt;--Seleccione--&lt;/option&gt;&quot;));
                $(&quot;#DDLTipoVehiculo&quot;).append($(&quot;&lt;option value='&quot; + $(&quot;#HFSelectedValue&quot;).val() + &quot;'&gt;&quot; + $(&quot;#HFSelectedText&quot;).val() + &quot;&lt;/option&gt;&quot;));
                $(&quot;#DDLTipoVehiculo&quot;).val($(&quot;#HFSelectedValue&quot;).val());
            }
            //Nos aseguramos que en el onblur del control se efectuen
            //los cambios respecto a la opción seleccionada.
            $(&quot;#DDLTipoVeiculo&quot;).blur(function () {
                $(&quot;#HFSelectedValue&quot;).val($(this).val());
                $(&quot;#HFSelectedText&quot;).val($(this).find(&quot;option:selected&quot;).text());
            });
            //Nos aseguramos que en el onchange del control se efectuen
            //los cambios respecto a la opción seleccionada.
            $(&quot;#DDLTipoVehiculo&quot;).change(function () {
                $(&quot;#HFSelectedValue&quot;).val($(this).val());
                $(&quot;#HFSelectedText&quot;).val($(this).val());
            });
            //Hacemos el llamado ajax al static web method de la página
            //para cargar los datos
            $(&quot;#DDLAction&quot;).change(function () {
                if ($(this).val() != &quot;-1&quot;) {
                    $.ajax({
                        type: &quot;POST&quot;,
                        url: &quot;CorrectSimpleCascadingDrop.aspx/GetTiposVehiculo&quot;,
                        data: {},
                        dataType: &quot;json&quot;,
                        contentType: &quot;application/json; chartset=utf-8&quot;,
                        success: function (result) {
                            //Construimos el &lt;select&gt;
                            if (result.d) {
                                $(&quot;#DDLTipoVehiculo&quot;).html(&quot;&quot;);
                                if (result.d.length &gt; 0)
                                    $(&quot;#DDLTipoVeiculo&quot;).attr(&quot;disabled&quot;, &quot;&quot;);
                                $(result.d).each(function () {
                                    $(&quot;#DDLTipoVeiculo&quot;).append($(&quot;&lt;option&gt;&lt;/option&gt;&quot;).attr(&quot;value&quot;, this.Id).text(this.NombreTipo));
                                });
                            }
                        },
                        error: function (xmlHttpError, err, desc) {
                            alert(xmlHttpError.responseText)
                        },
                        async: true
                    });
                }
            });
        });
    &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;form id=&quot;form1&quot; runat=&quot;server&quot;&gt;
    &lt;div&gt;
        &lt;table&gt;
            &lt;tr&gt;
                &lt;td&gt;
                    Qué hacer?
                &lt;/td&gt;
                &lt;td&gt;
                    &lt;asp:DropDownList ID=&quot;DDLAction&quot; style=&quot;width:150px&quot; runat=&quot;server&quot;&gt;
                        &lt;asp:ListItem Text=&quot;--Seleccionar--&quot; /&gt;
                        &lt;asp:ListItem Text=&quot;Comprar&quot; /&gt;
                        &lt;asp:ListItem Text=&quot;Vender&quot; /&gt;
                    &lt;/asp:DropDownList&gt;
                &lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
                &lt;td&gt;
                    Vehículos
                &lt;/td&gt;
                &lt;td&gt;
                    &lt;select id=&quot;DDLTipoVehiculo&quot; style=&quot;width:150px&quot; disabled=&quot;disabled&quot;&gt;
                        &lt;option value=&quot;-1&quot;&gt;--Seleccione--&lt;/option&gt;
                    &lt;/select&gt;
                    &lt;asp:HiddenField ID=&quot;HFSelectedValue&quot; runat=&quot;server&quot;  Value=&quot;-1&quot;/&gt;
                    &lt;asp:HiddenField ID=&quot;HFSelectedText&quot; runat=&quot;server&quot; /&gt;
                &lt;/td&gt;
            &lt;/tr&gt;
        &lt;/table&gt;
        &lt;br /&gt;
        &lt;asp:Button ID=&quot;BtProbar&quot; runat=&quot;server&quot; Text=&quot;Probar Error&quot; /&gt;

    &lt;/div&gt;
    &lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;

Demo

Eso es todo, en la parte inferior dejo el link al código como siempre, hasta la próxima!

Code here!

Anuncios