我正在一个项目中使用 WhatsApp Business Cloud API C# Wrapper Library 和 SignalR 来为网页创建实时聊天。我已经设法根据 SignalR 连接将发送到网站的消息分开(这样从网站的 WhatsApp 帐户发送的消息就不会在不同的连接上混合,这些连接都共享相同的 WhatsApp 号码),但我陷入了困境从网站向 WhatsApp 帐户发送消息。发送消息的action如下,位于HomeController.cs文件
/// <summary>
/// This is to handle:
/// 1. Plain Text messgaes
/// 2. Text Templates (NO params)
/// 3. Text Templates with Params
/// </summary>
/// <param name="payload"></param>
/// <returns></returns>
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> SendWhatsAppTextMessage(SendTemplateMessageViewModel payload)
{ // Functional using SendMessageController
try
{
SendWhatsAppPayload sendPayload = new();
sendPayload.SendText = new SendTextPayload()
{ ToNum = payload.RecipientPhoneNumber };
sendPayload.SendText.PreviewUrl = false;
if (payload.Message != null)
{ // This is a normal plain Text Message
sendPayload.SendText.Message = payload.Message;
}
else
{ // This is a Template Test Message
sendPayload.Template = new WhatsappTemplate();
sendPayload.Template.Name = payload.TemplateName;
// CJM to add a Params Textbox on the Form
if (payload.TemplateParams != null)
{
string strParams = payload.TemplateParams; // "Cornelius#DAFP";
List<string> listParams = strParams.Split(new string[] { "#" }, StringSplitOptions.None).ToList();
sendPayload.Template.Params = listParams;
}
}
// Send the message and get the WAMId
string WAMIds = _sendMessageController.GetWAMId((await _sendMessageController.SendWhatsApp_TextAsync(sendPayload)).Value);
if (WAMIds != null)
{
return RedirectToAction(nameof(Index)).WithSuccess("Success", $"Successfully sent video template message with WAMId '{WAMIds}'");
}
else
{
return RedirectToAction(nameof(SendWhatsAppTemplateMessage));
}
}
catch (WhatsappBusinessCloudAPIException ex)
{
_logger.LogError(ex, ex.Message);
return RedirectToAction(nameof(SendWhatsAppTemplateMessage)).WithDanger("Error", ex.Message);
}
}
这是来自 SendWhatsAppTextMessage.cshtml 文件的视图
@model SendTemplateMessageViewModel
@{
ViewData["Title"] = "Send WhatsApp Text Message Page";
ViewData["CurrentPage"] = "Send WhatsApp Text Message";
Layout = "~/Views/Shared/AdminLTE/_AdminLayout.cshtml";
ViewData["ControllerName"] = nameof(HomeController).Replace("Controller", "");
ViewData["ActionName"] = nameof(HomeController.SendWhatsAppTextMessage);
}
<section class="content">
<div class="row">
<div class="col-12">
<div class="card card-info">
<div class="card-header">
<h3 class="card-title">Send WhatsApp Text Message</h3>
</div> <!--/. card-header -->
<!--Form start -->
<form asp-action="SendWhatsAppTextMessage">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="card-body">
<div class="form-group">
<label class="control-label">Recipient Phone Number</label>
<input asp-for="RecipientPhoneNumber" class="form-control" />
<span asp-validation-for="RecipientPhoneNumber" class="form-control" />
</div>
<div class="form-group">
<label class="control-label">Message</label>
<input asp-for="Message" class="form-control" />
<span asp-validation-for="Message" class="form-control" />
</div>
</div> <!--/. card-body -->
<div class="card-footer">
<button type="submit" name="submit" class="btn btn-primary">Send Message</button>
</div>
</form>
</div> <!-- /.card -->
</div>
</div>
</section>
@section Scripts {
@{
await Html.RenderPartialAsync("_ValidationScriptsPartial");
}
}
以这种方式使用按钮发送消息的问题是,调用操作后,页面上会进行回发,并且 SignalR 连接会重置,因此我无法跟踪页面上的聊天。我想要实现的只是在从网站发送消息的同时保持 SignalR 连接,以便像往常一样看到聊天(网站用户和来自另一端的消息)。
谢谢。
编辑:
AJAX请求如下
$.ajax({
method: "POST",
url: '@Url.Action("SendWhatsAppTextMessage", "Home")',
data: { LinkUrl: '', MediaId: '', Message: $("#Message").val(), RecipientPhoneNumber: $("#RecipientPhoneNumber").val(), TemplateName: '', TemplateParams: '', hdnIdConexion: $("#hdnIdConexion").val() },
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function () {
},
error: function () {
alert("No se ha podido enviar el mensaje.");
}
});
如果我从
data
中删除JSON末尾的逗号,它将正确发送,但事实上,payload
的属性为空。我也尝试将键作为字符串传递给 data
,但我得到了相同的结果。
您的 AJAX 请求不起作用,因为您没有使用 JSON 模型。如果您想使用 JSON,那么您需要配置视图模型来处理 JSON 序列化。
如果没有,请将您的 AJAX 请求更改为以下内容:
$.ajax({
method: "POST",
url: '@Url.Action("SendWhatsAppTextMessage", "Home")',
data: { linkUrl: '', mediaId: '', message: $("#Message").val(), recipientPhoneNumber: $("#RecipientPhoneNumber").val(), templateName: '', templateParams: '', hdnIdConexion: $("#hdnIdConexion").val() },
success: function () {
},
error: function () {
alert("No se ha podido enviar el mensaje.");
}
});
注意属性名称是驼峰式大小写而不是 pascal。并且缺少JSON数据类型。我还摆脱了防伪造属性,但如果您需要它,请参阅这篇文章:include antiforgerytoken in ajax post ASP.NET MVC
我使用以下模型测试了上述内容:
// I'm assuming this is similar to what you have.
public class SendTemplateMessageViewModel
{
public string LinkUrl {get; set; }
public string MediaId {get; set; }
public string Message {get; set; }
public string RecipientPhoneNumber {get; set; }
public string TemplateName {get; set; }
public string TemplateParams {get; set; }
public string HdnIdConexion {get; set; }
}
它按预期工作。如果我是你,我会更改此模型以与 JSON 序列化兼容。实现更清晰、更清晰的实施。
希望这能让你继续前进。