private static EntityReferenceCollection GetEntityReferences( ODataNavigationLinkWithItems navigationLinkWrapper, ODataDeserializerContext readContext) { var referenceCollection = new EntityReferenceCollection(); foreach (var childItem in navigationLinkWrapper.NestedItems.OfType <ODataEntityReferenceLinkBase>()) { var uriParser = readContext.Request.GetODataUriParser(childItem.EntityReferenceLink.Url); referenceCollection.Add(uriParser.ParsePath()); } return(referenceCollection); }
public override void ApplyNavigationProperty( object entityResource, ODataNavigationLinkWithItems navigationLinkWrapper, IEdmEntityTypeReference entityType, ODataDeserializerContext readContext) { base.ApplyNavigationProperty(entityResource, navigationLinkWrapper, entityType, readContext); var referenceCollection = GetEntityReferences(navigationLinkWrapper, readContext); if (referenceCollection.Any()) { if (!entityResource.As <EdmStructuredObject>().TrySetPropertyValue(navigationLinkWrapper.NavigationLink.Name, referenceCollection)) { throw new InvalidOperationException("Unable to set entity reference links as navigation property value."); } } }
/// <summary> /// Десериализует navigation property. /// Также выполняет необходимые действия, чтобы обработка @odata.bind выполнялась по стандарту OData. /// </summary> /// <param name="entityResource">Объект, в который navigation property будет прочитано.</param> /// <param name="navigationLinkWrapper">navigation линк.</param> /// <param name="entityType">Тип сущности.</param> /// <param name="readContext">Состояние и установки, используемые при чтении.</param> public override void ApplyNavigationProperty( object entityResource, ODataNavigationLinkWithItems navigationLinkWrapper, IEdmEntityTypeReference entityType, ODataDeserializerContext readContext) { base.ApplyNavigationProperty(entityResource, navigationLinkWrapper, entityType, readContext); EdmEntityObject edmEntity = (EdmEntityObject)entityResource; DataObjectEdmModel model = readContext.Model as DataObjectEdmModel; foreach (var childItem in navigationLinkWrapper.NestedItems) { if (!readContext.Request.Properties.ContainsKey(Dictionary)) { readContext.Request.Properties.Add(Dictionary, new Dictionary <string, object>()); } var dictionary = (Dictionary <string, object>)readContext.Request.Properties[Dictionary]; var navigationPropertyName = navigationLinkWrapper.NavigationLink.Name; var entityReferenceLink = childItem as ODataEntityReferenceLinkBase; if (entityReferenceLink != null) { Uri referencedEntityUrl = entityReferenceLink.EntityReferenceLink.Url; if (referencedEntityUrl.IsAbsoluteUri) { referencedEntityUrl = referencedEntityUrl.MakeRelativeUri(readContext.Request.RequestUri); } var segments = referencedEntityUrl.OriginalString.Split(new[] { '(', ')' }, StringSplitOptions.RemoveEmptyEntries); if (segments.Length != 2) { throw new ApplicationException($"Invalid @odata.bind: {referencedEntityUrl.OriginalString}"); } var type = model.GetDataObjectType(segments[0]); if (type == null) { throw new ApplicationException($"Invalid entity set: {segments[0]}"); } Guid guid; try { guid = new Guid(segments[1]); } catch (Exception) { throw new ApplicationException($"Invalid guid: {segments[1]}"); } var linkedEdmEntity = new EdmEntityObject(model.GetEdmEntityType(type)); linkedEdmEntity.TrySetPropertyValue("__PrimaryKey", guid); edmEntity.TrySetPropertyValue(navigationPropertyName, linkedEdmEntity); if (!dictionary.ContainsKey(navigationPropertyName)) { dictionary.Add(navigationPropertyName, navigationPropertyName); } } var feed = childItem as ODataFeedWithEntries; if (childItem == null || (feed != null && feed.Entries.Count == 0)) { edmEntity.TrySetPropertyValue(navigationPropertyName, null); if (!dictionary.ContainsKey(navigationPropertyName)) { dictionary.Add(navigationPropertyName, null); } } } }