Andrew Andrew - 19 days ago 4x
JSON Question

C# - Office API returning 400 "69 {"error":{"code":"RequestBodyRead","message":"Cannot read the value '0' as a quoted JSON string value."}} 0 "

I'm trying to send email using the Office 365 API, I can't use the Microsoft.Office365 packages for sending, as they don't currently support our authentication, but I do have a valid token to access the API, get requests work perfectly, but when I try to post to "" I get the above error. While I can't use the send functions provided in Microsoft.Office365 I am using the message object to create my emails then serializing and posting.

public void SendMail(string Subject, string Body) {
HttpClient client = new HttpClient();
string accessToken = userCache.UserAccessToken;
Uri uri = new Uri("");
client.DefaultRequestHeaders.Add("User-Agent", agent);
client.DefaultRequestHeaders.Add("client-request-id", requestGuid);
client.DefaultRequestHeaders.Add("return-client-request-id", "true");
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);
List<string> recipients = new List<string>();

#region Create Email Message
Message email = new Message();
email.Body = new ItemBody();
email.Body.Content = Body;
email.Body.ContentType = 0;//0=text, 1=html
email.From = new Recipient();
email.From.EmailAddress = new EmailAddress();
email.From.EmailAddress.Address = userCache.Email;//set from email to email of current logged in user

email.Importance = Importance.Normal;
email.Sender = email.From;
email.Subject = Subject;
email.ToRecipients = recipients;
try {
dynamic mailObject = new ExpandoObject();
mailObject.Message = email;
mailObject.SaveToSentItems = "true";
HttpResponseMessage hrm = client.PostAsJsonAsync<Object>(uri, mailObject as ExpandoObject).Result;
} catch (Exception e) { }

This submits the json below to the API:

"Message": {
"Subject": "Products",
"Body": {
"ContentType": 0,
"Content": "Products"
"BodyPreview": null,
"Importance": 0,
"HasAttachments": null,
"ParentFolderId": null,
"From": {
"EmailAddress": {
"Name": null,
"Sender": {
"EmailAddress": {
"Name": null,
"Address": ""
"ToRecipients": [
"EmailAddress": {
"Name": null,
"Address": ""
"CcRecipients": [],
"BccRecipients": [],
"ReplyTo": [],
"ConversationId": null,
"UniqueBody": null,
"DateTimeReceived": null,
"DateTimeSent": null,
"IsDeliveryReceiptRequested": null,
"IsReadReceiptRequested": null,
"IsDraft": null,
"IsRead": null,
"WebLink": null,
"Attachments": [],
"ChangeKey": null,
"Categories": [],
"DateTimeCreated": null,
"DateTimeLastModified": null,
"Id": null
"SaveToSentItems": "true"

As far as I can tell this is what the API is looking for, since I used their own object to build it, but it seems to reject what I send no matter what I do. I have tried serializing first using

JsonConvert.SerializeObject(mailObject, Newtonsoft.Json.Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });

to not send the null values, figuring it might not accept values, even null, for things it calculates like the body preview, but no change.

dbc dbc

The error indicates that you are sending an integer value 0 when the API expects a string value. And in fact the documentation here shows that Message.Body.ContentType as well Message.Importance should be strings, e.g:

  "Body": {
    "ContentType": "Text",
    "Content": "Products"

You are likely sending integer values for these properties because, in your c# classes, they are enums. If you want to serialize enums as strings by name, you need to use StringEnumConverter.

You could set it directly on the property as an attribute, e.g.:

public class Body
    public ContentType ContentType { get; set; }

    public string Content { get; set; }

You could also configure HttpClient to use this converter for all enums as explained in this answer.