Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting created document result to POCO

I have the following code that calls DocumentDB and creates a new Employee document. How do I then convert the result to Employee document again? Basically, I want to capture the created document and convert it to Employee object.

var result = await client.CreateDocumentAsync(collection.SelfLink, employee);

if(result.StatusCode == System.Net.HttpStatusCode.Created)
{
   Employee emp = result.Resource; // How do I convert the result to Employee object here?
}
like image 252
Sam Avatar asked Nov 25 '14 04:11

Sam


4 Answers

You can do a dynamic cast like this:

Employee emp = (dynamic)result.Resource;

like image 184
Arnab Chakraborty Avatar answered Oct 26 '22 16:10

Arnab Chakraborty


I wrote an extension method to do this:

public static async Task<T> ReadAsAsync<T>(this Document d)
{
    using (var ms = new MemoryStream())
    using (var reader = new StreamReader(ms))
    {
        d.SaveTo(ms);
        ms.Position = 0;
        return JsonConvert.DeserializeObject<T>(await reader.ReadToEndAsync());
    }
}

Then you can use it like

Document d;
var myObj = await d.ReadAsAsync<MyObject>();
like image 38
mdickin Avatar answered Oct 26 '22 17:10

mdickin


(Copying over Andrew Davis's answer, from the DocumentDB MSDN forums, for the stackoverflow community)

The simplest way would be to have your Employee class inherit from Document, and then cast result.Resource to Employee. If you don't want to inherit from Document, you could also define an explicit cast between Document and Employee.

Having the Employee class inherit from Document should work out-of-the-box if the names of the members of your Employee class match the names of the corresponding properties of the JSON representation.

Defining your own type conversion gives you more control, and might look something like this:

public static explicit operator Employee(Document doc)
{
    Employee emp = new Employee();
    emp.Name = doc.GetPropertyValue<string>("employeeName");
    emp.Number = doc.GetPropertyValue<int>("employeeNumber");
    /* and so on, for all the properties of Employee */
    return emp;
}

This would define an explicit cast from Document to Employee. You'll have to make sure the GetPropertyValue strings (and type arguments) match your JSON properties.

like image 7
Andrew Liu Avatar answered Oct 26 '22 18:10

Andrew Liu


Here's a a synchronous extension method that doesn't silently miss properties like the (dynamic) cast method can. Uses recent .NET Core features Span and System.Text.Json for performance.

Usage:

Document doc; // source Document
MyType converted = doc.ConvertTo<MyType>();

Implementation:

public static T ConvertTo<T>(this Document item)
{
    using var stream = new MemoryStream();
    item.SaveTo(stream);
    var bytes = new ReadOnlySpan<byte>(stream.GetBuffer()).Slice(0, (int)stream.Length);
    return JsonSerializer.Deserialize<T>(bytes);
}
like image 1
Noah Stahl Avatar answered Oct 26 '22 17:10

Noah Stahl