protected async Task CreateDocumentAttachmentAsync <TDocument, TAttachment>( string documentRecordId, string partitionKey, AttachmentTypeMapping <TDocument, TAttachment> attachmentMapping, TAttachment attachment) { var client = GetClient(); var documentUri = UriFactory.CreateDocumentUri( _dbAccess.DbConfig.DatabaseId, _dbAccess.DbConfig.CollectionName, documentRecordId); await MakeClientCall(async() => { await client.CreateAttachmentAsync( documentUri, attachmentMapping.Writer(attachment), new MediaOptions { // Managed attachments are always stored as octet streams by CosmosDb. The value for content // type must be set to `application/octet-stream` when storing managed attachments otherwise // the CosmosDb API produces an error stating that the payload is invalid. This is not the // case for unmanaged attachments which require the content type to be set for the externally // stored data. ContentType = "application/octet-stream", // The (poorly) named `Slug` property is what CosmosDb uses as the unique identifier for the // attachment. This is the ID that is used for direct attachment retrieval and must be unique // within the context of the parent document. Slug = CreateAttachmentId(documentRecordId, attachmentMapping.AttachmentName) }, new RequestOptions { PartitionKey = new PartitionKey(partitionKey) }); }, "Failed to create document attachment"); }
private TAttachment DeserialiseAttachment <TDocument, TAttachment>( AttachmentTypeMapping <TDocument, TAttachment> attachmentMapping, MediaResponse mediaResponse) { try { return(attachmentMapping.Reader(mediaResponse.Media)); } catch (Exception e) { throw new NebulaStoreException("Failed to deserialise document attachment", e); } }
protected async Task <TAttachment> GetDocumentAttachmentAsync <TDocument, TAttachment>( string documentRecordId, string partitionKey, AttachmentTypeMapping <TDocument, TAttachment> attachmentMapping) { var client = GetClient(); var attachmentUri = UriFactory.CreateAttachmentUri( _dbAccess.DbConfig.DatabaseId, _dbAccess.DbConfig.CollectionName, documentRecordId, CreateAttachmentId(documentRecordId, attachmentMapping.AttachmentName)); var requestOptions = new RequestOptions { PartitionKey = new PartitionKey(partitionKey) }; var attachmentResponse = await MakeClientCall( async() => await client.ReadAttachmentAsync(attachmentUri, requestOptions), "Failed to read document attachment"); if (attachmentResponse == null) { // Attachment not found. return(default(TAttachment)); } var mediaResponse = await MakeClientCall( async() => await client.ReadMediaAsync(attachmentResponse.Resource.MediaLink), "Failed to read document attachment media"); if (mediaResponse == null) { // Media link not found. This would indicate a bug in attachment storage process. return(default(TAttachment)); } return(DeserialiseAttachment(attachmentMapping, mediaResponse)); }