2010-01-26 31 views
10

Deseo poder enviar JSON en lugar de las QueryStrings estándar cuando realizo una publicación en mis controladores en ASP.Net MVC. Tengo las cosas de Front-End funcionando bien (construyendo y luego enviando mis objetos JSON).ASP.Net MVC: Envío de JSON al controlador

El problema está en el lado del controlador donde los ModelBinders predeterminados que se envían con el marco MVC no son compatibles.

He visto una combinación de formas de evitar esto, una de ellas es aplicar un filtro que toma el objeto como parámetro, usa una biblioteca JSON para deserializarlo, y lo agrega a los parámetros de acción. Esto no es ideal

La otra forma, mejor, es utilizar una Carpeta de modelo personalizada. Todos los que he visto presumen que solo tendrá un modelo y que será una clase en lugar de una variable. Si tienes varios, se descompone.

¿Alguien más ha encontrado esto? Una idea que tuve fue si podía simplemente anular la forma en que MVC maneja el FormCollection e interceptarlo allí, agregando los valores a la colección yo mismo y esperando que MVC pueda hacer el resto de la manera normal. ¿Alguien sabe si eso es posible?

El problema clave, creo, es que mi problema no es vinculante porque mis modelos de vista no son diferentes a como estaban antes. El problema es obtener los valores de la publicación JSON.

Si estoy en lo correcto MVC obtiene los valores de QueryString y los coloca en la colección de formularios que luego se utiliza para ModelBinding. Entonces, ¿no debería el método correcto cambiar la forma en que se asigna el FormCollection?

Ejemplo de una acción:

public ActionResult MyFirstAction(Int32 ID, PersonObject Person, ClassObject ClassDetails) 
{ 
//etc 
} 

Las obras unión normal, JSON y no todo el ejemplo de modelo aglutinantes no va a funcionar bien. Mi mejor solución hasta el momento es convertir el objeto a un diccionario y recorrer cada parametro y unirlo. No parece ideal

+0

Si va a votar esto ¿podría explicar por qué? – Damien

+0

Lo siento, lamentablemente, cuando fui a hacer clic en la estrella favorita, accidentalmente hice clic en el voto hacia abajo, incluso después de que ya lo voté (es por eso que pasó de 5 a 3). Y ahora dijo inmediatamente después de tratar de deshacer lo que accidentalmente hice, que era demasiado tarde para cambiar mi voto, a menos que la pregunta sea editada. Si modificas la pregunta, con gusto arreglaré mi voto. – jamesaharvey

+0

¡Ningún problema! Eso me pasa a mí también muchas veces. – Damien

Respuesta

8

Puedo usar un ligante modelo personalizado para JSON como esto:

public class JsonModelBinder<T> : IModelBinder { 
    private string key; 

    public JsonModelBinder(string requestKey) { 
     this.key = requestKey; 
    } 

    public object BindModel(ControllerContext controllerContext, ...) { 
     var json = controllerContext.HttpContext.Request[key]; 
     return new JsonSerializer().Deserialize<T>(json); 
    } 
} 

Y entonces cablear en Global.asax.cs así:

ModelBinders.Binders.Add(
    typeof(Product), 
    new JsonModelBinder<Product>("ProductJson")); 

Puede leer más sobre esto aquí : Inheritance is Evil: The Epic Fail of the DataAnnotationsModelBinder

EDITAR

El JsonModelBinder se debe utilizar en el parámetro de acción del controlador tipeado como Producto solamente. Int32 y ClassObject deberían recurrir a DefaultModelBinder. ¿Estás experimentando un resultado diferente?

+0

¿Entonces necesitaría definir para qué tipos usarlo? – Damien

+0

Sí, debe especificar los tipos. ¿Puedes describir tu situación con un poco más de detalle? He estado investigando el enlace de modelos más recientemente y hay muchas funcionalidades no obvias. –

+0

Bueno, con los tipos ¿qué hago con los parámetros de acción que son tipos/picaduras primitivos? Si envío ID Int32, producto de clase, crea un problema – Damien

Cuestiones relacionadas