Mandrill 电子邮件发送错误:请输入一个数组

Posted

技术标签:

【中文标题】Mandrill 电子邮件发送错误:请输入一个数组【英文标题】:Mandrill Email sending error : Please enter an array 【发布时间】:2020-01-11 02:40:29 【问题描述】:

山魈

我正在使用 RestSharp 对 Mandrill 进行 API 调用以发送电子邮件。

public List<EmailResult> SendMessageTemplate(MandrillApi mapiResponse, string templateName, EmailMessage emailMessage)
    
        //if (mapiResponse != null && !string.IsNullOrEmpty(mapiResponse.ApiKey) && !string.IsNullOrEmpty(mapiResponse.BaseUrl)
        //                         && !string.IsNullOrEmpty(templateName) && templateContent != null && templateContent.Count > 0 && emailMessage != null)
        if (mapiResponse != null && !string.IsNullOrEmpty(mapiResponse.ApiKey) && !string.IsNullOrEmpty(mapiResponse.BaseUrl)
                                 && !string.IsNullOrEmpty(templateName) && emailMessage != null)
        

            List<EmailResult> emailResult = new List<EmailResult>();

            var soEmailMessage = JsonConvert.SerializeObject(emailMessage);
            restRequest = new RestSharp.RestRequest
            
                RequestFormat = DataFormat.Json,
                Method = RestSharp.Method.POST,
                //Resource = string.Format("0/send-template.json", "messages")
                Resource = string.Format("0/send.json", "messages")
            ;
            restRequest.AddBody(new  key = mapiResponse.ApiKey, template_name = templateName, message = soEmailMessage );

            restClient = new RestSharp.RestClient(mapiResponse.BaseUrl);
            var response = restClient.Execute(restRequest);

            emailResult = JsonConvert.DeserializeObject<List<EmailResult>>(response.Content);

            return emailResult;
        

        else
            return null;
    

但是我得到的响应是

“请输入一个数组”。

 "status":"error","code":-2,"name":"ValidationError","message":"Validation error: \"message\":\"Please enter an array\""

序列化后生成的JSON如下:

"message": 
"attachments": [],
"auto_html": null,
"auto_text": true,
"bcc_address": null,
"from_email": "test@gmail.com",
"from_name": "ABC",
"global_merge_vars": [
    "content": "test",
    "name": "ffname"
],
"google_analytics_campaign": null,
"google_analytics_domains": null,
"headers": null,
"html": null,
"images": null,
"important": null,
"inline_css": null,
"merge": null,
"merge_vars": null,
"metadata": null,
"preserve_recipients": false,
"raw_message": null,
"raw_to": null,
"recipient_metadata": null,
"return_path_domain": null,
"signing_domain": null,
"subaccount": null,
"subject": "Test",
"merge_language": null,
"tags": ["Sep-2019"],
"text": null,
"to": [
    "email": "shubhamtest@gmail.com",
    "name": "Test Email Address",
    "type": null
],
"track_clicks": true,
"track_opens": true,
"tracking_domain": null,
"url_strip_qs": null,
"view_content_link": null 

EmailMessage 类是 Mandrill 程序集的一部分,它包含:

Mandrill 组件:我通过 NugetPackage 安装它。请找到以下链接:

https://www.nuget.org/packages/Mandrill/

我尝试了一些解决方案,例如将 emailmessage 对象添加到列表中,然后将其转换为数组。但它给出的响应为"[]"

有人可以推荐一下吗?

谢谢

【问题讨论】:

您是为此使用特定的客户端 SDK,还是您自己编写了 C# 类?我只是想知道它是否是 within 消息而不是数组。根据mandrillapp.com/api/docs/messages.JSON.html#method=send,“消息”本身确实应该是一个对象,但其中有几个属性,如果已定义,则需要是数组。也许其中之一就是问题(来自 API 的错误消息不是很有用!)。向我们展示您正在生成的 JSON 和/或相关的 C# 类是有意义的。 SendMessageTemplate 方法是我编写的自定义方法。但是,作为参数传递的 EmailMessage 类存在于 Mandrill 程序集中。我已经编辑了我的问题并更新了 JSON " Mandrill 组件" ...哪一个?从快速搜索来看,这个 API 似乎有一些竞争的 .NET 客户端库 P.S.我看不出那个 JSON 有什么明显的错误。您是否尝试过通过 PostMan 之类的工具发送请求?因此,我们可以尝试确定问题是否真的出在请求数据上,还是出在 C# 代码中的其他内容上。 是的,我尝试使用 Postman 并得到正确的响应。对于 mandrill assemble,我已经更新了我的问题。请查看已编辑的问题。 【参考方案1】:

我想我现在可以看到问题了:

您正在对消息数据进行双重序列化。怎么样,你可能会问?好了,就这样吧:

var soEmailMessage = JsonConvert.SerializeObject(emailMessage);

emailMessage 转换为 JSON。所以soEmailMessage 是一个字符串。然后在创建消息正文时将其添加到另一个对象中:

new  key = mapiResponse.ApiKey, template_name = templateName, message = soEmailMessage 

这将创建另一个包含 3 个属性的 C# 对象,其中一个是您的消息。而且您不能在 HTTP 请求中发送 C# 对象。因此,RestSharp 将根据您的DataFormat.Json 指令将整个对象序列化为 JSON。但此时,消息已经是一个 JSON 字符串。所以你最终会被发送到服务器的是一个名为“消息”的属性,它是一个单一的字符串,包含 JSON 数据及其属性等转义,所以对于服务器来说,它看起来就像一大行文本,不是它所期望的对象。它无法发现这一点并反序列化数据。


简单的解决办法是:

不要手动序列化,只需让 RestSharp 为您序列化整个请求正文即可:

new  key = mapiResponse.ApiKey, template_name = templateName, message = emailMessage 

而且,您正在使用的客户端库已经为您提供了一个类来包装您的消息 - 您不需要定义自己的对象。使用SendMessageRequest 类:

restRequest.AddBody(new SendMessageRequest()  key = mapiResponse.ApiKey, message = emailMessage );

或者,如果您想使用模板发送,您可以改用SendMessageRequestTemplate 类。

我也不认为您实际上也需要自己使用 RestSharp。根据MandrillApi class,有一些方法可以自动将正确类型的请求发送到 API 端点。


附:另请参阅RestSharp JSON Parameter Posting,了解有人在使用 RestSharp 时对数据进行双重序列化的类似问题。

附言我不知道为什么 API 错误会抱怨数组,但对我来说似乎很清楚,上面肯定是导致问题的原因。

【讨论】:

以上是关于Mandrill 电子邮件发送错误:请输入一个数组的主要内容,如果未能解决你的问题,请参考以下文章

Mandrill 发送的电子邮件字体颜色错误

使用 Mandrill 发送电子邮件模板给我错误

Mandrill:请输入一个数组

Mandrill:无法通过表单发送邮件

IOS JSON 从 Mandrill 发送电子邮件

Mandrill API 错误地显示“已发送”状态