Hodaya Shalom
Hodaya Shalom

Reputation: 4417

Sending a list within an object to Wcf Service

I use Wcf Service and JS.

I send information to my service by AJAX.

I have a function in the service that accepts the following object:

  [DataContract]
    public class Business
    {
        [DataMember]
        public string Name { get; set; }
        [DataMember]
        public string Desc { get; set; }        
        [DataMember]
        public List<BusinessService> Services { get; set; }
    }

the BusinessService.cs:

   [DataContract]
    public class BusinessService
    {
        [DataMember]
        public string Name { get; set; }
        [DataMember]
        public string Desc { get; set; }
        [DataMember]
        public int LongTime { get; set; }
    }

I parse the objects in my JS to JSON and send them to the service.

Here the json that send to the wcf function:

"{"ManageBusiness":{"Name":"aaaaaa","Desc":"aaaaaaaaaaaa","Services":[{"Name":"aaaaaa","Desc":"aaaaaa","LongTime":30},{"Name":"aaaaaa1","Desc":"aaaaaa","LongTime":30}]}}"

Everything works as it should except the Services list.

The list comes to the wcf function as null.

I have no idea why this is happening, I would appreciate help?

Upvotes: 5

Views: 2867

Answers (4)

brando
brando

Reputation: 8431

The following I can say definitively works. I just tested it. Sorry its in vb.net, but you should get the idea.

On the server side: In IService1.vb

Imports System.ServiceModel
Imports System.ServiceModel.Activation
Imports System.ServiceModel.Web

Namespace Webservices
   <ServiceContract()>
    Public Interface IService1

    <OperationContract()> _
    <WebInvoke(method:="POST", ResponseFormat:=WebMessageFormat.Json, BodyStyle:=WebMessageBodyStyle.WrappedRequest)> _
    Function test(manageBusiness As ManagedBusiness) As string

   End Interface
End Namespace

In Service1.svc.vb

Imports System.Runtime.Serialization
Imports System.ServiceModel.Activation
Namespace Webservices
<AspNetCompatibilityRequirements(RequirementsMode:=AspNetCompatibilityRequirementsMode.Required)>
Public Class Service1
    Implements IService1 
    Public function test(manageBusiness As ManagedBusiness) As string Implements IService1.test 
       Return "done"   
     End function    
End Class   

<CollectionDataContract()>
Public Class Services
    Inherits List(Of Service)
End Class

<DataContract()>
Public Class Service
    <DataMember()>Public Property Name As String
    <DataMember()>Public Property Desc As String
    <DataMember()>Public Property LongTime As Integer 
End Class

<DataContract()>
Public Class ManagedBusiness 
    <DataMember()>Public Property Name As String
    <DataMember()>Public Property Desc As String
    <DataMember()>Public Property Services As Services

End Class 
End NameSpace

I wired up the webconfig settings. And put this jquery ajax call on the client side:

$("#btnTest").click(function () {
            var services = [];
            services.push({
                Name: "aaaaaa",
                Desc: "aaaaaa",
                LongTime: 30
            });
            services.push({
                Name: "aaaaaa1",
                Desc: "aaaaaa",
                LongTime: 30
            });
            var data = {};
            data.manageBusiness = {
                Name: "aaaaaa",
                Desc: "aaaaaaaaaaaa",
                Services: services
            }


            $.ajax({
                type: "POST",
                url: "http://localhost:64110/Webservices/Service1.svc/test",
                dataType: "json",
                contentType: "application/json; charset=utf-8",
                async: true,
                data: JSON.stringify(data),
                success(msg) {

                }
            });


        });

I can confirm that the Requested Payload was as follows:

{"manageBusiness":{"Name":"aaaaaa","Desc":"aaaaaaaaaaaa","Services":[{"Name":"aaaaaa","Desc":"aaaaaa","LongTime":30},{"Name":"aaaaaa1","Desc":"aaaaaa","LongTime":30}]}}

And the WCF service deserialized everything just fine. I think what you were missing was the [CollectionDataContract] attribute.

UPDATE: I tried removing the [CollectionDataContract] attribute and it STILL worked. So I am guessing that the data contract attributes are only for serializing, not needed for deserializing (?)

Upvotes: 0

DevAshish
DevAshish

Reputation: 11

try this,

var data = "{"ManageBusiness":{"Name":"aaaaaa","Desc":"aaaaaaaaaaaa","Services":[{"Name":"aaaaaa","Desc":"aaaaaa","LongTime":30},{"Name":"aaaaaa1","Desc":"aaaaaa","LongTime":30}]}}";

Add below in the ajax call

contentType: "application/json",
data: JSON.stringify({ business: data }),

the below code to receive the data

public ActionResult BusinessCall(Business business){}

Upvotes: 0

user762330
user762330

Reputation:

You can use WCF Service Trace Viewer to help you view and trace the errors you get from the service.

Upvotes: 0

George Mavritsakis
George Mavritsakis

Reputation: 7083

You cannot instantiate a List<T> from JSON data. What you can do, is replace :

[DataContract]
    public class Business
    {
        [DataMember]
        public string Name { get; set; }
        [DataMember]
        public string Desc { get; set; }        
        [DataMember]
        public List<BusinessService> Services { get; set; }
    }

with

[DataContract]
    public class Business
    {
        [DataMember]
        public string Name { get; set; }
        [DataMember]
        public string Desc { get; set; }        
        [DataMember]
        public BusinessService[] Services { get; set; }
    }

That is, replace List<T> with Array of T

Upvotes: 4

Related Questions