Skip to content

Instantly share code, notes, and snippets.

@chgeuer
Last active August 29, 2015 14:19
Show Gist options
  • Save chgeuer/b4ddde13caef8282fb20 to your computer and use it in GitHub Desktop.
Save chgeuer/b4ddde13caef8282fb20 to your computer and use it in GitHub Desktop.
DocDBMissingSlugRepro.cs
/*
* await client.CreateAttachmentAsync(document.AttachmentsLink, someStream, new MediaOptions { Slug = "attachment.jpg", ContentType = "..." });
*
* var attachments = client.CreateAttachmentQuery(attachmentsLink)...
* Attachment attachment = ...
* attachment.Id == "attachment.jpg"
*
* MediaResponse content = await client.ReadMediaAsync(attachment.MediaLink);
* content.Slug == ""
*/
// Uploaded attachment with slug="attachment.jpg"
// content.Slug = "", attachment.Id = "attachment.jpg"
// Downloaded attachment to "d:\src.customers\...\Demo1\Demo1\bin\Debug\attachment.jpg"
/*
POST https://xxx.documents.azure.com/dbs/nJcnAA==/colls/nJcnAIWUwAA=/docs/nJcnAIWUwAASAAAAAAAAAA==/attachments/ HTTP/1.1
User-Agent: Microsoft.Azure.Documents.Client/0.9.161.1
Content-Type: image/jpeg
Slug: attachment.jpg
Host: xxx.documents.azure.com
Content-Length: 3031
HTTP/1.1 201 Created
Content-Type: application/json
{"contentType":"text/plain","id":"attachment.jpg",...}
*/
namespace SPONDemo1
{
// <package id="Microsoft.Azure.DocumentDB" version="1.0.0" targetFramework="net45" />
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
using Microsoft.Azure.Documents.Linq;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
class Program2
{
static void Main(string[] args) { ReproAsync(args).Wait(); }
static DocumentClient CreateDocumentClient()
{
return new DocumentClient(
serviceEndpoint: new Uri("https://xxx.documents.azure.com:443/"),
authKeyOrResourceToken: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx==",
connectionPolicy: new ConnectionPolicy { ConnectionMode = ConnectionMode.Direct, ConnectionProtocol = Protocol.Https });
}
static async Task ReproAsync(string[] args)
{
DocumentClient client = CreateDocumentClient();
var json = @"{
'doc_name': 'XXXXXX-SP-2014-046-163082',
'doc_id': '130223322',
'title': 'Some fancy title',
'subtitle': 'Why stuff happens',
'ressort': 'Business',
'topic': [ 'Industry' ],
'text': 'lorem ipsum ...',
'wordcount': 2528,
'author': [ { 'name': 'Joe Random', 'first': 'Joe', 'last': 'Random' } ],
'category': [ 'Wirtschaft' ],
'source': 'SOME MAGAZINE',
'issue': '46', 'year': '2014', 'date': '2014-11-10',
'page_from': '82', 'page_to': '85'
}";
var jpegBytes = Convert.FromBase64String("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");
var j = JsonConvert.DeserializeObject<dynamic>(json);
var databaseId = "slugReproDB";
var collectionId = "slugReproCollection";
var documentId = (string)j.doc_id;
var account = await client.GetDatabaseAccountAsync();
var databases = await client.ReadDatabaseFeedAsync();
var database = databases.FirstOrDefault(_ => _.Id == databaseId);
if (database == null)
{
var databaseResponse = await client.CreateDatabaseAsync(new Database { Id = databaseId });
database = databaseResponse.Resource;
}
var collections = await client.ReadDocumentCollectionFeedAsync(database.CollectionsLink);
var collection = collections.FirstOrDefault(_ => _.Id == collectionId);
if (collection == null)
{
var collectionResponse = await client.CreateDocumentCollectionAsync(database.CollectionsLink, new DocumentCollection { Id = collectionId });
collection = collectionResponse.Resource;
}
var documents = await client.ReadDocumentFeedAsync(collection.DocumentsLink);
var document = documents.FirstOrDefault(_ => _.Id == documentId);
if (document == null)
{
j.id = documentId;
var documentResponse = await client.CreateDocumentAsync(collection.SelfLink, j, disableAutomaticIdGeneration: true);
document = documentResponse.Resource;
var slug = "attachment.jpg";
await client.CreateAttachmentAsync(document.AttachmentsLink, new MemoryStream(jpegBytes),
new MediaOptions { ContentType = "image/jpeg", Slug = slug });
Console.WriteLine("Uploaded attachment with slug=\"{0}\"", slug);
}
#region download attachments
var attachmentsLink = client.CreateDocumentQuery<Document>(collection.DocumentsLink).Where(_ => _.Id == documentId).ToList().First().AttachmentsLink;
var attachments = client.CreateAttachmentQuery(attachmentsLink).AsEnumerable();
var downloadAttachmentTasks = attachments.Select(async attachment =>
{
MediaResponse content = await client.ReadMediaAsync(attachment.MediaLink);
var contentSlug = content.Slug;
var attachmentId = attachment.Id;
var slug = attachmentId;
Console.WriteLine("content.Slug = \"{0}\", attachment.Id = \"{1}\"", content.Slug, attachment.Id);
var buffer = new byte[content.ContentLength];
await content.Media.ReadAsync(buffer, 0, buffer.Length);
await File.OpenWrite(slug).WriteAsync(buffer, 0, buffer.Length);
Console.WriteLine("Downloaded attachment to \"{0}\"", new FileInfo(slug).FullName);
}).ToArray();
await Task.WhenAll(downloadAttachmentTasks);
#endregion
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment