Home > database >  How to return different types of responses from WCF service application method?
How to return different types of responses from WCF service application method?

Time:03-17

I have a WCF service application with a method

public PersonResponse(PersonRequest request)
{
     return new PersonResponse { Id = 1, Name = "Mark" };
}

I have 2 different responses possible for that method

    [DataContract]
    public class PersonResponse 
    {
        int id;
        string name;

        [DataMember]
        public int Id
        {
            get { return id; }
            set { id = value; }
        }

        [DataMember]
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
    }

and

    [DataContract]
    public class ErrorResponse
    {
        int errorCode;
        string errorText;

        [DataMember]
        public int? ErrorCode
        {
            get { return errorCode; }
            set { errorCode = value; }
        }

        [DataMember]
        public string ErrorText
        {
            get { return errorText; }
            set { errorText = value; }
        }
    }

Is it possible to write a method that could return either of those responses but not both at the same time?

I Could do something like

    [DataContract]
    public class Response
    {
        PersonResponse personResponse;
        ErrorResponse errorResponse;

        [DataMember]
        public bool PersonResponse 
        {
            get { return personResponse; }
            set { personResponse= value; }
        }

        [DataMember]
        public string ErrorResponse 
        {
            get { return errorResponse; }
            set { errorResponse= value; }
        }
    }

public Response(PersonRequest request)
{
     return new Response{ PersonResponse = New PersonResponse { Id = 1, Name = "Mark" }, ErrorResponse = new ErrorResponse { ErrorCode = null, ErrorText = null } };
}

But I only need 1 type of the response to be returned, not both.

I've tried

public PersonResponse(PersonRequest request)
{
     throw new WebFaultException<ErrorResponse>(new ErrorResponse { ErrorCode = 103 ErrorText = "Try again later" }, HttpStatusCode.Conflict);
}

But it seems that this way it only returns the exception and not the ErrorResponse.

I've also tried adding and interface layer to the response like so and then returning that interface as a response

    public interface IResponse {}

    [DataContract]
    public class PersonResponse : IResponse
    {
        int id;
        string name;

        [DataMember]
        public int Id
        {
            get { return id; }
            set { id = value; }
        }

        [DataMember]
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
    }

    [DataContract]
    public class ErrorResponse : IResponse
    {
        int errorCode;
        string errorText;

        [DataMember]
        public int? ErrorCode
        {
            get { return errorCode; }
            set { errorCode = value; }
        }

        [DataMember]
        public string ErrorText
        {
            get { return errorText; }
            set { errorText = value; }
        }
    }

public IResponse(PersonRequest request)
{
     return new PersonResponse { Id = 1, Name = "Mark" };
}

But when I add this service as a reference to another project id doesn't generate any of the response type (Iresponse, ErrorResonse or PersonResponse) and throws an error when I try to call the method (Exception message https://ibb.co/Zdsbr9p)

CodePudding user response:

I think you can try to use FaultContractAttribute. Fault contracts allow you to specify alternate responses that will be returned in a SOAP fault.
Example interface:

[ServiceContract]
    interface IService
    {
        [OperationContract]
        [FaultContract(typeof(ErrorResponse))]
         PersonResponse  GetResponse();
    }

Service:

class Service : IService
{
    public PersonResponse GetResponse()
    {
        if (success)
        {
            return new PersonResponse();
        }
        else
        {
            throw new FaultException<ErrorResponse>(new ErrorResponse() 
            {
                ErrorMessage = "Something Happened"
            })
        }
    }
} 

The client can then handle the fault by catching FaultException<ErrorResponse>:

var serviceProxy = new ServiceProxy();

try 
{
    var dataObj = serviceProxy.GetResponse();
}
catch (FaultException<ErrorResponse> error)
{
    ErrorResponse detail = error.Detail;
    Console.WriteLine(detail.ErrorMessage);
}

source:How best should a Wcf service return different objects for the same method
resemblance:Return different Object (List or error class) from WCF service

  •  Tags:  
  • wcf
  • Related