【问题标题】:How to correctly format JSON responses (for jQuery) from ASP.NET AJAX?如何正确格式化来自 ASP.NET AJAX 的 JSON 响应(用于 jQuery)?
【发布时间】:2009-03-11 06:13:24
【问题描述】:

各位,我似乎无法让对象序列化在客户端为我的应用程序正常工作?当我在 jQuery 中使用带有 text/json 响应 mime 类型的 getJSON() 方法(使用 JSON.Net 库进行序列化)时,它工作正常,但是一旦我将它移到 ajax() 请求(所以我可以在我的页面上的 webmethods 中发布我的代码)它分崩离析。任何想法将不胜感激。

编辑:我使用的是框架 2.0,而不是 3.5

我的 javascript 看起来像这样:

    function companySearch(txt) 
    {
        $("#<%= divCompanyResult.ClientID %>").hide();
        $("#<%= divCompanyResult.ClientID %>").html("");

        var strCompanySearch = $("#<%= tbCompanySearch.ClientID %>").val();

        $.ajax
        ({
            type: "POST",
            url: "Home.aspx/GetCompanies", 
            contentType: "application/json; charset=utf-8", 
            datatype: "json",
            data: "{name: '" + strCompanySearch + "'} ", 
            success: companySearchSuccess,
            error: onError
        });

        return (true);
    }

    function companySearchSuccess(response)
    {
        $.each(response, 
            function(i, company) 
            {
                $("#<%= divCompanyResult.ClientID %>").prepend(company.Name + "<br />");
            });

        $("#<%= divCompanyResult.ClientID %>").slideDown(1000);
    }

我的 .ASPX 页面(注意,它是一个页面,而不是 Web 服务),如下所示:

    [WebMethod]
    public static Company[] GetCompanies(string name)
    {
        Company[] companies = Company.FindCompanies(name);

        return companies;
    }

返回的对象:

[ActiveRecord]
public class Company : ActiveRecordBase<Company>
{
    private int iD;
    private string name;
    private string accountNo;
    private string streetAddr1;
    private string streetAddr2;
    private string streetSuburb;
    private string streetCity;
    private string postAddr1;
    private string postAddr2;
    private string postSuburb;
    private string postState;
    private string postPC;
    private string accountType;
    private string accountSubType;
    private string areaRep;
    private string status;
    private string overview;
    private string bpcsId;
    private string modifiedBy;
    private DateTime modifiedDate;
    private IList<Contact> contacts;

    [PrimaryKey]
    public int ID { get { return this.iD; } set { this.iD = value; } }
    [Property]
    public string Name { get { return this.name; } set { this.name = value; } }
    [Property]
    public string AccountNo { get { return this.accountNo; } set { this.accountNo = value; } }
    [Property]
    public string StreetAddr1 { get { return this.streetAddr1; } set { this.streetAddr1 = value; } }
    [Property]
    public string StreetAddr2 { get { return this.streetAddr2; } set { this.streetAddr2 = value; } }
    [Property]
    public string StreetSuburb { get { return this.streetSuburb; } set { this.streetSuburb = value; } }
    [Property]
    public string StreetState { get { return this.streetCity; } set { this.streetCity = value; } }
    [Property]
    public string StreetPC { get { return this.streetCity; } set { this.streetCity = value; } }
    [Property]
    public string PostAddr1 { get { return this.postAddr1; } set { this.postAddr1 = value; } }
    [Property]
    public string PostAddr2 { get { return this.postAddr2; } set { this.postAddr2 = value; } }
    [Property]
    public string PostSuburb { get { return this.postSuburb; } set { this.postSuburb = value; } }
    [Property]
    public string PostState { get { return this.postState; } set { this.postState = value; } }
    [Property]
    public string PostPC { get { return this.postPC; } set { this.postPC = value; } }
    [Property]
    public string AccountType { get { return this.accountType; } set { this.accountType = value; } }
    [Property]
    public string AccountSubType { get { return this.accountSubType; } set { this.accountSubType = value; } }
    [Property]
    public string AreaRep { get { return this.areaRep; } set { this.areaRep = value; } }
    [Property]
    public string Status { get { return this.status; } set { this.status = value; } }
    [Property]
    public string Overview { get { return this.overview; } set { this.overview = value; } }
    [Property]
    public string BPCSId { get { return this.bpcsId; } set { this.bpcsId = value; } }
    [Property]
    public string ModifiedBy { get { return this.modifiedBy; } set { this.modifiedBy = value; } }
    [Property]
    public DateTime ModifiedDate { get { return this.modifiedDate; } set { this.modifiedDate = value; } }

    // Inverse ensures is read-only ie. Contact controls the relationship
    // Castle will usually infer relationship, but we explicitly set just to be on the safe side
    [HasMany(Inverse=true, Table="Contact", ColumnKey="CompanyId")] 
    [ScriptIgnore]
    public IList<Contact> Contacts { get { return this.contacts; } set { this.contacts = value; } }

    protected Company() { }

    public Company(string Name, string StreetAddr1)
    {
        this.Name = Name;
        this.StreetAddr1 = StreetAddr1;

        ModifiedBy = "Test";
        ModifiedDate = DateTime.Now;
    }

    public static Company[] FindCompanies(string name)
    {
        return FindAll(Expression.InsensitiveLike("Name", "%" + name + "%"));
    } 
}

【问题讨论】:

    标签: asp.net jquery


    【解决方案1】:

    原来我在我的 ajax 请求中忽略了 dataType 属性的驼峰式大小写

    旧:

        $.ajax
        ({
            type: "POST",
            url: "Home.aspx/GetCompanies", 
            contentType: "application/json; charset=utf-8", 
            datatype: "json",
            data: "{name: '" + strCompanySearch + "'} ", 
            success: companySearchSuccess,
            error: onError
        });
    

    解决方案

        $.ajax
        ({
            type: "POST",
            url: "Home.aspx/GetCompanies", 
            contentType: "application/json; charset=utf-8", 
            dataType: "json",
            data: "{name: '" + strCompanySearch + "'} ", 
            success: companySearchSuccess,
            error: onError
        });
    

    希望这可以帮助其他人避免我遭受的搜索谷歌、教程和博客的时间……Doh!

    【讨论】:

    • 嘿,我只花了 30 分钟扯头发,试图弄清楚为什么我的脚本无法读取我的对象......这正是这个错误! :( Bloomin'区分大小写的语言。
    【解决方案2】:

    Microsoft 的 WebMethods 将返回数据编码到名为“d”的对象中。因此,您需要将代码更改为如下所示:

    function companySearchSuccess(response)
    {
      // Get encoded data
      response = response.d; // you could rename this, or just change the variable reference
    
    }
    

    这样做是为了防止一种特殊的 javascript 漏洞利用。你可以看到更多细节herehere

    【讨论】:

    • 啊,可怕的“d”。如果你问我,非常有问题的安全“功能”......无论如何,“response = response.d || response;”会更合适,因为早期版本的 ASP.NET 不使用“d”包装器。
    • 不幸的是,我使用的是框架 2.0,所以这不是解决方案。我已经用 Firebug 检查了响应,并且字符串没有包装到“d”对象中......
    • @Tsvetomir:很好的补充。但是,是的,这个“特性”使得 webmethods 与其他框架非常不兼容,这可能是一个真正的痛苦。
    猜你喜欢
    • 2013-05-29
    • 1970-01-01
    • 2015-05-05
    • 2014-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多