JSON-пост работает в IE, а не в FF - PullRequest
0 голосов
/ 06 января 2010

У меня есть приложение asp.net MVC. Одна из форм отправляет данные json в открытый метод (не действие, возможно, это будет позже) на контроллере. Это прекрасно работает в IE 8. Однако, это не работает в Firefox 3.5.

Представление представляет собой список сортируемых объектов jquery внутри формы. Вот урезанная версия формы:

<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>

Вот javascript для запуска при нажатии кнопки. / Home / ProcessLinks - это открытый метод в контроллере, а Visible и Invisible - это параметр, передаваемый методу:

 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");
        }
    }

Я считаю, что вышеупомянутый метод не запускается в Firefox, поскольку точки останова, которые я устанавливаю с помощью Firebug, не получают удар.

Ради интереса, вот моя серверная функция:

    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";
    }

И мой пользовательский класс 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; }
}

Ты хоть представляешь, что я делаю не так? Кажется, я не могу это понять.

Ответы [ 3 ]

4 голосов
/ 06 января 2010

Firefox не поддерживает innerText. Вместо этого используйте innerHTML.

Другой возможной причиной является следующий HTML:

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

будет иметь следующую структуру в IE

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

тогда как во всех других браузерах, включая Firefox, он будет иметь следующую структуру:

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

Это нелепое поведение предписано спецификацией W3C. Таким образом, IE технически не прав здесь.

Теперь я заметил, что в вашем коде вы делаете предположения об индексации childNode без проверки element.nodeName. Это может быть, где проблема лежит.

2 голосов
/ 06 января 2010

Обновление: просмотрев загруженный код, я удалил кнопку <input type="submit... из формы и добавил тег button вне формы, например:

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

После нажатия этой кнопки я получил ошибку в FireFox:

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

Чтобы исправить это, я взял код из ответа Джержера (мне пришлось немного его изменить) и предложил следующий метод SaveLinks(), который работает в 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;
}
1 голос
/ 06 января 2010

Поскольку вы используете jquery, вы также можете использовать сокращение jquery для получения / установки text / html.

например, получение текстового содержимого:

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;

получение 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;

Это эквивалент 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");
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...