Search code examples
c#.netsaleslogixsdata

How to create a new contact in Saleslogix Infor CRM using DotNetSDataClient


I am trying to use the DotNetSDataClient library to add a new contact in Infor CRM. I have attempted to follow this documentation under the Create section. When I run the example code, I receive the error "The Contact's Account is required." This makes sense, because I believe each contact in the database must be associated with an account. I modified the code to specify an existing account, but now I receive the error "We're sorry, you've encountered an error. If applicable, please try again." with the innerexception, "The remove server returned an error: (500) Internal Server Error."

Here is my code.

public void someFunction(){
    var client = new SDataClient("https://domain/sdata/slx/dynamic/-/")
    {
        UserName = "username",
        Password = "password"
    };

    var contact = new Contact
    {
        Account = new Account
        {
            AccountName = "accountName",
            Id = "accountId"
        },
        Address = new Address
        {
            Address1 = "1234 Address",
            City = "someCity",
            PostalCode = "12345",
            State = "ST"
        },
        FirstName = "John",
        LastName = "Doe"
    };

    var contactOptions = new SDataPayloadOptions { Include = "Address" };

    try
    {
        contact = client.Post(contact, null, contactOptions);
    }
    catch (Exception ex)
    {
        var error = ex.Message;
    }
}

[SDataPath("accounts")]
public class Account
{
    [SDataProtocolProperty(SDataProtocolProperty.Key)]
    public string Id { get; set; }

    public string AccountName { get; set; }
    public List<Contact> Contacts { get; set; }
    public string Status { get; set; }
    public string Type { get; set; }
}

[SDataPath("contacts")]
public class Contact
{
    [SDataProtocolProperty(SDataProtocolProperty.Key)]
    public string Id { get; set; }

    public Account Account { get; set; }
    public Address Address { get; set; }
    public string Email { get; set; }
    public string FirstName { get; set; }
    public string FullName { get; set; }
    public string LastName { get; set; }
    public DateTime? ModifyDate { get; set; }
    public string Status { get; set; }
}

[SDataPath("addresses")]
public class Address
{
    [SDataProtocolProperty]
    public string Key { get; set; }
    public string Address1 { get; set; }
    public string Address3 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public string CountryCode { get; set; }
    public string Description { get; set; }
    public string PostalCode { get; set; }
    public string State { get; set; }
    public string Street { get; set; }
}

Does anyone have any ideas about what I am doing wrong?


Solution

  • I also posted this question on GitHub and Ryan Farley provided the answer. I wanted to include it here in case anyone else needs this solution.

    The issue is with how the library serializes the data. Here is Ryan's response:

    "The real issue here is that the POCO for Account has a collection of contacts. The DotNetSDataClient is serializing that as null and the SData server doesn't like that. Even setting that collection to new List() will fail because it will get serialized as []. where it should look like

    "Contacts": { "$resources": [] }
    

    When doing a POST with an existing parent or related entity, SData expects to only receive the $key and nothing else anyway. So, when the Contact class gets serialized, what you should be sending with the contact data is

    "Account": { "$key":"AXXX00000001" }
    

    and nothing more, but that is not the case, the library is serializing and sending everything."

    At this point, the solution is to create an account class that only has an id (key) property.

    [SDataPath("accounts")]
    public class Account
    {
        [SDataProtocolProperty(SDataProtocolProperty.Key)]
        public string Id { get; set; }
    }
    

    At some point the DotNetSDataClient library may be updated to handle this situation, but for now this is the solution.