C# - Office API 返回 400 "69 {"error":{"code":"RequestBodyRead","message":"Cannot read the value '0' as a quoted JSON string value."}} 0 "
C# - Office API returning 400 "69 {"error":{"code":"RequestBodyRead","message":"Cannot read the value '0' as a quoted JSON string value."}} 0 "
我正在尝试使用 Office 365 发送电子邮件 API,我无法使用 Microsoft.Office365 包进行发送,因为它们目前不支持我们的身份验证,但我有一个访问 API 的有效令牌,获取请求工作正常,但是当我尝试从 post 到“https://outlook.office.com/api/v2.0/me/sendmail”时,出现上述错误。虽然我不能使用 Microsoft.Office365 中提供的发送功能,但我正在使用消息对象创建我的电子邮件,然后序列化和 posting.
public void SendMail(string Subject, string Body) {
HttpClient client = new HttpClient();
string accessToken = userCache.UserAccessToken;
Uri uri = new Uri("https://outlook.office.com/api/v2.0/me/sendmail");
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>();
recipients.Add(userCache.Email);
#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;
#endregion
try {
dynamic mailObject = new ExpandoObject();
mailObject.Message = email;
mailObject.SaveToSentItems = "true";
HttpResponseMessage hrm = client.PostAsJsonAsync<Object>(uri, mailObject as ExpandoObject).Result;
} catch (Exception e) { }
}
这会将下面的 json 提交给 API:
{
"Message": {
"Subject": "Products",
"Body": {
"ContentType": 0,
"Content": "Products"
},
"BodyPreview": null,
"Importance": 0,
"HasAttachments": null,
"ParentFolderId": null,
"From": {
"EmailAddress": {
"Name": null,
"Address":"andrew.branoff@paretobiz.com"
}
},
"Sender": {
"EmailAddress": {
"Name": null,
"Address": "andrew.branoff@paretobiz.com"
}
},
"ToRecipients": [
{
"EmailAddress": {
"Name": null,
"Address": "andrew.branoff@paretobiz.com"
}
}
],
"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"
}
据我所知,这就是 API 正在寻找的东西,因为我使用了他们自己的对象来构建它,但无论我做什么,它似乎都拒绝我发送的内容。我尝试先使用
进行序列化
JsonConvert.SerializeObject(mailObject, Newtonsoft.Json.Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
不发送空值,认为它可能不接受值,即使是空值,对于它计算的东西,如正文预览,但没有变化。
指定的错误很可能是因为提供的 JSON 负载无效。
问题与此行有关:
email.Body.ContentType = 0;//0=text, 1=html
ContentType
属性 of Microsoft.OutlookServices.ItemBody
接受 string 值(不是 integer):Text
或 HTML
,例如:
email.Body.ContentType = "Text";
该错误表明您在 API 需要字符串值时发送整数值 0
。事实上,文档 here 表明 Message.Body.ContentType
以及 Message.Importance
应该是字符串,例如:
"Body": {
"ContentType": "Text",
"Content": "Products"
},
您可能会为这些属性发送整数值,因为在您的 c# 类 中,它们是枚举。如果要按名称将枚举序列化为字符串,则需要使用 StringEnumConverter
.
可以直接在属性上设置为属性,例如:
public class Body
{
[JsonConverter(typeof(StringEnumConverter))]
public ContentType ContentType { get; set; }
public string Content { get; set; }
}
您还可以配置 HttpClient
以将此转换器用于所有枚举,如 this answer 中所述。
感谢其他答案的帮助,我找到了解决方案,修改 Json.net 序列化对象的方式。我将发布确切的解决方案,以帮助其他人稍后解决此问题。
var settings = new JsonSerializerSettings();
settings.Converters.Add(new StringEnumConverter());
settings.NullValueHandling = NullValueHandling.Ignore;
string json = JsonConvert.SerializeObject(emailObject, Newtonsoft.Json.Formatting.None, settings);
StringContent content = new StringContent(json, Encoding.UTF8, "application/json");
我正在尝试使用 Office 365 发送电子邮件 API,我无法使用 Microsoft.Office365 包进行发送,因为它们目前不支持我们的身份验证,但我有一个访问 API 的有效令牌,获取请求工作正常,但是当我尝试从 post 到“https://outlook.office.com/api/v2.0/me/sendmail”时,出现上述错误。虽然我不能使用 Microsoft.Office365 中提供的发送功能,但我正在使用消息对象创建我的电子邮件,然后序列化和 posting.
public void SendMail(string Subject, string Body) {
HttpClient client = new HttpClient();
string accessToken = userCache.UserAccessToken;
Uri uri = new Uri("https://outlook.office.com/api/v2.0/me/sendmail");
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>();
recipients.Add(userCache.Email);
#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;
#endregion
try {
dynamic mailObject = new ExpandoObject();
mailObject.Message = email;
mailObject.SaveToSentItems = "true";
HttpResponseMessage hrm = client.PostAsJsonAsync<Object>(uri, mailObject as ExpandoObject).Result;
} catch (Exception e) { }
}
这会将下面的 json 提交给 API:
{
"Message": {
"Subject": "Products",
"Body": {
"ContentType": 0,
"Content": "Products"
},
"BodyPreview": null,
"Importance": 0,
"HasAttachments": null,
"ParentFolderId": null,
"From": {
"EmailAddress": {
"Name": null,
"Address":"andrew.branoff@paretobiz.com"
}
},
"Sender": {
"EmailAddress": {
"Name": null,
"Address": "andrew.branoff@paretobiz.com"
}
},
"ToRecipients": [
{
"EmailAddress": {
"Name": null,
"Address": "andrew.branoff@paretobiz.com"
}
}
],
"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"
}
据我所知,这就是 API 正在寻找的东西,因为我使用了他们自己的对象来构建它,但无论我做什么,它似乎都拒绝我发送的内容。我尝试先使用
进行序列化JsonConvert.SerializeObject(mailObject, Newtonsoft.Json.Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
不发送空值,认为它可能不接受值,即使是空值,对于它计算的东西,如正文预览,但没有变化。
指定的错误很可能是因为提供的 JSON 负载无效。
问题与此行有关:
email.Body.ContentType = 0;//0=text, 1=html
ContentType
属性 of Microsoft.OutlookServices.ItemBody
接受 string 值(不是 integer):Text
或 HTML
,例如:
email.Body.ContentType = "Text";
该错误表明您在 API 需要字符串值时发送整数值 0
。事实上,文档 here 表明 Message.Body.ContentType
以及 Message.Importance
应该是字符串,例如:
"Body": {
"ContentType": "Text",
"Content": "Products"
},
您可能会为这些属性发送整数值,因为在您的 c# 类 中,它们是枚举。如果要按名称将枚举序列化为字符串,则需要使用 StringEnumConverter
.
可以直接在属性上设置为属性,例如:
public class Body
{
[JsonConverter(typeof(StringEnumConverter))]
public ContentType ContentType { get; set; }
public string Content { get; set; }
}
您还可以配置 HttpClient
以将此转换器用于所有枚举,如 this answer 中所述。
感谢其他答案的帮助,我找到了解决方案,修改 Json.net 序列化对象的方式。我将发布确切的解决方案,以帮助其他人稍后解决此问题。
var settings = new JsonSerializerSettings();
settings.Converters.Add(new StringEnumConverter());
settings.NullValueHandling = NullValueHandling.Ignore;
string json = JsonConvert.SerializeObject(emailObject, Newtonsoft.Json.Formatting.None, settings);
StringContent content = new StringContent(json, Encoding.UTF8, "application/json");