viernes, 12 de junio de 2026

.NET C# Medidas para prevenir hack en sistema

Se debe agregar protección de cabeceras http en archivos Web.Config, dentro del tag <system.webServer>

Como en la imagen de referencia.


<httpProtocol>

      <customHeaders>

        <add name="X-Frame-Options" value="SAMEORIGIN"/>

        <add name="X-Content-Type-Options" value="nosniff"/>

      <add name="Content-Security-Policy-Report-Only" value="default-src 'self'"/>

        <add name="X-Xss-Protection" value="1; mode=block"/>

        <remove name="X-Powered-By"/>       

      </customHeaders>

</httpProtocol>




X-Frame-Options Con el valor SAMEORIGIN, este encabezado impide que el sitio sea cargado dentro de un <iframe> en otro dominio. Su propósito es proteger contra ataques de clickjacking, permitiendo que el contenido se muestre únicamente en páginas del mismo origen.

X-Content-Type-Options Con el valor nosniff, este encabezado indica al navegador que no debe intentar adivinar el tipo de contenido de los archivos. De esta manera, se evita que un archivo con extensión incorrecta sea interpretado como otro tipo, reduciendo el riesgo de ejecución de contenido malicioso.

Content-Security-Policy-Report-Only Con el valor default-src 'self', este encabezado define una política de seguridad de contenido (CSP) en modo report-only. No bloquea recursos, pero genera reportes cuando se detecta contenido que viola la política. En este caso, solo se permiten recursos provenientes del mismo dominio, y cualquier intento de cargar contenido externo se registra.

X-Xss-Protection Con el valor 1; mode=block, este encabezado activa el filtro de protección contra ataques de Cross-Site Scripting (XSS) en avengadores antiguos, como Internet Explorer y algunos basados en WebKit. Si el navegador detecta un posible ataque XSS, bloquea la carga de la página en lugar de mostrarla.

remove name="X-Powered-By" Este ajuste elimina el encabezado X-Powered-By que IIS agrega por defecto. Dicho encabezado suele revelar la tecnología utilizada (por ejemplo, "ASP.NET"), lo que podría dar pistas a atacantes. Al removerlo, se reduce la exposición de información innecesaria.

En conjunto, estos encabezados fortalecen la seguridad de una aplicación en IIS, mitigando riesgos como clickjacking, XSS, content sniffing y la divulgación de información sensible.


lunes, 22 de septiembre de 2025

.NET C# grilla dinámica desde SP

 .ASPX

<%@ Page Title="Informe Bienes Asegurados" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="InformeBienesAsegurados.aspx.cs" Inherits="LeaseOperWeb.Paginas.AdmSeguros.Consultas.InformeBienesAsegurados" %>


<%@ Register Assembly="DevExpress.Web.ASPxEditors.v11.1, Version=11.1.8.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a"

    Namespace="DevExpress.Web.ASPxEditors" TagPrefix="dx" %>

<%@ Register Assembly="DevExpress.Web.v11.1, Version=11.1.8.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a"

    Namespace="DevExpress.Web.ASPxPanel" TagPrefix="dx" %>

<%@ Register Assembly="DevExpress.Web.ASPxGridView.v11.1, Version=11.1.8.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a"

    Namespace="DevExpress.Web.ASPxGridView" TagPrefix="dx" %>


<asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat="server">

     


    <script type="text/javascript">

        // ===== Utilidades =====

        var _rutMsgShown = false;

        function _onceRutInvalidMessage() {

            if (_rutMsgShown) return false;

            _rutMsgShown = true;

            showMessage('RUT Cliente no es válido.', 'Validación');

            // liberar el lock después de un tick (evita múltiples eventos encadenados)

            setTimeout(function () { _rutMsgShown = false; }, 300);

            return true;

        }


        function onlyDigits(e) {

            var k = e.which || e.keyCode;

            if (k === 8 || k === 9 || k === 46 || (k >= 35 && k <= 40)) return true;

            if (k >= 48 && k <= 57) return true;

            if (k >= 96 && k <= 105) return true;

            return false;

        }

        function cleanRut(r) { return (r || "").toString().replace(/\./g, '').replace(/-/g, '').toUpperCase(); }

        function dvRut(num) { var M = 0, S = 1; for (; num; num = Math.floor(num / 10)) S = (S + num % 10 * (9 - M++ % 6)) % 11; return S ? String(S - 1) : 'K'; }

        function formatRut(r) {

            r = cleanRut(r); if (r.length < 2) return r;

            var cuerpo = r.slice(0, -1), dv = r.slice(-1), out = "", i = 0;

            for (var j = cuerpo.length - 1; j >= 0; j--) { out = cuerpo.charAt(j) + out; i++; if (i % 3 === 0 && j !== 0) out = "." + out; }

            return out + "-" + dv;

        }

        function isRutValido(r) {

            r = cleanRut(r); if (r.length < 2) return false;

            var c = r.slice(0, -1), dv = r.slice(-1); if (!/^\d+$/.test(c)) return false;

            return dv.toUpperCase() === dvRut(parseInt(c, 10));

        }

        function formatDateISO(d) {

            if (!d) return "";

            var yyyy = d.getFullYear(), mm = ("0" + (d.getMonth() + 1)).slice(-2), dd = ("0" + d.getDate()).slice(-2);

            return yyyy + "-" + mm + "-" + dd;

        }

        function validarFechas(fechaIni, fechaFin) {

            if ((fechaIni && !fechaFin) || (!fechaIni && fechaFin)) { showMessage('Debe ingresar ambas fechas: Inicio y Término.', 'Validación'); return false; }

            if (fechaIni && fechaFin && fechaIni > fechaFin) { showMessage('La fecha de inicio no puede ser mayor que la fecha de término.', 'Validación'); return false; }

            return true;

        }


        // Sincroniza filtros -> hidden inputs (para Request[...] y callbacks)

        function syncHiddenParams() {

            // RUT

            var rut = txtRutCliente.GetText();

            if (rut) {

                var limpio = cleanRut(rut);

                if (!isRutValido(limpio)) {

                    _onceRutInvalidMessage();

                    txtRutCliente.SetText('');

                    return false;

                }

                rut = formatRut(limpio);

            }


            var op = txtOperacion.GetText();

            if (op && !/^\d{1,20}$/.test(op)) { showMessage('Operación debe ser numérica (máx. 20 dígitos).', 'Validación'); return false; }

            var ult = txtUltimaPoliza.GetText();

            if (ult && !/^\d{1,10}$/.test(ult)) { showMessage('Última Póliza debe ser numérica entera (INT).', 'Validación'); return false; }


            var tipoSeg = cbxTipoSeguro.GetValue();

            var estPol = cbxEstadoPoliza.GetValue();

            var fIni = dtFechaTerminoIni.GetDate();

            var fFin = dtFechaTerminoFin.GetDate();

            if (!validarFechas(fIni, fFin)) return false;


            document.getElementById("rutCliente").value = rut || "";

            document.getElementById("operacion").value = op || "";

            document.getElementById("ultimaPoliza").value = ult || "";

            document.getElementById("tipoSeguro").value = tipoSeg || "";

            document.getElementById("estadoPoliza").value = estPol || "";

            document.getElementById("fechaTerminoIni").value = fIni ? formatDateISO(fIni) : "";

            document.getElementById("fechaTerminoFin").value = fFin ? formatDateISO(fFin) : "";

            return true;

        }


        // Cargar combos dependientes

        function onTipoSeguroChanged(s, e) {

            var tipo = s.GetValue();

            cbxEstadoPoliza.PerformCallback(tipo ? tipo.toString() : "");

        }


        // Buscar -> callback del GRID

        function onBuscarClick() {

            if (!syncHiddenParams()) return;


            var rutCliente = document.getElementById("rutCliente").value || "";

            var operacion = document.getElementById("operacion").value || "";

            var ultimaPoliza = document.getElementById("ultimaPoliza").value || "";

            var tipoSeguro = document.getElementById("tipoSeguro").value || "";

            var estadoPoliza = document.getElementById("estadoPoliza").value || "";

            var fechaTerminoIni = document.getElementById("fechaTerminoIni").value || "";

            var fechaTerminoFin = document.getElementById("fechaTerminoFin").value || "";


            var allEmpty =

                !rutCliente &&

                !operacion &&

                !ultimaPoliza &&

                (tipoSeguro === "0" || tipoSeguro === "") &&

                (estadoPoliza === "0" || estadoPoliza === "") &&

                !fechaTerminoIni &&

                !fechaTerminoFin;


            if (allEmpty) {

                showMessage('Ingrese al menos un criterio de búsqueda para recuperar.', 'Validación');

                return;

            }


            var p =

                rutCliente + "|" +

                operacion + "|" +

                ultimaPoliza + "|" +

                tipoSeguro + "|" +

                estadoPoliza + "|" +

                fechaTerminoIni + "|" +

                fechaTerminoFin;


            gvInforme.PerformCallback(p);

        }



        // Exportar Excel (usa los hidden, mismo orden que el .cs)

        function excel() {

            if (!syncHiddenParams()) return;


            var get = function (id) { return (document.getElementById(id).value || ''); };


            var rutCliente = get('rutCliente');

            var operacion = get('operacion');

            var ultimaPoliza = get('ultimaPoliza');

            var tipoSeguro = get('tipoSeguro');

            var estadoPoliza = get('estadoPoliza');

            var fechaTerminoIni = get('fechaTerminoIni');

            var fechaTerminoFin = get('fechaTerminoFin');



            var allEmpty =

                !rutCliente &&

                !operacion &&

                !ultimaPoliza &&

                (tipoSeguro === "0" || tipoSeguro === "") &&

                (estadoPoliza === "0" || estadoPoliza === "") &&

                !fechaTerminoIni &&

                !fechaTerminoFin;


            if (allEmpty) {

                showMessage('Ingrese al menos un criterio de búsqueda para exportar.', 'Validación');

                return;

            }


            var id_informe = "10031";

            var hoja = "BienesAsegurados";


            var wsdata = "{'iddoc':'" + id_informe +

                "','hoja':'" + hoja +

                "','rutCliente':'" + rutCliente +

                "','operacion':'" + operacion +

                "','ultimaPoliza':'" + ultimaPoliza +

                "','tipoSeguro':'" + tipoSeguro +

                "','estadoPoliza':'" + estadoPoliza +

                "','fechaTerminoIni':'" + fechaTerminoIni +

                "','fechaTerminoFin':'" + fechaTerminoFin + "'}";


            jutils.ajax.getJsonData_Async("ReporteXls", wsdata, arguments.callee.name, showReportExcel);

        }



        function showReportExcel(data) {

            if (data == 'SD') { showMessage('No se encontraron Registros', 'Información'); return; }

            var wsdata = "{}";

            var url = jutils.ajax.getJsonData("GetRutaCargaExcel", wsdata, arguments.callee.name);

            url = url + data;

            var opts = "toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=yes, width=1, height=1, top=1, left=1";

            window.open(url, '', opts);

        }


        // Formato/validación RUT en vivo

        function onRutKeyUp(s, e) {

            _rutMsgShown = false; // reset al teclear

            var v = s.GetText();

            v = v.replace(/[^\dkK.-]/g, '');

            s.SetText(v);

        }

        function onRutLostFocus(s, e) {

            var v = s.GetText();

            if (!v) return;


            var limpio = cleanRut(v);

            if (!isRutValido(limpio)) {

                // muestra solo 1 vez y limpia

                _onceRutInvalidMessage();

                s.SetText('');

                return;

            }

            s.SetText(formatRut(limpio));

        }


        function onLimpiarClick() {


            txtRutCliente.SetText('');

            txtOperacion.SetText('');

            txtUltimaPoliza.SetText('');



            cbxTipoSeguro.SetSelectedIndex(0); // "No definido"

            cbxEstadoPoliza.ClearItems();



            dtFechaTerminoIni.SetDate(null);

            dtFechaTerminoFin.SetDate(null);



            document.getElementById("rutCliente").value = "";

            document.getElementById("operacion").value = "";

            document.getElementById("ultimaPoliza").value = "";

            document.getElementById("tipoSeguro").value = "";

            document.getElementById("estadoPoliza").value = "";

            document.getElementById("fechaTerminoIni").value = "";

            document.getElementById("fechaTerminoFin").value = "";



            gvInforme.ClearFilter();

            gvInforme.PerformCallback('');

        }


    </script>

</asp:Content>


<asp:Content ID="Content2" ContentPlaceHolderID="HeaderContent" runat="server">

    <!-- Hidden para callbacks/WebMethods -->

    <input type="hidden" id="rutCliente" name="rutCliente" />

    <input type="hidden" id="operacion" name="operacion" />

    <input type="hidden" id="ultimaPoliza" name="ultimaPoliza" />

    <input type="hidden" id="tipoSeguro" name="tipoSeguro" />

    <input type="hidden" id="estadoPoliza" name="estadoPoliza" />

    <input type="hidden" id="fechaTerminoIni" name="fechaTerminoIni" />

    <input type="hidden" id="fechaTerminoFin" name="fechaTerminoFin" />


    <table width="100%" border="0" cellspacing="0" cellpadding="0">

        <tr>

            <td valign="top" id="td-descrip">

                <table width="100%" border="0" cellspacing="0" cellpadding="0">

                    <tr>

                        <td>&nbsp;</td>

                    </tr>

                    <tr>

                        <td class="td-titulos">Informe Bienes ASEGURADOS</td>

                    </tr>

                    <tr>

                        <td>

                            <table width="100%" border="0" cellspacing="0" cellpadding="0">

                                <tr>

                                    <td width="40">&nbsp;</td>

                                    <td class="lin-borde">&nbsp;</td>

                                </tr>

                            </table>

                        </td>

                    </tr>

                    <tr>

                        <td class="mig">Adm. Seguros / Consultas / INFORME BIENES ASEGURADOS</td>

                    </tr>

                </table>

            </td>

        </tr>

        <tr>

            <td valign="top">&nbsp;</td>

        </tr>

        <tr>

            <td valign="top">

                <table width="100%" border="0" cellpadding="0" cellspacing="0">

                    <tr>

                        <td width="10">&nbsp;</td>

                        <td>

                            <asp:UpdatePanel ID="udp" runat="server" UpdateMode="Conditional">

                                <ContentTemplate>

                                    <table width="100%" border="0" cellspacing="0" cellpadding="0">

                                        <tr>

                                            <td valign="top">

                                                <table width="100%" border="0" cellpadding="0" cellspacing="0" class="style2">

                                                    <tr>

                                                        <td>

                                                            <table width="100%" border="0" cellpadding="0" cellspacing="0" class="style2">

                                                                <tr>

                                                                    <td>

                                                                        <table width="100%" border="0" cellspacing="0" cellpadding="0">

                                                                            <tr>

                                                                                <td>

                                                                                    <table width="100%" border="0" cellspacing="0" cellpadding="0" class="borde">

                                                                                        <tr>

                                                                                            <td>

                                                                                                <div class="modul">

                                                                                                    <div class="modul_top">

                                                                                                        <div class="modul_top_right">

                                                                                                            <table width="100%" border="0" cellspacing="0" cellpadding="0">

                                                                                                                <tr>

                                                                                                                    <td width="9"></td>

                                                                                                                    <td class="modul_fd">

                                                                                                                        <table width="100%" border="0" cellspacing="0" cellpadding="0">

                                                                                                                            <tr>

                                                                                                                                <td class="modul_fd_tit">BÚSQUEDA</td>

                                                                                                                            </tr>

                                                                                                                        </table>

                                                                                                                    </td>

                                                                                                                    <td width="9"></td>

                                                                                                                </tr>

                                                                                                            </table>

                                                                                                        </div>

                                                                                                    </div>

                                                                                                    <div id="modul_content"></div>

                                                                                                </div>

                                                                                            </td>

                                                                                        </tr>

                                                                                    </table>

                                                                                </td>

                                                                            </tr>

                                                                            <tr>

                                                                                <td class="modul_bordes">

                                                                                    <table width="100%" border="0" cellspacing="0" cellpadding="0" class="caja-datos">

                                                                                        <tr>

                                                                                            <td width="10"></td>

                                                                                            <td height="10"></td>

                                                                                            <td width="10"></td>

                                                                                        </tr>

                                                                                        <tr>

                                                                                            <td rowspan="2"></td>

                                                                                            <td>

                                                                                                <!-- ===== Filtros ===== -->

                                                                                                <table class="style2" style="margin-bottom: 8px;">

                                                                                                    <tr>

                                                                                                        <td>RUT Cliente:</td>

                                                                                                        <td>

                                                                                                            <dx:ASPxTextBox ID="txtRutCliente" runat="server" Width="150" ClientInstanceName="txtRutCliente" MaxLength="12">

                                                                                                                <ClientSideEvents KeyUp="onRutKeyUp" LostFocus="onRutLostFocus" />

                                                                                                            </dx:ASPxTextBox>

                                                                                                            <span style="font-size: 10px; color: #666;">(11.111.111-1)</span>

                                                                                                        </td>

                                                                                                        <td>Operación:</td>

                                                                                                        <td>

                                                                                                            <dx:ASPxTextBox ID="txtOperacion" runat="server" Width="150" ClientInstanceName="txtOperacion" MaxLength="20">

                                                                                                                <ClientSideEvents KeyPress="function(s,e){ if(!onlyDigits(e)) e.preventDefault(); }" />

                                                                                                            </dx:ASPxTextBox>

                                                                                                        </td>

                                                                                                        <td>Última Póliza:</td>

                                                                                                        <td>

                                                                                                            <dx:ASPxTextBox ID="txtUltimaPoliza" runat="server" Width="150" ClientInstanceName="txtUltimaPoliza" MaxLength="10">

                                                                                                                <ClientSideEvents KeyPress="function(s,e){ if(!onlyDigits(e)) e.preventDefault(); }" />

                                                                                                            </dx:ASPxTextBox>

                                                                                                        </td>

                                                                                                        <td>Tipo Seguro:</td>

                                                                                                        <td>

                                                                                                            <dx:ASPxComboBox ID="cbxTipoSeguro" ClientInstanceName="cbxTipoSeguro" runat="server" Width="150" ValueType="System.String">

                                                                                                                <Items>

                                                                                                                    <dx:ListEditItem Value="0" Text="No definido" Selected="True" />

                                                                                                                    <dx:ListEditItem Value="1" Text="Seguro Banco" />

                                                                                                                    <dx:ListEditItem Value="2" Text="Seguro Cliente" />

                                                                                                                </Items>

                                                                                                                <ClientSideEvents SelectedIndexChanged="onTipoSeguroChanged" />

                                                                                                            </dx:ASPxComboBox>

                                                                                                        </td>

                                                                                                    </tr>

                                                                                                    <tr>

                                                                                                        <td>Estado Póliza:</td>

                                                                                                        <td>

                                                                                                            <dx:ASPxComboBox ID="cbxEstadoPoliza"

                                                                                                                ClientInstanceName="cbxEstadoPoliza"

                                                                                                                runat="server"

                                                                                                                Width="150"

                                                                                                                ValueType="System.String"

                                                                                                                OnCallback="cbxEstadoPoliza_Callback" />

                                                                                                        </td>

                                                                                                        <td>Fecha Término Ini:</td>

                                                                                                        <td>

                                                                                                            <dx:ASPxDateEdit ID="dtFechaTerminoIni" ClientInstanceName="dtFechaTerminoIni" runat="server" Width="150" />

                                                                                                        </td>

                                                                                                        <td>Fecha Término Fin:</td>

                                                                                                        <td>

                                                                                                            <dx:ASPxDateEdit ID="dtFechaTerminoFin" ClientInstanceName="dtFechaTerminoFin" runat="server" Width="150" />

                                                                                                        </td>

                                                                                                        <td>&nbsp;</td>

                                                                                                        <td>&nbsp;</td>

                                                                                                    </tr>

                                                                                                </table>


                                                                                                <!-- Botones -->

                                                                                                <table class="style2">

                                                                                                    <tr>

                                                                                                        <td>

                                                                                                            <dx:ASPxButton ID="btnBuscar" runat="server" AutoPostBack="false"

                                                                                                                CssClass="btn_buscar" ClientInstanceName="btnBuscar" Cursor="pointer"

                                                                                                                EnableDefaultAppearance="False" EnableTheming="False" Text="Recuperar">

                                                                                                                <ClientSideEvents Click="function(s, e){ onBuscarClick(); }" />

                                                                                                            </dx:ASPxButton>

                                                                                                        </td>

                                                                                                        <td>&nbsp;</td>

                                                                                                        <td>

                                                                                                            <input type="button" value="Exportar" name="btnImprimir" onclick="excel();" class="btn_excel" /></td>

                                                                                                        <td>

                                                                                                            <dx:ASPxButton ID="btnLimpiar" runat="server" AutoPostBack="false"

                                                                                                                CssClass="btn_limpiar" ClientInstanceName="btnLimpiar" Cursor="pointer"

                                                                                                                EnableDefaultAppearance="False" EnableTheming="False" Text="Limpiar">

                                                                                                                <ClientSideEvents Click="function(s, e){ onLimpiarClick(); }" />

                                                                                                            </dx:ASPxButton>

                                                                                                        </td>

                                                                                                    </tr>

                                                                                                </table>

                                                                                            </td>

                                                                                            <td>&nbsp;</td>

                                                                                        </tr>

                                                                                    </table>

                                                                                </td>

                                                                            </tr>

                                                                            <tr>

                                                                                <td>

                                                                                    <div class="modul_bottom">

                                                                                        <div class="modul_bottom_right">

                                                                                            <div class="modul_borde-bottom"></div>

                                                                                        </div>

                                                                                    </div>

                                                                                </td>

                                                                            </tr>

                                                                        </table>

                                                                    </td>

                                                                </tr>

                                                            </table>

                                                        </td>

                                                    </tr>

                                                </table>

                                            </td>

                                        </tr>

                                        <tr>

                                            <td valign="top">&nbsp;</td>

                                        </tr>


                                        <!-- ===== GRID EN PANTALLA ===== -->

                                        <tr>

                                            <td valign="top">

                                                <dx:ASPxGridView ID="gvInforme" runat="server"

                                                    ClientInstanceName="gvInforme"

                                                    Width="100%" AutoGenerateColumns="True"

                                                    OnCustomCallback="gvInforme_CustomCallback">

                                                    <Settings ShowGroupPanel="False" />

                                                    <SettingsBehavior AllowGroup="False" />

                                                    <SettingsText GroupPanel="" />

                                                    <Settings ShowHorizontalScrollBar="true" ShowVerticalScrollBar="true" VerticalScrollableHeight="320" />

                                                    <SettingsPager Mode="ShowAllRecords" />

                                                </dx:ASPxGridView>




                                            </td>

                                        </tr>

                                    </table>

                                </ContentTemplate>

                            </asp:UpdatePanel>

                        </td>

                        <td width="10">&nbsp;</td>

                    </tr>

                </table>

            </td>

        </tr>

    </table>

</asp:Content>



.CS

using System;
using System.Data;
using System.Globalization;
using System.Web.Services;
using DevExpress.Web.ASPxGridView;
using LeaOperBussinesLayer.BussinesComponents.AdmSeguros.SolicitudSeguros;
using LeaseOperWeb.Negocio.Comun;
using LeaseOperWeb.Utils;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Web.UI.WebControls;
using DevExpress.Web.ASPxGridView;


namespace LeaseOperWeb.Paginas.AdmSeguros.Consultas
{
    public partial class InformeBienesAsegurados : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e) { }

        protected void cbxEstadoPoliza_Callback(object source, DevExpress.Web.ASPxClasses.CallbackEventArgsBase e)
        {
            cbxEstadoPoliza.Items.Clear();

            int ts;
            if (int.TryParse(e.Parameter, out ts) && (ts == 1 || ts == 2))
            {
                DataTable dt = new SolicitudSegurosBc().ListarEstadosPolizaPorTipoSeguro(ts);
                if (dt != null)
                {
                    foreach (DataRow r in dt.Rows)
                    {
                        var text = Convert.ToString(r["desc_valor"]);
                        var val = Convert.ToString(r["valor"]);
                        cbxEstadoPoliza.Items.Add(text, val);
                    }
                    if (cbxEstadoPoliza.Items.Count > 0) cbxEstadoPoliza.SelectedIndex = 0;
                }
            }
        }


        protected void gvInforme_CustomCallback(object sender, ASPxGridViewCustomCallbackEventArgs e)
        {
            try
            {
                string[] p = (e.Parameters ?? "").Split('|');
                string rutCliente = p.Length > 0 ? p[0] : string.Empty;
                string operacion = p.Length > 1 ? p[1] : string.Empty;
                string ultimaPoliza = p.Length > 2 ? p[2] : string.Empty;
                string tipoSeguro = p.Length > 3 ? p[3] : string.Empty;
                string estadoPoliza = p.Length > 4 ? p[4] : string.Empty;
                string fechaTerminoIni = p.Length > 5 ? p[5] : string.Empty;
                string fechaTerminoFin = p.Length > 6 ? p[6] : string.Empty;

                int rutCliente0 = RutSinDv(rutCliente);                  
                long operacion0 = ToNullableLong(operacion) ?? 0L;
                int ultimaPoliza0 = ToNullableInt(ultimaPoliza) ?? 0;
                int tipoSeguro0 = ToNullableInt(tipoSeguro) ?? 0;
                int estadoPoliza0 = ToNullableInt(estadoPoliza) ?? 0;
                DateTime? fechaIni = ToNullableDate(fechaTerminoIni);
                DateTime? fechaFin = ToNullableDate(fechaTerminoFin);

                byte? tipoSalida = 1;

                DataTable raw = new SolicitudSegurosBc().ListarPolizasClientesBienesAsegurados(
                    tipoSalida, rutCliente0, operacion0, ultimaPoliza0, tipoSeguro0, estadoPoliza0, fechaIni, fechaFin);

                if (raw == null || raw.Rows.Count == 0)
                {
                    gvInforme.DataSource = null;
                    gvInforme.DataBind();
                    return;
                }

                Dictionary<string, string> captions;
                DataTable dt = SanitizeColumns(raw, out captions);
                BuildGridColumns(dt, captions);

                gvInforme.DataSource = dt;
                gvInforme.DataBind();
            }
            catch
            {
                gvInforme.DataSource = null;
                gvInforme.DataBind();
            }
        }





        private static int? ToNullableInt(string s)
        {
            if (int.TryParse(s, out var v)) return v;
            return null;
        }

        private static long? ToNullableLong(string s)
        {
            if (long.TryParse(s, out var v)) return v;
            return null;
        }

        private static DateTime? ToNullableDate(string s)
        {
            if (string.IsNullOrWhiteSpace(s)) return null;
            if (DateTime.TryParseExact(s, "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out var d))
                return d;
            if (DateTime.TryParse(s, out d)) return d;
            return null;
        }
        [WebMethod]
        public static string ReporteXls(
            string iddoc,
            string hoja,
            string rutCliente,
            string operacion,
            string ultimaPoliza,
            string tipoSeguro,
            string estadoPoliza,
            string fechaTerminoIni,
            string fechaTerminoFin)
        {
            string salida = string.Empty;
            try
            {
                int rutCliente0 = RutSinDv(rutCliente);
                long operacion0 = ToNullableLong(operacion) ?? 0L;
                int ultimaPoliza0 = ToNullableInt(ultimaPoliza) ?? 0;
                int tipoSeguro0 = ToNullableInt(tipoSeguro) ?? 0;
                int estadoPoliza0 = ToNullableInt(estadoPoliza) ?? 0;
                DateTime? fechaIni = ToNullableDate(fechaTerminoIni);
                DateTime? fechaFin = ToNullableDate(fechaTerminoFin);

                byte? tipoSalida = 1;

                DataTable dt = new SolicitudSegurosBc().ListarPolizasClientesBienesAsegurados(
                    tipoSalida, rutCliente0, operacion0, ultimaPoliza0, tipoSeguro0, estadoPoliza0, fechaIni, fechaFin);

                if (dt == null || dt.Rows.Count == 0)
                    return JsonConvert.SerializeObject("SD");

                string sheet = string.IsNullOrWhiteSpace(hoja) ? "BienesAsegurados" : hoja;
                salida = FuncionesGenericasWebBc.bajarExcel(dt, sheet);
            }
            catch (Exception exc)
            {
                salida = "*" + exc.Message.Replace("'", " ") + "*";
            }
            return JsonConvert.SerializeObject(salida);
        }



        [WebMethod]
        public static string GetRutaCRError()
        {
            return JsonConvert.SerializeObject(new FuncionesGenericas().MapPathURLCRError());
        }

        [WebMethod]
        public static string GetRutaCargaExcel()
        {
            return JsonConvert.SerializeObject(new FuncionesGenericas().MapPathURLExcelDownLoad());
        }

        private static int RutSinDv(string rut)
        {
            if (string.IsNullOrWhiteSpace(rut)) return 0;
            string s = (rut ?? "").Trim().ToUpper().Replace(".", "");
            int guion = s.IndexOf('-');
            if (guion > 0) s = s.Substring(0, guion);
            else if (s.Length > 1) s = s.Substring(0, s.Length - 1);
            int v; return int.TryParse(s, out v) ? v : 0;
        }

        private static DataTable SanitizeColumns(DataTable src, out Dictionary<string, string> captions)
        {
            captions = new Dictionary<string, string>();
            var dt = src.Copy();

            foreach (DataColumn c in dt.Columns)
            {
                string original = c.ColumnName;
                string safe = Regex.Replace(original, @"[^\w]", "_");   // reemplaza espacios, puntos, etc.
                safe = Regex.Replace(safe, "_{2,}", "_");               // colapsa __
                if (char.IsDigit(safe[0])) safe = "_" + safe;           // no iniciar con dígito
                if (safe != original) c.ColumnName = safe;
                captions[c.ColumnName] = original;                      // guarda caption
            }
            return dt;
        }

        private void BuildGridColumns(DataTable dt, IDictionary<string, string> captions)
        {
            gvInforme.Columns.Clear();
            gvInforme.KeyFieldName = dt.Columns.Contains("ID") ? "ID" : dt.Columns[0].ColumnName;

            foreach (DataColumn col in dt.Columns)
            {
                var gcol = new GridViewDataTextColumn
                {
                    FieldName = col.ColumnName,
                    Caption = captions.ContainsKey(col.ColumnName) ? captions[col.ColumnName] : col.ColumnName
                };

                if (col.DataType == typeof(DateTime))
                    gcol.PropertiesTextEdit.DisplayFormatString = "dd/MM/yyyy";

                if (col.DataType == typeof(decimal) || col.DataType == typeof(double) || col.DataType == typeof(float) || col.DataType == typeof(int) || col.DataType == typeof(long))
                    gcol.CellStyle.HorizontalAlign = HorizontalAlign.Right;

                gvInforme.Columns.Add(gcol);
            }
        }


    }
}