locked
Issue in sending response with two complex types RRS feed

  • Question

  • Hi,

    I want to send more than one collection (complex type) in the response of WCF Service. I tried by sending one collection type and it is successful. But when I have added one more coplex type to the response message XSD, then its started giving problem. When I am calling the method(operation) from the client, its started showing the new added complextype as the output type parameter in the method call. 

    ServiceReference1.ArrayOfRestaurantInfo res = client.GetRestaurants("11001"); ------ here it is giving problem.

    Find below the message XSD

    <xs:element name="getRestaurants">
    <xs:complexType>
    <xs:sequence>
    <xs:element name="zip" type="xs:string" />
    </xs:sequence>
    </xs:complexType>
    </xs:element>
    <xs:element name="getRestaurantsResponse">
    <xs:complexType>
    <xs:sequence minOccurs="1" maxOccurs="1">
    <xs:element name="restaurants" type="import:restaurantsList" nillable="true" />
    <xs:element name="hotels" type="import:restaurantsList" nillable="true" />
    <xs:element name="Error" type="xs:string" />
    </xs:sequence>
    </xs:complexType>
    </xs:element>

    Code :

    public partial class GetRestaurantsResponse
    {

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="urn:RestuarantService:messages:v1", Order=0, Name="restaurants")]
    [System.Xml.Serialization.XmlArrayAttribute(IsNullable=true)]
    [System.Xml.Serialization.XmlArrayItemAttribute("restaurant", Namespace="urn:RestuarantService:data:v1", IsNullable=false)]
    public RestaurantInfoCollection Restaurants;

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="urn:RestuarantService:messages:v1", Order=1, Name="hotels")]
    [System.Xml.Serialization.XmlArrayAttribute(IsNullable=true)]
    [System.Xml.Serialization.XmlArrayItemAttribute("restaurant", Namespace="urn:RestuarantService:data:v1", IsNullable=false)]
    public RestaurantInfoCollection Hotels;

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="urn:RestuarantService:messages:v1", Order=2)]
    public string Error;

    public GetRestaurantsResponse()
    {
    }

    public GetRestaurantsResponse(RestaurantInfoCollection restaurants, RestaurantInfoCollection hotels, string Error)
    {
    this.Restaurants = restaurants;
    this.Hotels = hotels;
    this.Error = Error;
    }

    Would appreciate if anyone please provide me the solution to it.

    Thanks & regards,

    Afreen

    Thursday, February 9, 2012 5:46 AM

All replies

  • Hello, what problems do you have? I tried your code with the following classes, and didn't encounter any issue.

        public class RestaurantInfoCollection : List<RestaurantInfo>
        {
        }
    
        public class RestaurantInfo
        {
            public int ID { getset; }
            public string Name { getset; }
        }
    

    Service operation:

            public GetRestaurantsResponse GetRestaurants()
            {
                RestaurantInfoCollection collection = new RestaurantInfoCollection()
                {
                    new RestaurantInfo() { ID = 1, Name = "a" },
                    new RestaurantInfo() { ID = 2, Name = "b" },
                    new RestaurantInfo() { ID = 3, Name = "c" }
                };
                return new GetRestaurantsResponse() { Restaurants = collection };
            }
    

    Lante, shanaolanxing This posting is provided "AS IS" with no warranties, and confers no rights.
    If you have feedback about forum business, please contact msdnmg@microsoft.com. But please do not ask technical questions in the email.

    Thursday, February 9, 2012 12:25 PM
  • Hi Li-Yun,

    Thanks for the response.

    I am facing the problem only when I am trying to send more than one collection in the WCF response. I am putting the code below:

                    

    *******************************************************************

    <xs:element name="getRestaurantsResponse">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="restaurants" type="import:restaurantsList" nillable="true" />
            <xs:element name="hotels" type="import:hotelList" nillable="true" />
            <xs:element name="Error" type="xs:string" />
          </xs:sequence>
        </xs:complexType>
      </xs:element>

    ***********************************************

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="urn:RestuarantService:messages:v1", Order=0, Name="restaurants")]
            [System.Xml.Serialization.XmlArrayAttribute(IsNullable=true)]
            [System.Xml.Serialization.XmlArrayItemAttribute("restaurant", Namespace="urn:RestuarantService:data:v1", IsNullable=false)]
            public RestaurantInfoCollection Restaurants;

            [System.ServiceModel.MessageBodyMemberAttribute(Namespace="urn:RestuarantService:messages:v1", Order=1, Name="hotels")]
            [System.Xml.Serialization.XmlArrayAttribute(IsNullable=true)]
            [System.Xml.Serialization.XmlArrayItemAttribute("hotel", Namespace="urn:RestuarantService:data:v1", IsNullable=false)]
            public HotelInfoCollection Hotels;

            [System.ServiceModel.MessageBodyMemberAttribute(Namespace="urn:RestuarantService:messages:v1", Order=2)]
            public string Error;

    **********************************************************************

    public virtual GetRestaurantsResponse GetRestaurants(GetRestaurantsRequest request)
            {
                string a = request.Zip.ToString();


                GetRestaurantsResponse res = new GetRestaurantsResponse();


                RestaurantInfo resInfo = new RestaurantInfo();


                RestaurantInfoCollection reCol = new RestaurantInfoCollection();


                resInfo.RestaurantID = 101;
                resInfo.Address = "Kondwa";
                resInfo.City = "Pune";
                resInfo.Name = "McDonalds";
                resInfo.State = "Maharashtra";
                resInfo.Zip = "411048";


                reCol.Add(resInfo);


                RestaurantInfo resInfo1 = new RestaurantInfo();


                resInfo1.RestaurantID = 13301;
                resInfo1.Address = "Kondwa 1";
                resInfo1.City = "Pune 1";
                resInfo1.Name = "McDonalds 1";
                resInfo1.State = "Maharashtra 1";
                resInfo1.Zip = "411048 1";


                reCol.Add(resInfo1);


                HotelInfo hoInfo = new HotelInfo();
                HotelInfoCollection hoCol = new HotelInfoCollection();


                hoInfo.RestaurantID = 1001;
                hoInfo.Address = "Laxmi Nagar";
                hoInfo.City = "New Delhi";
                hoInfo.Name = "KFC";
                hoInfo.State = "Delhi";
                hoInfo.Zip = "110092";


                hoCol.Add(hoInfo);


                res.Error = "Error";


                //res.Restaurants.Add(resInfo);


                res.Restaurants = reCol;
                res.Hotels = hoCol;


                return res;
            }


    The problem is when I am calling the getRestuarant() from the client, its converting hotel and error as the output parameter for the method.

    The collections are not getting transfered to the Client.

    Please have a look and provide the solution.

    Thanks in advance.

    Regards,

    Afreen

    Thursday, February 9, 2012 3:07 PM
  • I tried your code and it still works fine for me. On the client side I can successfully see the correct data returned:

    McDonalds

    KFC

                var response = client.GetRestaurants();
                Console.WriteLine(response.Restaurants[0].Name);
                Console.WriteLine(response.Hotels[0].Name);
    

    Lante, shanaolanxing This posting is provided "AS IS" with no warranties, and confers no rights.
    If you have feedback about forum business, please contact msdnmg@microsoft.com. But please do not ask technical questions in the email.

    Friday, February 10, 2012 2:32 AM
  • Hi Yi-Lun,

    Thanks for the reply.

    When I am calling the same method as also mentioned:

     var response = client.GetRestaurants();

    Its showing the signature of getRestuarant with two out parameters (Hotelcollection and Error) and I am getting the Hotel collection & Error in the out parameter.

    I dont what I am doing wrong that it is converting the collections of response to out parameter of getRestuarant method.I have already provided the complete code to you.

    Please can you look once again and do let me know if you find something wrong in it.

    Thanks & regards,

    Afreen

    Friday, February 10, 2012 4:21 AM
  • Hi,

    Now I have to call the GetRestaurants() method as mention below from the client:

     ServiceReference1.ArrayOfHotelInfo HotelInfo = new ServiceReference1.ArrayOfHotelInfo();

     string s = "Err";

    ServiceReference1.ArrayOfRestaurantInfo res = client.GetRestaurants("11001", out hotelInfo, out s);

    and I am getting the hotel collection in HotelInfo.

    I dont know how its converting into out parameter?

    Please provide some solution.

    Regards,

    Afreen

    Friday, February 10, 2012 6:33 AM
  • What is the method signature for GetRestaurants on the server side? I assume it is:

    GetRestaurantsResponse GetRestaurants();

    But from the above code, it seems at least the client side signature is:

    ArrayOfRestaurantInfo GetRestaurants(string someID, out HotelInfo holtelInfo, out string error);

    So you're not using GetRestaurantsResponse at all? Is the service written by you? How do you design the operation contract?


    Lante, shanaolanxing This posting is provided "AS IS" with no warranties, and confers no rights.
    If you have feedback about forum business, please contact msdnmg@microsoft.com. But please do not ask technical questions in the email.

    Friday, February 10, 2012 7:19 AM
  • Hi Y-Lun,

    Thanks again.

    Please find below the signature of getRestuarants method and below is the structure of GetRestaurantsRequest :

     [System.ServiceModel.OperationContractAttribute(Action="http://www.RestuarantService.com/IRestuarantService/GetRestaurants", ReplyAction="http://www.RestuarantService.com/IRestuarantService/GetRestaurantsResponse")]
            [System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults=true)]
            GetRestaurantsResponse GetRestaurants(GetRestaurantsRequest request);

    ********************************************************************

    [System.Diagnostics.DebuggerStepThroughAttribute()]

        [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
        [System.ServiceModel.MessageContractAttribute(WrapperName="GetRestaurants", WrapperNamespace="urn:RestuarantService:messages:v1", IsWrapped=true)]
        public partial class GetRestaurantsRequest
        {

            [System.ServiceModel.MessageBodyMemberAttribute(Namespace="urn:RestuarantService:messages:v1", Order=0, Name="zip")]
            public string Zip;

            public GetRestaurantsRequest()
            {
            }

            public GetRestaurantsRequest(string zip)
            {
                this.Zip = zip;
            }
        }

    *******************************************************

    Regards,

    Afreen

    Friday, February 10, 2012 7:23 AM
  • Is this the signature on the server side? If so, the client side should use the same signature. Are you using Add Service Reference to generate the client proxy?

    Lante, shanaolanxing This posting is provided "AS IS" with no warranties, and confers no rights.
    If you have feedback about forum business, please contact msdnmg@microsoft.com. But please do not ask technical questions in the email.

    Friday, February 10, 2012 7:53 AM
  • Yes this is the signature at the server side and I used add service reference to generate the client proxy.

    Still not sure what is the issue.

    Thanks 

    Friday, February 10, 2012 9:19 AM