2010-01-06 5 views
0

J'ai une application asp.net MVC. L'une des formes envoie des données json à une méthode publique (pas une action, peut-être plus tard) sur le contrôleur. Cela fonctionne très bien dans IE 8. Cependant, cela ne fonctionne pas dans Firefox 3.5.Post JSON fonctionne dans IE, pas dans FF

La vue est une liste d'objets triés jquery à l'intérieur d'un formulaire. Voici une version dépouillée de la forme:

<form class="cmxform" id="UserForm" method="post" action="/Home/Index"> 
//...the <li> objects that are sortable 
<input type="submit" value="Save Changes" onclick="SaveLinks();" /> 
</form> 

est le javascript ici pour tirer lorsque le bouton est cliqué./Accueil/ProcessLinks est une méthode publique dans le contrôleur, et visible et invisible est un paramètre étant transmis à la méthode:

function SaveLinks() { 
     var VisibleList = document.getElementById('sortable1'); 
     var InvsibleList = document.getElementById('sortable2'); 

     for (var i = 0; i < VisibleList.childNodes.length; i++) { 
      var link = {}; 
      link.id = VisibleList.childNodes[i].childNodes[1].innerText; 
      link.title = VisibleList.childNodes[i].childNodes[2].innerText; 
      link.description = VisibleList.childNodes[i].childNodes[3].innerText; 
      link.url = VisibleList.childNodes[i].childNodes[4].innerText; 
      link.order = i + 1; 

      $.post("/Home/ProcessLinks/Visible", $.toJSON(link), function(data, testStatus) { 
       /*This is where the user can be notified that the item was saved successfully*/ 
       //alert(link.id + " has been updated"); 
       window.location.reload(); 
      }, "text"); 
     } 

     for (var i = 0; i < InvsibleList.childNodes.length; i++) { 
      var link = {}; 
      link.id = InvsibleList.childNodes[i].childNodes[1].innerText; 
      link.title = InvsibleList.childNodes[i].childNodes[2].innerText; 
      link.description = InvsibleList.childNodes[i].childNodes[3].innerText; 
      link.url = InvsibleList.childNodes[i].childNodes[4].innerText; 
      link.order = i + 1; 

      $.post("/Home/ProcessLinks/Invisible", $.toJSON(link), function(data, testStatus) { 
       /*This is where the user can be notified that the item was saved successfully*/ 
       //alert(link.id + " has been updated"); 
       window.location.reload(); 
      }, "text"); 
     } 
    } 

Je crois que la méthode ci-dessus ne soit pas déclenchée lorsque dans Firefox, comme les points d'arrêt que je place avec Firebug ne sont pas touchés.

Pour le plaisir, voici ma fonction Serverside:

public string ProcessLinks(string id) 
    { 
     string Type = id; 
     string json = Request.Form[0]; 

     var serializer = new DataContractJsonSerializer(typeof(JsonObject)); 
     var memoryStream = new MemoryStream(Encoding.Unicode.GetBytes(json)); 
     JsonObject item = (JsonObject)serializer.ReadObject(memoryStream); 
     memoryStream.Close(); 

     return "hello"; 
    } 

Et ma classe personnalisée JsonObject:

[DataContract] 
public class JsonObject 
{ 
     [DataMember] 
     internal int id { get; set; } 

     [DataMember] 
     internal string title { get; set; } 

     [DataMember] 
     internal string description { get; set; } 

     [DataMember] 
     internal string order { get; set; } 

     [DataMember] 
     internal string url { get; set; } 
} 

Avez-vous une idée de ce que je fais mal? Je n'arrive pas à l'abattre.

Répondre

2

Mise à jour: après avoir regardé le code que vous avez téléchargé j'ai supprimé le bouton <input type="submit... de la forme et ajouté une balise button en dehors de la forme comme ceci:

</form> 
<button onclick="SaveLinks();">Save Changes</button> 

Après avoir cliqué ce que je suis une erreur FireFox:

"VisibleList.childNodes[i].childNodes[1] is undefined" 

pour corriger cela, je pris le code de la réponse de jerjer (je devais modifier un peu) et est venu avec lasuivante 0 méthode qui fonctionne en FF.

function SaveLinks() { 
    $('#sortable1 li').each(function(i, item) { 
     var divs = $('div:not(.imagecontainer)', this); 

     var link = { 
      id: $(divs[0]).text(), 
      title: $(divs[1]).text(), 
      description: $(divs[2]).text(), 
      url: $(divs[3]).text(), 
      order: i + 1 
     }; 

     $.post("/Home/ProcessLinks/Visible", $.toJSON(link), function(data, testStatus) { 
      /*This is where the user can be notified that the item was saved successfully*/ 
      alert(link.id + " has been updated"); 
      //window.location.reload(); 
     }, "text"); 
    }); 

    $('#sortable2 li').each(function(i, item) { 
     var divs = $('div:not(.imagecontainer)', this); 

     var link = { 
      id: $(divs[0]).text(), 
      title: $(divs[1]).text(), 
      description: $(divs[2]).text(), 
      url: $(divs[3]).text(), 
      order: i + 1 
     }; 

     $.post("/Home/ProcessLinks/Invisible", $.toJSON(link), function(data, testStatus) { 
      /*This is where the user can be notified that the item was saved successfully*/ 
      alert(link.id + " has been updated"); 
      //window.location.reload(); 
     }, "text"); 
    }); 
    return false; 
} 
+0

La raison pour laquelle je publie chaque objet plutôt que l'ordre de la liste est parce que les propriétés des objets peuvent être modifiées avant la publication. Je refactoriserai une fois que cette preuve de concept sera disponible – splatto

+0

Oui, ça marche. Je vais télécharger un fichier zip de la solution pour vous si vous souhaitez voir ce que je fais. – splatto

+0

J'ai téléchargé les fichiers de solution sur http://splatto.net/content/sort.zip. – splatto

4

Firefox ne prend pas en charge innerText. Utilisez innerHTML à la place.

Une autre raison possible est le code HTML suivant:

<div> 
    <span>foo</span> 
    <span>bar</span> 
</div> 

aura la structure suivante dans IE

div 
    |---span(childNode[0]) 
    |  | 
    |  '---text---foo 
    | 
    '---span(childNode[1]) 
      | 
      '---text---bar 

alors que dans tous les autres navigateurs comme Firefox, il aura la structure suivante:

div 
    |---text(childNode[0])---newline and tabs 
    | 
    |---span(childNode[1]) 
    |  | 
    |  '---text---foo 
    | 
    |---text(childNode[2])---newline and tabs 
    | 
    '---span(childNode[3]) 
      | 
      '---text---bar 

Ce comportement ridicule est mandaté par la spécification W3C. Donc, IE est techniquement mauvais ici.

Maintenant, je remarque dans votre code que vous faites des suppositions sur l'indexation childNode sans vérifier element.nodeName. Cela pourrait être le problème.

+1

bien que innerHTML aussi ne fait pas partie du W3C Spécification DOM – Xinus

+0

Terminé. L'application ne fonctionne toujours pas car je ne crois pas que cela arrive même à cette fonction dans Firefox. – splatto

+3

+1 bonne explication des différences de structure dom. – Jared

1

Puisque vous utilisez jquery, vous pourriez aussi bien utiliser le raccourci du jquery pour obtenir/réglage text/html.

par exemple obtenir le contenu du texte:

link.id = $(VisibleList.childNodes[i].childNodes[1]).text(); 
link.title = $(VisibleList.childNodes[i].childNodes[2]).text(); 
link.description = $(VisibleList.childNodes[i].childNodes[3]).text(); 
link.url = $(VisibleList.childNodes[i].childNodes[4]).text(); 
link.order = i + 1; 

obtenir le contenu html:

link.id = $(VisibleList.childNodes[i].childNodes[1]).html(); 
link.title = $(VisibleList.childNodes[i].childNodes[2]).html(); 
link.description = $(VisibleList.childNodes[i].childNodes[3]).html(); 
link.url = $(VisibleList.childNodes[i].childNodes[4]).html(); 
link.order = i + 1; 

Ceci est l'équivalent jquery:

$('#sortable1 li').each(function(){ 
    var $li = $(this); 
    var link = {}; 
    link.id = $li.children(1).text(); 
    link.title =$li.children(2).text(); 
    link.description = $li.children(3).text(); 
    link.url = $li.children(4).text(); 
    link.order = i + 1; 

    $.post("/Home/ProcessLinks/Visible", $.toJSON(link), function(data, testStatus) { 
     /*This is where the user can be notified that the item was saved successfully*/ 
     //alert(link.id + " has been updated"); 
     window.location.reload(); 
    }, "text"); 
}); 
Questions connexes