2010-05-18 41 views
5

Tengo esto en mi controlador:publicaciones JSON al controlador

[HttpPost] 
    public void UpdateLanguagePreference(string languageTag) 
    { 
     if (string.IsNullOrEmpty(languageTag)) 
     { 
      throw new ArgumentNullException("languageTag"); 
     } 

     ... 
    } 

Y tienen el código de Publicación jQuery para el controlador:

  jQuery.ajax({ 
       type: 'POST', 
       url: '/Config/UpdateLanguagePreference', 
       contentType: 'application/json; charset=utf-8', 
       data: '{ "languageTag": "' + selectedLanguage + '" }' 
      }); 

Cuando intento del código, sin embargo, obtiene el error:

Server Error in '/' Application. 
Value cannot be null. 
Parameter name: languageTag 

¿Cuál es el problema? ¿No es así como POST JSON a un controlador MVC? Puedo examinar el POST utilizando Fiddler y ver si la solicitud es correcta. Por alguna razón, UpdateLanguagePreference() está obteniendo una cadena vacía o nula.

Respuesta

1

hmm ....

lo hago

$.post(target, 
     { 
      "ProblemId": id, 
      "Status": update 
     }, ProcessPostResult); 

con

public class ProblemReportUpdate 
    { 
     public int ProblemId { get; set; } 
     public string Status { get; set; } 
    } 

y

[HttpPost] 
public ActionResult UpdateProblemReport(ProblemReportUpdate update) 

el objetivo se fija por

var target = '<%=Url.Action("UpdateProblemReport", "ProblemReport") %> 
1

Está publicando una cadena y no un objeto JSONificado.

de datos: '{ "languageTag": "' + selectedLanguage + '"}'

debería ser

datos: { "languageTag": selectedLanguage}

Y asegúrese selectedLanguage se define dentro del alcance de su llamada ajax.

+0

Hmm, en realidad no es eso. Un objeto JSONified es una cadena. No hay diferencia entre la cadena que estoy publicando y un objeto JSONified con un miembro llamado "languageTag". – JamesBrownIsDead

+0

@JamesBrownIsDead - En realidad, según tengo entendido, hay una diferencia. Echa un vistazo a mi respuesta a continuación. – kdawg

1

Cuando le asigna a jQuery $ .ajax() una variable de datos en forma de un objeto javascript, en realidad lo traduce en una serie de pares clave/valor y lo envía al servidor de esa manera. Cuando envía el objeto json con cadena, no está en esa forma y el encuadernador de modelo estándar en mvc/mvc2 no lo cortará.

Si desea enviar datos de la publicación de esa manera, está a punto de llegar. Necesita la clase JsonValueProviderFactory que se encuentra en MVC2 Futures/MVC3 Beta. Echar un vistazo a los siguientes enlaces para obtener más información:

http://haacked.com/archive/2010/04/15/sending-json-to-an-asp-net-mvc-action-method-argument.aspx

... hay otro enlace que se utiliza al implementar esto mismo que habló más sobre lo que la clase JsonValueProviderFactory en su aplicación, pero no puedo encontrar por mi vida

7

Advertencia muy importante, incluso en MVC3, sobre la forma en que funciona MVC3.

Si pasa un objeto como por ejemplo:

​{ 
    Test: 'Hi' 
} 

Y la clase de recepción es:

public class MyModel 
{ 
    public string Test { get; set; } 
} 

Con un método de controlador que recibe como:

[HttpPost] 
public JsonResult Submit(MyModel model) 
{ 
    . . . 

Se trabajará. Pero si su método de controlador tiene esta muy menor, el cambio aparentemente inofensivo:

[HttpPost] 
public JsonResult Submit(MyModel test) 
{ 
    . . . 

Se fallará. Esto se debe a que el marco MVC consume el JSON en un diccionario como se menciona anteriormente, y ve que uno de los parámetros tiene el mismo nombre, que no distingue entre mayúsculas y minúsculas, como una de sus claves ("Prueba"/"prueba"). A continuación, toma el valor de cadena "Hi", asignado a Prueba, y lo pasa a este argumento "prueba", aunque esto obviamente no es lo que el autor pretendía.

Lo más problemático de esto es que el framework no arroja un error al intentar asignar una cadena a un arg de tipo MyModel, que al menos le daría una pista sobre lo que salió mal. No ve que este fue el tipo equivocado y la alternativa a su comportamiento alternativo (que hubiera seguido si estas arg/propiedades no coincidieran en el nombre). Simplemente falla silenciosamente y asigna nulo a su argumento, dejándolo sin la menor idea de lo que está sucediendo.

Me he encontrado con este problema repetidamente y finalmente encontré el problema que hace que las cosas parezcan dejar de funcionar aleatoriamente en MVC ... Espero que esto ayude a otra persona. Dado que cualquier nombre razonable para este argumento de Acción es un nombre de propiedad potencialmente razonable loco, muy poco probable-a-siempre-be-a-nombre-propiedad nombre de argumento, como:

[HttpPost] 
public JsonResult Submit(MyModel _$_$twinkleTwinkleLittleFuckIt) 
{ 

Pero si usted tiene el tiempo, fijar la ModelBinder/JsonValueProviderFactory por lo que hay riesgo 0 en lugar de que un extraño error en una década que nadie puede llegar al fondo de.

+0

Funciona como dices, pero si tengo una lista de un objeto dentro del modelo, no se enlaza. Produce una lista vacía – Bryida

Cuestiones relacionadas