JSON帖子在IE中工作,而不是在FF中

时间:2010-01-06 05:46:30

标签: c# javascript jquery asp.net-mvc json

我有一个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 个答案:

答案 0 :(得分:4)

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在技术上错误在这里。

现在,我在您的代码中注意到您在不检查element.nodeName的情况下对childNode索引进行了假设。这可能是问题所在。

答案 1 :(得分:2)

<强>更新 在查看您上传的代码后,我从表单中删除了<input type="submit...按钮,并在表单外添加了button标记,如下所示:

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

点击后我在FireFox中出错:

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

为了纠正这个问题,我从jerjer的答案中获取了代码(我必须对其进行一些修改)并提出了以下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;
}

答案 2 :(得分:1)

由于你使用的是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");
});