2

I've got this interface, from a WCF service:

[ServiceContract]
[ServiceKnownType("GetKnownTypes", typeof(KnownTypesProvider))]
public interface IQuerySageService
{

    [OperationContract]
    CustomerLedger GetBillingContact(string crmAccountNumber);

    [OperationContract]
    ImportCrmInvoicesResponse ImportCrmInvoices(List<New.Xrm.Entities.Invoice> invoices);


}

And the method refered above is from this class:

internal static class KnownTypesProvider
{
    public static IEnumerable<Type> GetKnownTypes(ICustomAttributeProvider provider)
    {
        List<Type> types = new List<Type>();

        types.Add(typeof(New.Xrm.Entities.InvoiceDetail));

        return types;
    }
}

But when invoking ImportCrmInvoices (Invoice has InvoiceDetail children) from the client (a CRM workflow), I get the following error:

There was an error while trying to serialize parameter http://tempuri.org/:invoices. The InnerException message was 'Type 'New.Xrm.Entities.InvoiceDetail' with data contract name 'InvoiceDetail:http://schemas.datacontract.org/2004/07/New.Xrm.Entities' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.'. Please see InnerException for more details."

I thought this ServiceKnownType decoration would do the trick from what I've read, but apparently not.

The types (Invoice, InvoiceDetail) are contained within an assembly, refered by both the client and the server (namespace New.Xrm.Entities)

Now, the physical CS file that holds those types is huge (7MB), and barely editable. So maybe I'm missing a DataContract decoration somewhere, but I don't want to go in this file to add it.

Any other ways to achieve this ?

2
  • Serializing/Deserializing early bound entities is a pain and also will increase dependency and not to mention the 1001 unnecessary members that it holds. Try to flatten it out by using a poco with just the members you need, it is much cleaner and leaner this way. Commented Jul 6, 2016 at 16:06
  • @dynamicallyCRM I think that's what it'll come to... Thanks. Commented Jul 6, 2016 at 16:19

2 Answers 2

1

Another way to achieve this is to use the KnownTypes attribute on your parent DataContract class from which your child classes derive.

The KnownTypeAttribute class allows you to specify, in advance, the types that should be included for consideration during deserialization.

(https://msdn.microsoft.com/en-us/library/ms730167(v=vs.110).aspx)

The KnownTypes attribute can either take a type parameter, or you can provide the name of a method in that class that returns an array of valid types.

For example:

[DataContract]
[KnownTypes(typeof(InvoiceDetail)]
public class Invoice
{
    [DataMember]
    public string SomeProperty {get; set; }
}

[DataContract]
public class InvoiceDetail : Invoice
{
}
Sign up to request clarification or add additional context in comments.

2 Comments

I added details in my question, regarding where these types are held and I don't want to edit the file. It's huge and inconvient to edit and generated by a tool.
Does the tool generate a partial class? If so, you could just create a partial that applies the known types attribute.
0

I ended up have having the WCF service doing it's own look ups in CRM. The ImportCrmInvoices method accepts a list of GUIDS and fetches the data about them itself.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.