¿Cómo se deben pasar los datos entre Javascript del lado del cliente y el código C # detrás de una aplicación ASP.NET?

21

Estoy buscando la forma más eficiente / estándar de pasar datos entre el código JavaScript del lado del cliente y el código C # detrás de una aplicación ASP.NET. He estado usando los siguientes métodos para lograr esto, pero todos se sienten un poco falsos.

Para pasar datos de JavaScript al código de C # se deben configurar variables ASP ocultas y activar una devolución de datos:

<asp:HiddenField ID="RandomList" runat="server" />

function SetDataField(data) {
      document.getElementById('<%=RandomList.ClientID%>').value = data;
}

Luego, en el código C #, recopilo la lista:

protected void GetData(object sender, EventArgs e)
{
      var _list = RandomList.value;
}

Volviendo al otro lado, a menudo utilizo ScriptManager para registrar una función y pasarle datos durante Page_Load:

ScriptManager.RegisterStartupScript(this.GetType(), "Set","get("Test();",true);

o agrego atributos a los controles antes de una publicación posterior o durante las etapas de inicialización o representación previa:

Btn.Attributes.Add("onclick", "DisplayMessage("Hello");");

Estos métodos me han servido bien y hacen el trabajo, pero simplemente no se sienten completos. ¿Existe una forma más estándar de pasar datos entre JavaScript del lado del cliente y el código de fondo de C #?

He visto algunas publicaciones como esta que describen la clase HtmlElement; ¿Es esto algo que debería investigar?

cwc1983
fuente
55
json.org
Oded
Depende de lo que quieras decir al pasar datos entre el servidor y el cliente. Si los datos se conocen en el momento en que se representa la página, entonces es perfectamente razonable agregar un script para crear sus datos o configurar json a través de una variación literal o similar u otra variación. Si, OTOH, está tratando de tener una página que interactúe con el servidor sin hacer una devolución de datos, entonces ese es un problema completamente diferente. Definitivamente mira a json.
Murph
Por ejemplo. Si lancé un botón desde el cliente que obtuvo algunos datos de un archivo xml. Luego, se realizan algunos cálculos sobre los datos en C #. Entonces quiero que ese resultado final se muestre en una bonita pantalla gráfica de JavaScript. Esa es una devolución de datos en la que el cliente no conoce el resultado hasta después de que se haya generado la devolución.
cwc1983
A partir de ese comentario, aún puede realizar todo el trabajo en el servidor (carga / proceso / retorno), así que, en primera instancia, haría exactamente eso. Formatee los datos como json, incluya el json cuando renderice la página (un literal le permitirá hacer esto). Cuando lo consigas, probablemente quieras hacer algo más asíncrono, pero será lo mismo.
Murph
Gracias a todos. Después de leer el consejo aquí e investigar un poco más, he encontrado un nuevo método para lograr lo que quería hacer. El problema principal que recibía era que cuando realizaba una publicación de Ajax no podía obtener el código del lado del cliente para recordar dónde estaba el programa. Ahora estoy usando JQuery $ Ajax.Post, ya que devuelve una publicación de éxito al cliente para guardar los datos de la sesión.
cwc1983

Respuestas:

9

Puede llamar simple y fácilmente a un método de página estática desde JavaScript como en este ejemplo . Si necesita llamar al método desde varias páginas, puede configurar un servicio web y llamarlo desde Javascript de la misma manera. Ejemplo también incluido a continuación.

Código .aspx

<asp:ScriptManager ID="ScriptManager1" 
EnablePageMethods="true" 
EnablePartialRendering="true" runat="server" />

Código subyacente

using System.Web.Services;

[WebMethod]
public static string MyMethod(string name)
{
    return "Hello " + name;
}

Código Javascript

function test() {
    alert(PageMethods.MyMethod("Paul Hayman"));
}

NOTA: Los métodos de página deben ser estáticos. Esto podría ser problemático para usted, dependiendo de lo que la aplicación esté tratando de hacer. Sin embargo, si la información se basa en la sesión, y está utilizando algún tipo de autenticación integrada, puede colocar un atributo EnableSession en el decorador WebMethod, y eso le permitirá acceder a HttpContext.Current.User, Sesión, etc.

Kasey Speakman
fuente
Gran ejemplo, esto funciona bien y lo usaré. ¡Gracias!
Mausimo
3

Recomiendo echar un vistazo a jQuery. JQuery se puede usar para realizar llamadas AJAX al servidor, que puede devolver datos en cualquier formato que necesite; un buen formato podría ser JSON, ya que se puede usar directamente en javascript.

Para extraer datos del servidor a javascript usando jQuery , las siguientes recuperaciones realizan una solicitud asincrónica a http://youserver.com/my/uri y reciben los datos del servidor en la función suministrada.

$.get("my/uri", 
    function(data) { 
       // client side logic using the data from the server
    })

El envío de datos desde JavaScript al servidor funciona de manera similar:

$.post("my/uri", { aValue : "put any data for the server here" }
    function(data) { 
       // client side logic using the data returned from the server
    })
Christian Horsdal
fuente
Gracias, esto es genial, pero me refiero específicamente a situaciones en las que se realiza una devolución antes de que el cliente sepa qué mostrar. Si el "resultado" se logra a través de c #, ¿cómo puedo "inyectarlo" al cliente?
cwc1983
3

Microsoft ha implementado el UpdatePanelcontrol para hacer ajax, por lo que podría decirse que es la forma "estándar". Sin embargo, personalmente no recomendaría usarlo, no tiene nada que ver con el rico conjunto de funciones y el control que tiene cuando usa JavaScript directamente.

Esta es la forma en que personalmente lo hago:

Cree campos ocultos para cualquier valor del lado del cliente que desee usar en una devolución de datos de página estándar (es decir, cuando el usuario presiona enviar)

<asp:HiddenField ID="selectedProduct" runat="server" />

En el código detrás, registre los controles que desea usar del lado del cliente.

    /* Register the controls we want to use client side */

    string js = "var productBox = document.getElementById('" + selectedProduct.ClientID + "'); ";
    js += "var macCodeBoxBE = document.getElementById('" + beMacCode.ClientID + "'); ";


    ClientScript.RegisterStartupScript(this.GetType(), "prodBox", js, true);

Use una biblioteca javascript * para hacer su publicación / get ajax y luego use JavaScript para actualizar la página en función de la respuesta

$.get("../ajax/BTBookAppointment.aspx?dsl=" + telNumberBox.value + "&date=" + requiredDate.value + "&timeslot=" + ddTimeslot.value, function (response, status, xhr) {

    if (response.indexOf("not available") > -1) {
        loaderImage.src = "../images/cross.png"
        output.innerHTML = response;
    } });

Escriba una página separada "ajax" que anule el método de representación para hacer el trabajo.

protected override void Render(HtmlTextWriter writer)
{
    if (string.IsNullOrEmpty(Request["mac"])) { return; }
    if (string.IsNullOrEmpty(Request["dsl"])) { return; }
    DataLayer.Checkers.BTmacCheckResponse rsp = DataLayer.Checkers.Foo.CheckMAC(Request["dsl"], Request["mac"]);

    writer.Write(rsp.Valid.ToString());
}

* Hay muchas bibliotecas para elegir, incluso puede rodar la suya. Recomendaría jQuery , es estable y tiene un amplio conjunto de características.

Tom Squires
fuente
8
Estoy bastante seguro de que hay un lugar especial en el infierno para las personas que crean fragmentos de JavaScript en el servidor de esa manera
Raynos
1
@Raynos No hay nada de malo en generar el lado del servidor JavaScript.
Tom Squires
2
si desea que el servidor haga algo, envíe una solicitud HTTP (usando XHR) a un URI sensible con datos sensibles. A partir de ahí, el servidor HTTP sabrá qué hacer con él.
Raynos
NO PONGA NADA JS EN EL LADO DEL SERVIDOR. VA SOBRE EL CLIENTE. POR LO TANTO EL NOMBRE CÓDIGO LATERAL DEL CLIENTE. Vaya, la tecla de bloqueo de mayúsculas se atascó.
snowYetis
3

JSON es la mejor forma de realizar la tarea. No mire el problema como un paso entre "C # y JavaScript". Esta forma de pensar conduce a rarezas de código como lo que tienes en la publicación original.

En términos más generales, solo se trata de pasar objetos entre el cliente y el servidor de forma independiente del lenguaje. JSON es excelente para la tarea porque es ampliamente compatible y fácil de leer.

P.Brian.Mackey
fuente
2

Para establecer una etiqueta de entrada que no necesita asp del servidor, puede usar: (o <% #%> para la vinculación de datos de formularios)

html:

<input type="hidden" value='<%= RandomValues %>' name="RANDOM_VALUES" />

control de asp:

<asp:HiddenField ID="RandomList" runat="server" />

para obtener los valores en la devolución de datos

Request.Form["RANDOM_VALUES"]

Si es así, asp controla la entrada oculta, puede usar

Request.Form[RandomList.UniqueID]

La mejor parte de Request.Form es que si tiene varias etiquetas con el mismo atributo "nombre", devolverá el resultado en CSV.

MackPro
fuente