web-dev-qa-db-fra.com

json analyse d'erreur erreur de syntaxe fin inattendue de l'entrée

J'ai le code suivant

function pushJsonData(productName) {
    $.ajax({
        url: "/knockout/SaveProduct",
        type: "POST",
        contentType: "application/json",
        dataType: "json",
        data: " { \"Name\" : \"AA\" } ",
        async: false,
        success: function () {
            loadJsonData();   
        },
        error: function (jqXHR, textStatus, errorThrown) {
          alert(textStatus + " in pushJsonData: " + errorThrown + " " + jqXHR);
        }
    });
}

Notez que j'ai codé en dur la valeur des données. Les données sont poussées dans la base de données. Cependant, je continue à avoir l'erreur "erreur syntaxique d'analyse syntaxique erreur de fin inattendue". Je suis sûr que mes données sont dans la syntaxe JSON correcte. Lorsque j'ai vérifié avec l'inspecteur Network of Chrome, la demande saveProduct a montré que les données sont correctes. 

{ "Name": "AA" }

Cette demande POST n'avait pas de réponse. Donc, je ne sais pas d'où vient l'erreur d'analyse. J'ai essayé d'utiliser le navigateur FireFox. la même chose s'est produite.

Quelqu'un peut-il donner une idée de ce qui ne va pas?

Merci, 

P.S . Voici le code du contrôleur

namespace MvcApplJSON.Controllers
{
    public class KnockoutController : Controller
    {
        //
        // GET: /Knockout/

        public ActionResult Index()
        {
            return View();
        }

        [HttpGet]
        public JsonResult GetProductList()
        {
            var model = new List<Product>();
            try
            {
                using (var db = new KOEntities())
                {
                    var product = from p in db.Products orderby p.Name select p;
                    model = product.ToList();
                }
            }
            catch (Exception ex)
            { throw ex; }
            return Json(model, JsonRequestBehavior.AllowGet);
        }
        [HttpPost]
        public void SaveProduct (Product product)
        {
            using (var db = new KOEntities())
            {
                db.Products.Add(new Product { Name = product.Name, DateCreated = DateTime.Now });
                db.SaveChanges();
            }
        }
    }
}
43
Shawn

Je ne peux pas dire avec certitude quel est le problème. Peut-être un mauvais personnage, pourrait-être les espaces que vous avez laissés au début et à la fin, aucune idée.

Quoi qu'il en soit, vous ne devriez pas coder votre JSON en tant que chaînes comme vous le faisiez. Au lieu de cela, le moyen approprié d'envoyer des données JSON au serveur consiste à utiliser un sérialiseur JSON:

data: JSON.stringify({ name : "AA" }),

Maintenant, sur le serveur, assurez-vous également que vous disposez du modèle de vue approprié, dans l'attente de recevoir cette entrée:

public class UserViewModel
{
    public string Name { get; set; }
}

et l'action correspondante:

[HttpPost]
public ActionResult SaveProduct(UserViewModel model)
{
    ...
}

Maintenant, il y a encore une chose. Vous avez spécifié dataType: 'json'. Cela signifie que vous vous attendez à ce que le serveur retourne un résultat JSON. L'action du contrôleur doit renvoyer JSON. Si votre action du contrôleur renvoie une vue, cela pourrait expliquer l'erreur que vous obtenez. C'est quand jQuery tente d'analyser la réponse du serveur:

[HttpPost]
public ActionResult SaveProduct(UserViewModel model)
{
    ...
    return Json(new { Foo = "bar" });
}

Cela étant dit, dans la plupart des cas, il n'est généralement pas nécessaire de définir la propriété dataType pour effectuer une demande AJAX à une action du contrôleur ASP.NET MVC. La raison en est que, lorsque vous renvoyez un ActionResult spécifique (tel qu'un ViewResult ou un JsonResult), la structure définira automatiquement l'en-tête HTTP correct de la réponse Content-Type. jQuery utilisera ensuite cet en-tête pour analyser la réponse et l'enfouira en tant que paramètre pour le rappel de réussite déjà analysé.

Je suppose que le problème que vous rencontrez ici est que votre serveur n’a pas renvoyé de code JSON valide. Il a renvoyé soit ViewResult ou PartialViewResult, soit vous avez essayé de créer manuellement un JSON cassé dans l'action de votre contrôleur (ce que vous ne devriez évidemment pas faire, mais utilisez plutôt JsonResult).

Une dernière chose que je viens de remarquer:

async: false,

Évitez de définir cet attribut sur false. Si vous définissez cet attribut sur false, vous bloquez le navigateur du client pendant toute l’exécution de la demande. Vous pouvez simplement faire une demande normale dans ce cas. Si vous souhaitez utiliser AJAX, commencez à penser en termes d'événements asynchrones et de rappels.

66
Darin Dimitrov

J'utilisais une requête Node http et écoutais l'événement data. Cet événement place uniquement les données dans un tampon temporairement, de sorte qu'un fichier JSON complet n'est pas disponible. Pour résoudre ce problème, chaque événement data doit être ajouté à une variable. Peut aider quelqu'un ( http://nodejs.org/api/http.html ).

4
Ben

Pour moi, le problème était dû à des guillemets simples pour la paire nom/valeur ... Data: "{'Name': 'AA'}"

Une fois que je l’ai changée en guillemets pour la paire nom/valeur, cela fonctionne très bien. Données: '{"Nom": "AA"}. {\ "Nom \":\"AA \"} "

1
Vish

Essayez d'utiliser des guillemets simples,

data: '{"Name":"AA"}'
0

Une fin d'entrée inattendue signifie que l'analyseur s'est terminé prématurément. Par exemple, il peut s’attendre à "abcd...wxyz" mais ne voit que "abcd...wxy

Il peut s'agir d'une erreur typo quelque part ou d'un problème rencontré lorsque les codages sont mélangés dans différentes parties de l'application.

Un exemple: considérons que vous recevez des données d'une application native utilisant chrome.runtime.sendNativeMessage:

chrome.runtime.sendNativeMessage('appname', {toJSON:()=>{return msg}}, (data)=>{
    console.log(data);
});

Maintenant, avant votre rappel est appelé, le navigateur tente d'analyser le message à l'aide de JSON.parse, ce qui peut générer des erreurs de "fin inattendue de la saisie" si longueur d'octet fournie ne correspond pas aux données.

0
Pacerier

Peut-être sera-t-il utile.

Le nom du paramètre de la méthode doit être identique à celui de JSON.

Ça fonctionnera bien

C #

public ActionResult GetMTypes(int id)

JS

 var params = { id: modelId  };
                 var url = '@Url.Action("GetMTypes", "MaintenanceTypes")';
                 $.ajax({
                     type: "POST",
                     url: url,
                     contentType: "application/json; charset=utf-8",
                     dataType: "json",
                     data: JSON.stringify(params),

Cela ne fonctionnera pas bien

C #

public ActionResult GetMTypes(int modelId)

JS

 var params = { id: modelId  };
                 var url = '@Url.Action("GetMTypes", "MaintenanceTypes")';
                 $.ajax({
                     type: "POST",
                     url: url,
                     contentType: "application/json; charset=utf-8",
                     dataType: "json",
                     data: JSON.stringify(params),
0

Je l'ai fait et cela a résolu ce problème.

var data = JSON.parse (Buffer.concat (arr) .toString ());

PS: dans le noeud JS

0