simple-odata-client / Simple.OData.Client

MIT License
331 stars 197 forks source link

UnresolvableObjectException after successful insert (SharePoint) #528

Open kitsu opened 6 years ago

kitsu commented 6 years ago

Hopefully I'm just missing something obvious, but I can't figure out how to convince Simple.OData.Client to give me the object the server returns after an insert. Because of how SharePoint is structured the request is a little strange, and I think it is confusing SOC about what it is getting back:

        async public Task<IContactInfo> AddContact(IContactInfo contact)
        {
            var record = await cc.Client
                .For("SP.List")
                .Key(cc.ContactsId)
                .NavigateTo<SPContactInfo>("items")
                .Set(SPContactInfo.FromContact(contact))
                .InsertEntryAsync();
            return record;
        }

Here is a heavily trimmed version of what SharePoint hands back:

<?xml version="1.0" encoding="utf-8"?>
<entry>
    <id>Web/Lists(guid'a1796420-a6c4-40b3-a4ca-bdf74fc25025')/Items(13774)</id>
    <category term="SP.Data.ContactsListItem" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
        <content type="application/xml">
        <m:properties>
            <d:Id m:type="Edm.Int32">13774</d:Id>
            <d:Fields m:type="Edm.String">Have been omitted</d:Fields>
        </m:properties>
    </content>
</entry>

And the exception

{ "error": {
    "code": "",
    "message": "An error has occurred.",
    "innererror": {
        "message": "Entity type [Lists(%27a1796420-a6c4-40b3-a4ca-bdf74fc25025%27)/Items] not found",
        "type": "Simple.OData.Client.UnresolvableObjectException",
        "stacktrace": "
           at Microsoft.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
           at Microsoft.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccess(Task task)
           at Simple.OData.Client.BoundClient`1.<InsertEntryAsync>d__15.MoveNext()
        --- End of stack trace from previous location where exception was thrown ---
           at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
           at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
           at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
           at Companies360.SPCompanyData.Repositories.SPContactRepository.<AddContact>d__1.MoveNext() in SPContactsRepository.cs:line 28
        --- End of stack trace from previous location where exception was thrown ---
           at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
           at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
           at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
           at Companies360.Api.Controllers.ContactsController.<AddContact>d__3.MoveNext() in ContactsController.cs:line 43
        --- End of stack trace from previous location where exception was thrown ---
           at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
           at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
           at System.Threading.Tasks.TaskHelpersExtensions.<CastToObject>d__1`1.MoveNext()
        --- End of stack trace from previous location where exception was thrown ---
           at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
           at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
           at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__1.MoveNext()
        --- End of stack trace from previous location where exception was thrown ---
           at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
           at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
           at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__5.MoveNext()
        --- End of stack trace from previous location where exception was thrown ---
           at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
           at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
           at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__15.MoveNext()"
}}}

Intellisense successfully determines the result should be SPContactInfo, but how do I convince SOC?

kitsu commented 6 years ago

One more SharePoint problem: On update SP refuses to return the updated record, instead returning a 204 No Content. I know this, but I can't tell SOC, so it blows up with a null reference exception every time, even if resultRequired is false.

Edit: Same with delete....

Also, when I tried setting Prefer: return-content I noticed the request went as Prefer: return-no-content, return-content.