Я пытаюсь отправить электронную почту с помощью API Office 365, я не могу использовать пакеты Microsoft.Office365 для отправки, так как в настоящее время они не поддерживают нашу аутентификацию, но у меня есть действующий токен для доступа к API, получения запросов работают отлично, но когда я пытаюсь отправить сообщение на "https://outlook.office. com / api / v2.0 / me / sendmail "Я получаю указанную выше ошибку. Хотя я не могу использовать функции отправки, предоставляемые в Microsoft.Office365, я использую объект сообщения для создания своих писем, а затем их сериализации и публикации.

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) { }
}

Это отправляет в API следующий код json:

{
    "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 });

Чтобы не отправлять нулевые значения, полагая, что он может не принимать значения, даже нулевые, для таких вычислений, как предварительный просмотр тела, но без изменений.

0
Andrew 4 Сен 2016 в 23:02

2 ответа

Лучший ответ

Ошибка указывает на то, что вы отправляете целочисленное значение 0, когда API ожидает строковое значение. Фактически, документация здесь показывает, что { {X1}} также Message.Importance должны быть строками, например:

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

Вы, вероятно, отправляете целочисленные значения для этих свойств, потому что в ваших классах C # они являются перечислениями. Если вы хотите сериализовать перечисления в виде строк по имени, вам необходимо использовать {{X0} }.

Вы можете установить его прямо в свойстве как атрибут, например:

public class Body
{ 
    [JsonConverter(typeof(StringEnumConverter))]
    public ContentType ContentType { get; set; }

    public string Content { get; set; }
}

Вы также можете настроить HttpClient для использования этого конвертера для всех перечислений, как описано в этот ответ.

1
dbc 4 Сен 2016 в 21:40

Благодаря помощи, предоставленной другими ответами, я нашел свое решение, чтобы изменить способ сериализации объекта 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");
1
Andrew 5 Окт 2016 в 14:17