He tenido problemas al intentar enviar JSON a los controladores ASP.NET MVC. No quiero aceptar un parámetro de cadena en cada método de controlador y deserializarlo manualmente. Descubrí que construir una colección de variables de publicación funciona de manera confiable, pero no tengo una función generalizada para hacerlo. Puedo escribir uno yo mismo si nadie lo ha hecho ya, pero me resulta muy difícil de creer.

Si nadie contesta esto para mañana, supongo que dejaré de ser perezosa.

Editar: para ser claros, no estoy preguntando cómo serializar objetos .NET en JSON. Me pregunto si alguien ha escrito una función javascript para hacer lo siguiente:

objeto javascript dado:

{ 
    name: { first: "first", last: "last" }, 
    age: 35,
    drinks: [
        { carbonated: false, name: "juice" },
        { carbonated: true, name: "soda" }
    ]
}

devuelve (solicitud POST como objeto):

name.first  :   first
name.last   :   last
age         :   35
drinks[0].carbonated    :   false
drinks[0].name          :   juice
drinks[1].carbonated    :   true
drinks[1].name          :   soda

Gracias.

2
kwcto 6 nov. 2009 a las 01:12

7 respuestas

La mejor respuesta

Depende de qué tan profundo desea que funcione la serialización. Puede usar el método $ .param (obj) en jQuery para hacer simple serialización de objetos, pero no funcionará en su ejemplo, ya que supone que los valores son tipos simples o matrices de tipos simples. Es posible que desee ver el código de param y adaptarlo a sus necesidades especializadas. Esencialmente, necesitaría determinar cuándo el valor es un objeto y usarlo para agregar las claves del objeto a la clave externa al construir las matrices de clave / valor. El manejo de matrices de objetos complejos requeriría algunos ajustes similares para obtener los índices clave configurados correctamente.

Lo siguiente ha sido probado en FF3.5 / IE8. No hay garantías para otros navegadores, pero creo que debería funcionar.

jQuery.extend( {
    isObject: function(obj) {
       return typeof(obj) === "object";
    },
    complexParam: function( a ) {
        var s = [ ];

        function add( key, value ){
            s[ s.length ] = encodeURIComponent(key) + '=' + encodeURIComponent(value);
        };

        // If an array was passed in, assume that it is an array
        // of form elements
        if ( jQuery.isArray(a) || a.jquery )
            // Serialize the form elements
            jQuery.each( a, function(){
                add( this.name, this.value );
            });

        // Otherwise, assume that it's an object of key/value pairs
        else
            // Serialize the key/values
            for ( var j in a )
                // If the value is an array then the key names need to be repeated
                if ( jQuery.isArray(a[j]) )
                    jQuery.each( a[j], function(){
                        if (jQuery.isObject(this)) {
                            var idx = 0;
                            for (var k in this) {
                               add( j + "[" + idx + "]." + k, this[k] );
                               ++idx;
                            }
                        }
                        else {
                             add( j, this );
                        }
                    });
                else {
                    if (jQuery.isFunction(a[j])) {
                       add( j, a[j]() );
                    }
                    else if (jQuery.isObject(a[j])) {
                       for (var k in a[j]) {
                          add( j + "." + k, a[j][k] );
                       }
                    }
                    else {
                        add( j, a[j] );
                    }
                }

        // Return the resulting serialization
        return s.join("&").replace(/%20/g, "+");
    }
});

Llamado

var serialized = $.complexParam( obj );

Tenga en cuenta que esto deja los corchetes codificados en URL. Si eso no está bien, entonces agregue

.replace(/%5B/g, "[").replace(/%5D/g, "]")

Al regreso en complexParam ()

4
tvanfosson 3 dic. 2009 a las 22:48

Esta es una versión de Mootools de lo que quería. En realidad, no sabía que Mootools Hash.toQueryString () casi lo hace por defecto. Formatea los arreglos de una manera que ASP.NET MVC no reconocerá, por lo que aún necesito implementar el mío:

var POSTEncoder = {
getHash: function(request, prefix, out) {

    if($type(out) != 'object') { out = {}; }

    function add(key, value){
        out[ key ] = value;
    };

    var validPrefix = $type(prefix) == 'string';

    switch($type(request)) {
        case 'array':

            if(!validPrefix) { prefix = 'request'; }

            request.each(function(item, i){
                POSTEncoder.getHash(item, prefix + '[' + i + ']', out);
            });

            break;

        case 'object':

            if(!validPrefix) { prefix = ''; }

            new Hash(request).each(function(val, key) {
                POSTEncoder.getHash(val, (prefix != '' ? prefix + '.' : '') + key, out);
            });

            break;

        case 'string':
        case 'number':
        case 'boolean':
        case 'date':

            if(!validPrefix) { prefix = 'request'; }

            add(prefix, request);

            break;
        case false:
            add(prefix || 'request', '');
    }

    return new Hash(out);
}};

POSTEncoder.getHash (solicitud) aplanará la solicitud en pares clave / valor adecuados para un formulario POST. POSTencoder.getHash (request) .toQueryString () lo convertirá en una cadena de consulta.

Ejemplo:

var test = {
bool: true,
strng: 'a',
numbr: 1,
basicArr: ['d','e','f'],
basicObj: {x:1, y: 'z'},
objectArr: [{n:1, o:2}, {n:3,o:4}],
complex: {
    one: 1,
    two: 'two',
    three: [{x:1},{x:2},{x:3}]
}};

var hash = POSTEncoder.getHash(test);

console.log(hash);
console.log(hash.toQueryString());
0
kwcto 8 dic. 2009 a las 15:16

Uso $ .toJSON de jQuery para serializar el objeto en el javascript, y luego deserialícelo del lado del controlador usando Json.Net (I descubrió que el stock JSON deserializado en ASP.NET MVC barfs a veces en algunas entradas).

0
axel_c 3 dic. 2009 a las 10:09

No sé si este es el tipo de respuesta que realmente quieres escuchar, pero personalmente no trataría de empujar absolutamente todo a un objeto JSON en JavaScript, donde todavía necesitas hacer un poco de trabajo en el otro extremo .

La forma en que hago esto actualmente es pasando el valor Request.Form del Controlador al objeto base del modelo, que luego utiliza la reflexión para extraer los valores necesarios de la variable Request.Form y actualizar los valores en el objeto modelo. Básicamente, puede usar una llamada a un solo método para guardar todos los detalles centrales de un objeto sin preocuparse de separar el formulario manualmente. Un ejemplo de esto sería:

Job temp = new Job();
temp.UpdateDetails(Request.Form);

Cualquier cosa más de 10 artículos es probablemente "mucho", pero no demasiado inmediatamente, que todo depende del contexto de su solicitud.…

Si lo desea, puedo entrar en más detalles explicando este método, pero no haré un esfuerzo adicional para explicar cada paso individual si esto no es lo que necesita, ya que me doy cuenta de que no se trata de su pregunta original.

0
Matt Kocaj 2 dic. 2009 a las 08:04

Ya es una pregunta donde alguien ha escrito un filtro de Acción para hacer esto, es posible que desee ver su solución.

Aplicación de enlace / json al objeto POCO en asp.net mvc, excepción de serialización

0
Community 23 may. 2017 a las 12:13

Entonces, está la clase System.Runtime.Serialization.Json.DataContractJsonSerializer en .Net v3.5 y superior. Serializa y deserializa los datos JSON en objetos. Tendrá que hacer referencia al ensamblado System.ServiceModel.Web.

La función System.Web.Mvc.Controller.Json () también puede manejar sus necesidades de serialización.

Entonces tienes el controlador cubierto allí y parece que tienes cubierto el lado de JavaScript, ¿verdad?

0
a7drew 6 nov. 2009 a las 00:59