WCF fails to return complex type

0

I've faced a problem of returning complex type from wcf service and feel lack of knowledge to solve it. The problem is that wcf service brakes the connection when trying to return one complex type (it contains other complex types). The thing is that wcf returns another complex type without any problem. So, here is the exception it generates:

System.ServiceModel.CommunicationException HResult=0x80131501 Message=An error occurred while receiving the HTTP response to http://localhost:52943/FivePlusService.svc. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more details. Source=mscorlib StackTrace: at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) at TestService.ServiceLocal.IFivePlusService.GetBoardByCodeTest(String boardCode) at TestService.ServiceLocal.FivePlusServiceClient.GetBoardByCodeTest(String boardCode) in C:\Users\Gricla30\source\repos\FivePlus\FivePlus\TestService\Connected Services\ServiceLocal\Reference.cs:line 1991 at TestService.Program.Main(String[] args) in C:\Users\Gricla30\source\repos\FivePlus\FivePlus\TestService\Program.cs:line 23

Inner Exception 1: WebException: The underlying connection was closed: An unexpected error occurred on a receive.

Inner Exception 2: IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.

Inner Exception 3: SocketException: An existing connection was forcibly closed by the remote host

Here is my CODE: This is the client side where I call wcf method

class Program
{
    //static FivePlusService.FivePlusServiceClient client = new FivePlusService.FivePlusServiceClient();
    static ServiceLocal.FivePlusServiceClient serviceLocal = new ServiceLocal.FivePlusServiceClient();
    static void Main(string[] args)
    {
        ServiceLocal.Board bLocal = serviceLocal.GetBoardByCodeTest("01-01");
        Console.WriteLine(bLocal.BoardId + " Price : " + bLocal.BoardPrice);
    }
}

This one is WCF method (it is marked as [OperationContract] in the interface):

namespace FivePlusWcfService
{
    [ServiceBehavior(IncludeExceptionDetailInFaults = true)]
    [ExceptionHandlerBehavior(typeof(ExceptionHandler))]
    public class FivePlusService : IFivePlusService
    {
        IBllAdd adder = new BllAdder();
        IBllSendEmail sender = new BllMailSender();
        IBllReturnData returner = new BllReturner();
        IBllVerify verifier = new BllVerifier();
        IBllEdit editor = new BllEditor();       
        public Board GetBoardByCodeTest(string boardCode)
        {
            return returner.GetBoardByCode(boardCode);
        }
    }
}

Now goes Server side:

namespace BllServiceToDal.Realization
{
    public class BllReturner : IBllReturnData
    {
        IDalReturnData returner = new DalDataReturner();

        public Board GetBoardByCode(string boardCode)
        {
            BoardsDB.DBTables.Board boardD = returner.GetBoardByCode(boardCode);
            return Convertor.BoardDbToPoco(boardD);
        }
     }
}

!!! While testing I found that this method RETURNS object of type Board without any problems. The next method just gets data from DB and is not imortant. The next thing which might be helpfull is Board class:

namespace POCOlib
{
    [DataContract]
    public enum Sides : byte { A = 1, B }
    [DataContract]
    public enum Types : byte { billboard = 1, pryzmatron, brandmauer }

    [DataContract]
    [KnownType(typeof(BoardAddress))]
    [KnownType(typeof(BoardImage))]
    [KnownType(typeof(Period))]
    [KnownType(typeof(City))]
    [KnownType(typeof(Street))]
    public class Board
    {
        [DataMember]
        public int BoardId { get; set; }

        [DataMember]
        public string BoardCode { get; set; }

        [DataMember]
        public Types BoardType { get; set; }

        [DataMember]
        public Sides BoardSide { get; set; }

        [DataMember]
        public virtual BoardAddress BoardAddress { get; set; }

        [DataMember]
        public string DorsCode { get; set; }

        [DataMember]
        public virtual BoardImage Img { get; set; }

        [DataMember]
        public decimal BoardPrice { get; set; }

        [DataMember]
        public bool IsAvailable { get; set; }

        [DataMember]
        public virtual Period OccupationPeriod { get; set; }
    }
}

What I tried to do: 1. Added [Serializable] attribute to Board class 2. Added 0 element to enums (as u can see they start from 1) 3. Removed all complex types (Address, Period, Image) 4. Tested WCF both localy and on the host Nothing helped (((

Can anyone help me with that, please?

wcf
asked on Stack Overflow Jan 17, 2018 by Serhiy • edited Jan 17, 2018 by jsanalytics

1 Answer

0
   [DataContract]
    public enum Sides : byte { A = 1, B }
    [DataContract]
    public enum Types : byte { billboard = 1, pryzmatron, brandmauer }

First it must be inside your class Board.

Next Enum need be decorated with DataContract and EnumMember attributes

namespace POCOlib
{

    [DataContract]
    [KnownType(typeof(BoardAddress))]
    [KnownType(typeof(BoardImage))]
    [KnownType(typeof(Period))]
    [KnownType(typeof(City))]
    [KnownType(typeof(Street))]
    public class Board
    {
        [DataMember]
        public int BoardId { get; set; }

        [DataMember]
        public string BoardCode { get; set; }

        [DataMember]
        public Types BoardType { get; set; }

        [DataMember]
        public Sides BoardSide { get; set; }

        [DataMember]
        public virtual BoardAddress BoardAddress { get; set; }

        [DataMember]
        public string DorsCode { get; set; }

        [DataMember]
        public virtual BoardImage Img { get; set; }

        [DataMember]
        public decimal BoardPrice { get; set; }

        [DataMember]
        public bool IsAvailable { get; set; }

        [DataMember]
        public virtual Period OccupationPeriod { get; set; }

        [DataContract]
        public enum Sides : byte 
        { 

        [EnumMember]
        A = 1,
        [EnumMember]
        B 

        }

        [DataContract]
        public enum Types : byte 
        { 

        [EnumMember]
        billboard = 1,
        [EnumMember]
        pryzmatron, brandmauer

        }    
    }
}

Then add those enum types to your service contract or class Board.

[ServiceKnownType(typeof(Sides))]
[ServiceKnownType(typeof(Types))]
answered on Stack Overflow Jan 17, 2018 by Hameed Syed

User contributions licensed under CC BY-SA 3.0