简体   繁体   English

带有 Simple.OData.Client 的 DTO

[英]DTOs with Simple.OData.Client

In my server I have the following setup:在我的服务器中,我有以下设置:

EntitySet<Contact>("Contacts");
EntityType<ContactDto>();

Here's the controller actions:这是 controller 操作:

[EnableQuery]
public ActionResult<IQueryable<ContactDto>> Get()
{
  return Ok(_DbContext.Contacts.Select(c => new ContactDto(c)));
}

[EnableQuery]
public async Task<ActionResult<Contact>> Get(int key)
{
  return await _DbContext.Contacts.FindAsync(key);
}

Contact and ContactDto implement IContact , besides that they are unaware of each other. ContactContactDto实现IContact ,此外它们彼此不知道。

When querying the server (using the Contacts route), I get the expected result, but in the client I'm trying to do:查询服务器时(使用Contacts路由),我得到了预期的结果,但在客户端我试图做:

var settings = new ODataClientSettings(new Uri(
    $"https://localhost:{Constants.Port}/{Constants.Api}"));
var client = new ODataClient(settings);

var result = await client
    .For<Contact>()
    .FindEntriesAsync();

And I'm getting an exception:我遇到了一个例外:

Microsoft.OData.ODataException: 'The context URL 'https://localhost:54687/api/$metadata#Contacts/ODataDtoRepro.Models.ContactDto' is invalid

StackTrace:堆栈跟踪:

at Microsoft.OData.JsonLight.ODataJsonLightContextUriParser.ParseContextUriFragment(String fragment, Func`3 clientCustomTypeResolver, Boolean throwIfMetadataConflict, Boolean& isUndeclared)
   at Microsoft.OData.JsonLight.ODataJsonLightContextUriParser.ParseContextUri(ODataPayloadKind expectedPayloadKind, Func`3 clientCustomTypeResolver, Boolean throwIfMetadataConflict)
   at Microsoft.OData.JsonLight.ODataJsonLightContextUriParser.Parse(IEdmModel model, String contextUriFromPayload, ODataPayloadKind payloadKind, Func`3 clientCustomTypeResolver, Boolean needParseFragment, Boolean throwIfMetadataConflict)
   at Microsoft.OData.JsonLight.ODataJsonLightDeserializer.ReadPayloadStart(ODataPayloadKind payloadKind, PropertyAndAnnotationCollector propertyAndAnnotationCollector, Boolean isReadingNestedPayload, Boolean allowEmptyPayload)
   at Microsoft.OData.JsonLight.ODataJsonLightReader.ReadAtStartImplementation()
   at Microsoft.OData.ODataReaderCore.ReadImplementation()
   at Microsoft.OData.ODataReaderCore.ReadSynchronously()
   at Microsoft.OData.ODataReaderCore.InterceptException[T](Func`1 action)
   at Microsoft.OData.ODataReaderCore.Read()
   at Simple.OData.Client.V4.Adapter.ResponseReader.ReadResponse(ODataReader odataReader, IODataResponseMessageAsync responseMessage)
   at Simple.OData.Client.V4.Adapter.ResponseReader.<GetResponseAsync>d__3.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at Simple.OData.Client.ODataClient.<ExecuteRequestWithResultAsync>d__147`1.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at Simple.OData.Client.ODataClient.<FindAnnotatedEntriesAsync>d__88.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at Simple.OData.Client.ODataClient.<FindEntriesAsync>d__89.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at Simple.OData.Client.FluentClientBase`2.<FilterAndTypeColumnsAsync>d__91.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Client.Program.<Main>d__0.MoveNext() in D:\Users\Shimmy\Documents\Visual Studio 2019\Projects\ODataDtoRepro\Client\Program.cs:line 16

I've made a repro project on GitHub .我在GitHub上做了一个重现项目。

I've created another repro branch , that tries a different approach, so that it uses a shared base-class registered in the EDM model, instead of an interface.我创建了另一个repro 分支,它尝试了不同的方法,因此它使用在 EDM model 中注册的共享基类,而不是接口。 Still, Simple.OData.Client can't get around it.尽管如此,Simple.OData.Client 还是无法绕过它。 Please check also my comments on this issue.另请查看我对这个问题的评论。

How can I get DTOs to work with OData?如何让 DTO 与 OData 一起使用?

Update更新

Possible solution: using actions/functions.可能的解决方案:使用动作/功能。 Tried experimenting with it but couldn't make it work between client and server, see this answer for more.尝试对其进行试验,但无法使其在客户端和服务器之间工作,请参阅答案了解更多信息。

I believe that the issue is that there is no relation between the two objects.我认为问题在于这两个对象之间没有关系。 I pulled down your code and got it working by removing the entity set我删除了您的代码并通过删除实体集使其正常工作

var edmModel = new ODataConventionModelBuilder();
edmModel.EntitySet<ContactDto>("Contacts");
routeBuilder.MapODataServiceRoute("API Route", Constants.Api, edmModel.GetEdmModel());

and by having ContactDto extend Contact并通过让 ContactD 扩展联系人

public class ContactDto : Contact

As contact is a subset of contact dto it returns as expected with no errors.由于contact 是contact dto 的子集,因此它按预期返回,没有错误。 Let me know if you want me submit the code to your github.如果您希望我将代码提交给您的 github,请告诉我。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM