2
I have a problem here where I have a Webapi consuming a WCF. I’m basically having trouble getting into WCF a property that’s the base type of class I’m actually sending. I’ll set an example to make it easier to explain:
[DataContract]
[KnownType(typeof(EnderNacional))]
[KnownType(typeof(EnderInternacional))]
public abstract class EnderBase
{
[DataMember]
public String Logradouro { get; set; }
///...
}
[DataContract]
public class EnderNacional : EnderBase
{
public String Cep { get; set; }
///...
}
[DataContract]
public class EnderInternacional : EnderBase
{
[DataMember]
public String CodigoPostal { get; set; }
///...
}
[DataContract]
[KnownType(typeof(CliNacional))]
[KnownType(typeof(CliInternacional))]
public abstract class CliBase
{
[DataMember]
public String Nome { get; set; }
[DataMember]
public IEnumerable<EnderBase> Enderecos { get; set; }
///...
}
[DataContract]
public class CliNacional : CliBase
{
[DataMember]
public String Cnpj { get; set; }
}
[DataContract]
public class CliInternacional : CliBase
{
[DataMember]
public String Identificacao { get; set; }
}
Here I put an example of a national and international client class, which inherit from a base class. The same happens with addresses where there are national and international inheriting from base class to address. For those who have worked with WCF certainly have had the problem with abstract classes and so the use of "Knowntype" so that WCF can serialize the object passed.
[ServiceContract]
public interface IServiceClientes
{
[OperationContract]
int SalvarNacional(ServiceClientes.CliNacional cliente);
}
public class ServiceClientes : IServiceClientes
{
public int SalvarNacional(Clientes.CliNacional cliente)
{
//...código
return int.MinValue;
}
}
The above code is a representation of the implementation of Iserviceclientes.
This works well when I test directly by Wcftestclient.exe, when I will inform the address, also appears the Endernacional and Enderinternational for choice. So, just choose one of the two, fill in the information and that’s it, C# can serialize the object because it knows that type, thanks to Knowntype. I know there are other ways and even dynamics to do this but this is not the case.
My problem starts when I use a Webapi to consume this method and make it available to Clients. Example:
[HttpPost]
public HttpResponseMessage SalvarClienteNacional(Api.CliNacional clienteNacional)
{
return Request.CreateResponse(HttpStatusCode.OK, new MyService.ServiceClientesClient().SalvarNacional(clienteNacional));
}
Here is a simple example of a call to my WCF through the Webapi, assuming that Myservice is my properly mapped WCF service.
When I test the Webapi, correctly sent the JSON object I get it correctly in my parameter "national clientele", but the same comes with the property "Addresses" mapped as "Enderbase" and when this is sent to the WCF I receive an Exception that it is not possible to instantiate an abstract class.
Probably the WCF cannot understand that my JSON represents a national or international address or because the "Addressees" property is mapped as being the base class, which is really abstract! At the time of the cast it seems that it attempts to instantiate the Collection type itself, generating Exception.
Googlei enough and only find the same solution I’m already using, which is the use of Knowntype but it seems that this worked only when I use WCF classes directly, not when cast through a JSON.
What could I do to solve this problem? Has anyone had similar problem?
Any and all help is welcome.
I bless you all in advance.
Regarding the 3 items: 1) I will govern my service yes; 2) in the Webapi I checked yes the structure of the object and was ok, IE, json for the api was not in trouble. But I don’t know what these attributes are specific to the Model Binder, could you help me? 3) This structure of having a Webapi was client’s requirement, where the WCF would be only local and only the Web visible Api.
– Eric