Javascript ASP.Net Web服务中的JSON数组类型解析

Javascript ASP.Net Web服务中的JSON数组类型解析,javascript,asp.net,jquery,vb.net,webservice-client,Javascript,Asp.net,Jquery,Vb.net,Webservice Client,因此,我已经研究出如何将自定义对象传递到ASP.NETJSON Web服务中。他很有魅力 我遇到的问题是传入自定义对象的直数组,或者传入作为自定义对象参数的数组 比如说 Public Class WebService1 Inherits System.Web.Services.WebService <WebMethod()> _ <ScriptMethod(ResponseFormat:=ResponseFormat.Json)> _ P

因此,我已经研究出如何将自定义对象传递到ASP.NETJSON Web服务中。他很有魅力

我遇到的问题是传入自定义对象的直数组,或者传入作为自定义对象参数的数组

比如说

Public Class WebService1
    Inherits System.Web.Services.WebService

    <WebMethod()> _
    <ScriptMethod(ResponseFormat:=ResponseFormat.Json)> _
    Public Function AddPersonList(ByVal PersonList As PersonList) As String
        Debug.Assert(False)
    End Function

    Public Class Person
        Public Sub New()
        End Sub

        Public Property FirstName As String
        Public Property LastName As String
    End Class

    Public Class PersonList
        Inherits List(Of Person)

    End Class
End Class

<script>
        $(function () {
            $.ajax({
                type: "POST",
                url: "WebService1.asmx/AddPersonList",
                data: " { PersonList: [ { FirstName: 'Max', LastName: 'Gershkovich' }, { FirstName: 'Test1', LastName: 'Test2' } ] }",
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: function (e) { debugger; },
                error: function (e) { debugger; }
            });
        });
    </script>
我可以使用以下代码重新创建错误。

Public Function AddPersonList(ByVal PersonList As String) As PersonList
Dim PersonList As PersonList = jsonSerializer.Deserialize(Of PersonList)(PList)
Dim jsonSerializer As New JavaScriptSerializer(New MyCustomTypeResolver)
但是,当我按照

Public Function AddPersonList(ByVal PersonList As String) As PersonList
Dim PersonList As PersonList = jsonSerializer.Deserialize(Of PersonList)(PList)
Dim jsonSerializer As New JavaScriptSerializer(New MyCustomTypeResolver)
我可以成功创建自定义列表的实例。

<system.web.extensions>
    <scripting>
      <webServices>
        <jsonSerialization>
          <converters>
            <add name="MyCustomConverter" type="WebApplication1.MyCustomConverter" />
          </converters>
        </jsonSerialization>
      </webServices>      
    </scripting>
  </system.web.extensions>
现在,我已经知道如何在web.config文件中提供自己的自定义转换器。沿着这条路线……

<system.web.extensions>
    <scripting>
      <webServices>
        <jsonSerialization>
          <converters>
            <add name="MyCustomConverter" type="WebApplication1.MyCustomConverter" />
          </converters>
        </jsonSerialization>
      </webServices>      
    </scripting>
  </system.web.extensions>
现在需要将其更改为

Customer {CustomerID AS Guid, FirstName AS String, LastName AS String, EmailAddresses AS List(Of EmailAddress)} 

诚然,这并不是世界末日,在webservice上下文中可能更好(正如您所建议的),但在我的集合属性的内部应用程序使用方面,这无疑是一种损害。这意味着,一旦我拥有了这个属性,每当我想使用一些高级功能时,我要么需要将它强制转换到CustomCollectionList,要么需要实现另一个公开CustomCollectionList的属性。任何一种解决方案都会让我感到恶心。

您的数据似乎与JSON格式不一致。请尝试使用

data: " { PersonList: [ { 'FirstName': 'Max', 'LastName': 'Gershkovich' }, { 'FirstName': 'Test1', 'LastName': 'Test2' } ] }"

为了安全起见,请使用json库将数据转换为json。

只是猜测一下,您的数据字符串中是否有前导空格?在“和{”之间

试着去掉空格。有什么变化吗?

首先是数据

{ PersonList: [ { FirstName: 'Max', LastName: 'Gershkovich' }, { FirstName: 'Test1', LastName: 'Test2' } ] }
您发送到web服务的JSON数据错误。您可以在上验证数据。将显示正确的JSON数据

{"PersonList":[{"FirstName":"Max","LastName":"Gershkovich"},{"FirstName":"Test1","LastName":"Test2"}]}
此外,我建议您不要手动创建JSON。而应该使用此功能。在大多数情况下,此功能甚至可以在web浏览器中使用(更新后的某个时间,如)。可以对web服务参数进行正确的序列化

$.ajax({
    data: {PersonList:JSON.stringify(t)} 
    // other parameters
});
(有关更多详细信息,请参阅)或

在哪里

哪个版本的数据表示法
JSON.stringify({PersonList:t})
{PersonList:JSON.stringify(t)}
是正确的取决于其他因素。很容易测试哪个版本在您的环境中起作用

下一个小问题:您最好在
AddPersonList
的参数中直接使用
List(Of Person)
,而不是使用继承自
List(Of Person)
的类型
PersonList

更新:刚才我读了你对
名单(个人)的评论
PersonList
的另一个答案。为了避免同样的讨论,我决定写下我的观点。在web服务内部使用哪些类并不重要。您应该设计web服务的界面,使其简单明了实现。方法的输入数据(至少你在问题中包含的数据)可以用
List(of Person)
完美地描述。而且
List(of Person)
有利于数据传输。在方法实现内部你可以转换
List(of Person)
到任何其他对方法内部有好处的类。例如,从
列表(人员)
构建
PersonList
非常简单。因此我建议您遵循以下方法:保持web服务的接口不受实现细节的影响

更新2:如果作为web方法输入参数的对象具有另一个对象的属性,如
列表(电子邮件地址)
,则根本没有问题。例如,如果您将上一个示例中的
电子邮件地址定义为

Public Class EmailAddress
    Public Property Type As String
    Public Property Address As String
End Class
客户
喜欢

Public Class Customer
    'Public CustomerID As Guid
    Public Property FirstName As String
    Public Property LastName As String
    Public Property EmailAddresses As List(Of EmailAddress)
End Class
这样,您就不会对如下定义的
AddPersonList
web方法有任何问题

<WebMethod()> _
Public Function AddPersonList(ByVal PersonList As List(Of Customer)) As String
var myData = [
        { FirstName: 'Max', LastName: 'Gershkovich',
            EmailAddresses: [
                { Type: 'SMTP', Address: 'Max.Gershkovich@googlemail.com' },
                { Type: 'SMTP', Address: 'Max.Gershkovich@mail.ru' },
            ]
        },
        { FirstName: 'Test1', LastName: 'Test2' }
    ];
或许多其他版本的对象,使用
$.ajax
将信息发送到web服务器

在客户端,您可以定义
myData
,如下所示

<WebMethod()> _
Public Function AddPersonList(ByVal PersonList As List(Of Customer)) As String
var myData = [
        { FirstName: 'Max', LastName: 'Gershkovich',
            EmailAddresses: [
                { Type: 'SMTP', Address: 'Max.Gershkovich@googlemail.com' },
                { Type: 'SMTP', Address: 'Max.Gershkovich@mail.ru' },
            ]
        },
        { FirstName: 'Test1', LastName: 'Test2' }
    ];
然后使用将数据发送到web服务器

$.ajax({
    type: "POST",
    url: "WebService1.asmx/AddPersonList",
    data: JSON.stringify({ PersonList: myData }),
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function (data) {
        alert(data.d);
    },
    error: function (xhr, textStatus, errorThrown) {
        alert("Error Occured!" + " | " + xhr.responseText + " | " +
              textStatus + " | " + errorThrown);
    }
});

以上所有功能都可以正常工作。您可以下载这些功能(应启动Default.htm。要调用该方法,请单击第一个或第二个按钮)

如果您查看客户机代码中定义的
myData
对象,然后查看上面
JSON的用法。stringify
,您将看到在发送任何复杂对象(包括数组和属性)时不会有问题。在服务器端,您可以使用
列表(客户)
列表(指EmailAddress)
或作为JavaScript数组表示形式的其他对象列表。所有这些都将起作用。只有您最初的对象继承示例是不好的


如果您试图从客户端而不是从内部服务器结构设计web服务的接口,您将很容易为web方法的相应输入参数构造类。所有这些都将立即起作用。如果您需要使用信息初始化内部类在上,您将能够非常简单地完成此操作。此类数据转换将非常简单,并且您不需要编写任何自定义类型解析程序,而实际上也需要编写相同的自定义类型解析程序。

更新:第一步将是从.asmx移动到WCF的.svc-它的方式更加灵活,其序列化程序也更加智能

我通常只使用一个泛型列表参数,这到目前为止还没有让我失望

如果需要使用自定义的
ObjectList
属性而不是通用的
list
,那么如何隐藏
ObjectList
属性以防止序列化,并在两者之间使用
list
属性代理

这样,序列化程序可以序列化和反序列化
列表
属性,而您可以
$.ajax({
    type: "POST",
    url: "WebService1.asmx/AddPersonList1",
    data: JSON.stringify({ input: {PersonList: myData} }),
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function (data) {
        alert(data.d);
    },
    error: function (xhr, textStatus, errorThrown) {
        alert("Error Occured!" + " | " + xhr.responseText + " | " +
              textStatus + " | " + errorThrown);
    }
});