
ASP.NET(twilio.aspnet)的Twilio Helper庫,可幫助您將官方的Twilio SDK集成到C#和.NET中,並將其集成到您的ASP.NET應用程序中。該庫支持.NET框架和ASP.NET Core上的ASP.NET MVC。
該庫可幫助您響應Webhooks,將Twilio客戶端添加到依賴項注入容器中,並驗證HTTP請求來自Twilio。
需要.NET 6.0或更高版本。
運行以下命令使用.NET CLI:
dotnet add package Twilio.AspNet.Core另外,從軟件包管理器控制台或開發人員PowerShell中運行以下命令來安裝最新版本:
Install-Package Twilio.AspNet.Core或者,將Nuget軟件包管理器用於Visual Studio或Jetbrains Rider的Nuget窗口,然後搜索Twilio.aspnet.core並安裝軟件包。
需要.NET 4.6.2或更高版本。
從包裝管理器控制台或開發人員PowerShell中運行以下命令以安裝最新版本:
Install-Package Twilio.AspNet.Mvc或者,使用Nuget軟件包管理器作為Visual Studio或Jetbrains Rider的Nuget窗口,然後搜索twilio.aspnet.mvc並安裝軟件包。
using Twilio . AspNet . Common ;
using Twilio . AspNet . Core ; // or .Mvc for .NET Framework
using Twilio . TwiML ;
public class SmsController : TwilioController
{
// GET: Sms
public TwiMLResult Index ( SmsRequest request )
{
var response = new MessagingResponse ( ) ;
response . Message ( $ "Ahoy { request . From } !" ) ;
return TwiML ( response ) ;
}
}該控制器將處理SMS Webhook。傳入SMS的詳細信息將綁定到SmsRequest request參數。通過繼承TwilioController ,您可以訪問TwiML方法,您可以使用該方法與Twiml響應。
using Twilio . AspNet . Common ;
using Twilio . AspNet . Core ; // or .Mvc for .NET Framework
using Twilio . TwiML ;
public class VoiceController : TwilioController
{
// GET: Voice
public TwiMLResult Index ( VoiceRequest request )
{
var response = new VoiceResponse ( ) ;
response . Say ( $ "Ahoy! Are you from { request . FromCity } ?" ) ;
return TwiML ( response ) ;
}
}該控制器將處理語音webook。傳入語音呼叫的詳細信息將綁定到VoiceRequest request參數。通過繼承TwilioController ,您可以訪問TwiML方法,您可以使用該方法與Twiml響應。
TwiML擴展方法而不是從TwilioController繼承如果您不能從TwilioController類繼承,則可以使用TwiML擴展方法。
using Microsoft . AspNetCore . Mvc ; // or System.Web.Mvc for .NET Framework
using Twilio . AspNet . Common ;
using Twilio . AspNet . Core ; // or .Mvc for .NET Framework
using Twilio . TwiML ;
public class SmsController : Controller
{
// GET: Sms
public TwiMLResult Index ( SmsRequest request )
{
var response = new MessagingResponse ( ) ;
response . Message ( $ "Ahoy { request . From } !" ) ;
return this . TwiML ( response ) ;
}
}該樣本與以前的SMS Webhook樣本相同,但是SmsController從ASP.NET MVC提供的Controller繼承,而不是從TwilioController繼承,而是使用this.TwiML使用TwiML擴展方法。
Twilio.aspnet.Core還支持最小API。
該示例向您展示瞭如何使用HTTP GET並發布SMS Webhook。
using Microsoft . AspNetCore . Mvc ;
using Twilio . AspNet . Core . MinimalApi ;
using Twilio . TwiML ;
var builder = WebApplication . CreateBuilder ( args ) ;
var app = builder . Build ( ) ;
app . MapGet ( "/sms" , ( [ FromQuery ] string from ) =>
{
var response = new MessagingResponse ( ) ;
response . Message ( $ "Ahoy { from } !" ) ;
return Results . Extensions . TwiML ( response ) ;
} ) ;
app . MapPost ( "/sms" , async ( HttpRequest request ) =>
{
var form = await request . ReadFormAsync ( ) ;
var from = form [ "from" ] ;
response . Message ( $ "Ahoy { from } !" ) ;
return Results . Extensions . TwiML ( response ) ;
} ) ;
app . Run ( ) ;在傳統的MVC控制器中, SmsRequest , VoiceRequest和其他鍵入請求對象將受到綁定,但最小API不支持相同的模型綁定。
相反,您可以使用FromQuery屬性綁定HTTP獲取請求的單個參數。當您不指定FROFQUERY屬性時,除了查詢字符串參數外,還將考慮多個源可以綁定。對於HTTP POST請求,您可以獲取表單,然後通過字符串索引檢索單個參數。
要使用twiml響應,請使用Results.Extensions.TwiML方法。
Twilio.aspnet配備多個類,可幫助您將Webhooks的數據綁定到強烈鍵入的.NET對象。這是類列表:
SmsRequest :保留用於傳入SMS Webhook請求的數據SmsStatusCallbackRequest :保留用於跟踪出站Twilio SMS或MMS的交付狀態的數據StatusCallbackRequest :保留用於跟踪出站Twilio語音通話狀態的數據VoiceRequest :保留傳入語音通話的數據注意僅MVC控制器和Razor頁面支持模型綁定到鍵入的.NET對象。在最小API和其他方案中,您必須編寫代碼以自己提取參數。
以下示例顯示瞭如何接受入站SMS,響應並跟踪SMS響應的狀態。
using Twilio . AspNet . Common ;
using Twilio . AspNet . Core ; // or .Mvc for .NET Framework
using Twilio . TwiML ;
public class SmsController : TwilioController
{
private readonly ILogger < SmsController > logger ;
public SmsController ( ILogger < SmsController > logger )
{
this . logger = logger ;
}
public TwiMLResult Index ( SmsRequest request )
{
var messagingResponse = new MessagingResponse ( ) ;
messagingResponse . Message (
body : $ "Ahoy { request . From } !" ,
action : new Uri ( "/Sms/StatusCallback" ) ,
method : Twilio . Http . HttpMethod . Post
) ;
return TwiML ( messagingResponse ) ;
}
public void StatusCallback ( SmsStatusCallbackRequest request )
{
logger . LogInformation ( "SMS Status: {Status}" , request . MessageStatus ) ;
}
}如上示例所示,您可以添加一個SmsRequest作為參數,MVC將為您綁定對象。然後,代碼以帶有status和method參數的SMS響應。當SMS的狀態更改時,Twilio將向StatusCallback操作發送HTTP POST請求。您可以將SmsStatusCallbackRequest添加為參數,MVC將為您綁定對象。
在ASP.NET Core中,您可以使用.AddTwilioClient方法將Twilio Rest API客戶端添加到ASP.NET Core的服務中:
using Twilio . AspNet . Core ;
var builder = WebApplication . CreateBuilder ( args ) ;
builder . Services . AddTwilioClient ( )現在,您可以通過依賴注入要求ITwilioRestClient和TwilioRestClient 。
您可以使用以下配置配置Twilio客戶端:
{
"Twilio" : {
"AuthToken" : " [YOUR_AUTH_TOKEN] " ,
"Client" : {
"AccountSid" : " [YOUR_ACCOUNT_SID] " ,
"AuthToken" : " [YOUR_AUTH_TOKEN] " ,
"ApiKeySid" : " [YOUR_API_KEY_SID] " ,
"ApiKeySecret" : " [YOUR_API_KEY_SECRET] " ,
"CredentialType" : " [Unspecified|AuthToken|ApiKey] " ,
"Region" : null ,
"Edge" : null ,
"LogLevel" : null
}
}
}一些筆記:
Twilio:Client:AuthToken回到Twilio:AuthToken 。您只需要配置其中之一即可。Twilio:Client:CredentialType具有以下有效值: Unspecified , AuthToken或ApiKey 。Twilio:Client:CredentialType為可選,默認為Unspecified 。如果Unspecified ,將檢測到您是否配置了API密鑰還是驗證令牌。如果您不希望使用.NET配置配置Twilio客戶端,則可以手動進行操作:
using Twilio . AspNet . Core ;
var builder = WebApplication . CreateBuilder ( args ) ;
builder . Services
. AddTwilioClient ( ( serviceProvider , options ) =>
{
options . AccountSid = "[YOUR_ACCOUNT_SID]" ;
options . AuthToken = "[YOUR_AUTH_TOKEN]" ;
options . ApiKeySid = "[YOUR_API_KEY_SID]" ;
options . ApiKeySecret = "[YOUR_API_KEY_SECRET]" ;
options . Edge = null ;
options . Region = null ;
options . LogLevel = null ;
options . CredentialType = CredentialType . Unspecified ;
} ) ;警告不要將您的身份令牌或API密鑰秘密用硬編碼為代碼,也不要將其檢查為源控件。我們建議使用秘密經理進行本地發展。另外,您可以使用環境變量,保管庫服務或其他更安全的技術。
默認情況下,當您調用.AddTwilioClient時,將配置HTTP客戶端工廠,用於為Twilio Rest客戶端提供HttpClient 。如果您想自定義此HTTP客戶端,則可以通過覆蓋“ Twilio” HTTP客戶端工廠來進行.AddTwilioClient
builder . Services . AddTwilioClient ( ) ;
builder . Services . AddHttpClient ( "Twilio" )
. ConfigureHttpClient ( client =>
{
client . BaseAddress = new Uri ( "YOUR_PROXY_ADDRESS" ) ;
} )
. ConfigurePrimaryHttpMessageHandler ( ( ) => new HttpClientHandler
{
// same options as the Twilio C# SDK
AllowAutoRedirect = false
} ) ;Webhooks要求您的端點公開可用,但這也引入了不良演員可以找到您的Webhook URL並嘗試濫用它的風險。
幸運的是,您可以驗證HTTP請求源自Twilio。 Twilio.AspNet庫提供了一個屬性,該屬性將在MVC中驗證您的請求。實現在Twilio.AspNet.Core和Twilio.AspNet.Mvc庫之間有所不同。
在啟動時添加.AddTwilioRequestValidation方法:
using Twilio . AspNet . Core ;
var builder = WebApplication . CreateBuilder ( args ) ;
builder . Services . AddTwilioRequestValidation ( ) ;然後配置請求驗證:
{
"Twilio" : {
"AuthToken" : " [YOUR_AUTH_TOKEN] " ,
"RequestValidation" : {
"AuthToken" : " [YOUR_AUTH_TOKEN] " ,
"AllowLocal" : false ,
"BaseUrlOverride" : " https://??????.ngrok.io "
}
}
}關於配置的幾個註釋:
Twilio:RequestValidation:AuthToken落在Twilio:AuthToken上。您只需要配置其中之一即可。AllowLocal將跳過驗證。BaseUrlOverride 。當前請求的路徑將附加到BaseUrlOverride以進行請求驗證。您可以在當前的HTTP請求上使用轉發的標頭中間件來設置正確的方案,端口,主機等,而不是配置
BaseUrlOverride。
using Microsoft . AspNetCore . HttpOverrides ;
using Twilio . AspNet . Core ;
var builder = WebApplication . CreateBuilder ( args ) ;
builder . Services . AddTwilioRequestValidation ( ) ;
builder . Services . Configure < ForwardedHeadersOptions > ( options => options . ForwardedHeaders = ForwardedHeaders . All ) ;
// more service configuration
var app = builder . Build ( ) ;
app . UseForwardedHeaders ( ) ;
// more request pipeline configuration
app . Run ( ) ;結果,每當重新啟動NGrok或更改反向代理URL時,您都不必配置BaseUrlOverride 。遵循Microsoft的指南,以安全地配置轉發的標頭中間件。
您還可以手動配置請求驗證:
using Twilio . AspNet . Core ;
var builder = WebApplication . CreateBuilder ( args ) ;
builder . Services
. AddTwilioRequestValidation ( ( serviceProvider , options ) =>
{
options . AuthToken = "[YOUR_AUTH_TOKEN]" ;
options . AllowLocal = false ;
options . BaseUrlOverride = "https://??????.ngrok.io" ;
} ) ;警告不要將您的身份令牌編碼為代碼,也不要將其檢查為源控件。我們建議使用秘密經理進行本地發展。另外,您可以使用環境變量,保管庫服務或其他更安全的技術。
一旦配置了請求驗證,您就可以在MVC中使用[ValidateRequest]屬性。您可以將屬性應用於MVC區域,控制器和操作。這是將屬性應用於Index操作的示例:
using Twilio . AspNet . Common ;
using Twilio . AspNet . Core ;
using Twilio . TwiML ;
public class SmsController : TwilioController
{
[ ValidateRequest ]
public TwiMLResult Index ( SmsRequest request )
{
var response = new MessagingResponse ( ) ;
response . Message ( "Ahoy!" ) ;
return TwiML ( response ) ;
}
} .NET 7介紹了端點過濾器的概念,您可以將其應用於任何ASP.NET核心端點。用於ASP.NET核心的輔助庫添加了一個端點過濾器,以驗證稱為ValidateTwilioRequestFilter的Twilio請求。
您可以使用ValidateTwilioRequest方法將此過濾器添加到任何端點或端點組:
// add filter to endpoint
app . MapPost ( "/sms" , ( ) => .. . )
. ValidateTwilioRequest ( ) ;
// add filter to endpoint group
var twilioGroup = app . MapGroup ( "/twilio" ) ;
twilioGroup . ValidateTwilioRequest ( ) ;
twilioGroup . MapPost ( "/sms" , ( ) => .. . ) ;
twilioGroup . MapPost ( "/voice" , ( ) => .. . ) ;另外,您可以自己添加端點過濾器:
app . MapPost ( "/sms" , ( ) => .. . )
. AddEndpointFilter < ValidateTwilioRequestFilter > ( ) ; 當您無法使用[ValidateRequest]過濾器或ValidateTwilioRequestFilter時,可以改用ValidateTwilioRequestMiddleware 。您可以添加添加ValidateTwilioRequestFilter :
app . UseTwilioRequestValidation ( ) ;
// or the equivalent: app.UseMiddleware<ValidateTwilioRequestMiddleware>();此中間軟件將對所有請求執行驗證。如果您不想將驗證應用於所有請求,則可以使用app.UseWhen()有條件地運行中間件。
這是如何驗證以路徑/Twilio-Media開頭的請求的示例,以保護只有Twilio代理應該能夠訪問的媒體文件:
using System . Net ;
using Microsoft . Extensions . FileProviders ;
using Microsoft . Extensions . Options ;
using Twilio . AspNet . Core ;
var builder = WebApplication . CreateBuilder ( args ) ;
builder . Services . AddTwilioRequestValidation ( ) ;
var app = builder . Build ( ) ;
app . UseWhen (
context => context . Request . Path . StartsWithSegments ( "/twilio-media" , StringComparison . OrdinalIgnoreCase ) ,
app => app . UseTwilioRequestValidation ( )
) ;
app . UseStaticFiles ( new StaticFileOptions
{
FileProvider = new PhysicalFileProvider ( Path . Combine ( builder . Environment . ContentRootPath , "TwilioMedia" ) ) ,
RequestPath = "/twilio-media"
} ) ;
app . Run ( ) ; 在您的Web.config中,您可以配置請求驗證,如下所示:
<? xml version = " 1.0 " encoding = " utf-8 " ?>
< configuration >
< configSections >
< sectionGroup name = " twilio " type = " Twilio.AspNet.Mvc.TwilioSectionGroup,Twilio.AspNet.Mvc " >
< section name = " requestValidation " type = " Twilio.AspNet.Mvc.RequestValidationConfigurationSection,Twilio.AspNet.Mvc " />
</ sectionGroup >
</ configSections >
< twilio >
< requestValidation
authToken = " [YOUR_AUTH_TOKEN] "
baseUrlOverride = " https://??????.ngrok.io "
allowLocal = " false "
/>
</ twilio >
</ configuration >您還可以使用應用程序設置配置請求驗證:
<? xml version = " 1.0 " encoding = " utf-8 " ?>
< configuration >
< appSettings >
< add key = " twilio:requestValidation:authToken " value = " [YOUR_AUTH_TOKEN] " />
< add key = " twilio:requestValidation:baseUrlOverride " value = " https://??????.ngrok.io " />
< add key = " twilio:requestValidation:allowLocal " value = " false " />
</ appSettings >
</ configuration >如果您使用這兩種方式配置請求驗證,則應用程序設置將覆蓋twilio/requestValidation配置元素。
關於配置的幾個註釋:
allowLocal將跳過驗證。baseUrlOverride 。當前請求的路徑將附加到baseUrlOverride以進行請求驗證。警告不要將您的身份令牌編碼為代碼,也不要將其檢查為源控件。使用
UserSecretsConfigBuilder使用sconfigbuilder進行本地開發或其他配置構建器之一。另外,您應該加密包含諸如auth令牌的秘密的配置部分。
現在,已配置了請求驗證,請使用[ValidateRequest]屬性。您可以將屬性應用於MVC區域,控制器和操作。這是將屬性應用於Index操作的示例:
using Twilio . AspNet . Common ;
using Twilio . AspNet . Mvc ;
using Twilio . TwiML ;
public class SmsController : TwilioController
{
[ ValidateRequest ]
public TwiMLResult Index ( SmsRequest request )
{
var response = new MessagingResponse ( ) ;
response . Message ( "Ahoy!" ) ;
return TwiML ( response ) ;
}
} [ValidateRequest]屬性僅適用於MVC。如果您需要驗證MVC之外的請求,則可以使用Twilio.AspNet提供的RequestValidationHelper類。另外,Twilio SDK的RequestValidator類也可以為您提供幫助。
這是一個最小的API示例,該示例驗證了來自Twilio的傳入請求:
using System . Net ;
using Microsoft . Extensions . Options ;
using Twilio . AspNet . Core ;
using Twilio . AspNet . Core . MinimalApi ;
using Twilio . TwiML ;
var builder = WebApplication . CreateBuilder ( args ) ;
// adds TwilioRequestValidationOptions
builder . Services . AddTwilioRequestValidation ( ) ;
var app = builder . Build ( ) ;
app . MapPost ( "/sms" , ( HttpContext httpContext ) =>
{
if ( IsValidTwilioRequest ( httpContext ) == false )
return Results . StatusCode ( ( int ) HttpStatusCode . Forbidden ) ;
var messagingResponse = new MessagingResponse ( ) ;
messagingResponse . Message ( "Ahoy!" ) ;
return Results . Extensions . TwiML ( messagingResponse ) ;
} ) ;
app . Run ( ) ;
bool IsValidTwilioRequest ( HttpContext httpContext )
{
var options = httpContext . RequestServices
. GetService < IOptions < TwilioRequestValidationOptions > > ( )
? . Value ?? throw new Exception ( "TwilioRequestValidationOptions missing." ) ;
string ? urlOverride = null ;
if ( options . BaseUrlOverride is not null )
{
var request = httpContext . Request ;
urlOverride = $ " { options . BaseUrlOverride . TrimEnd ( '/' ) } { request . Path } { request . QueryString } " ;
}
return RequestValidationHelper . IsValidRequest ( httpContext , options . AuthToken , urlOverride , options . AllowLocal ) ;
} AddTwilioRequestValidation添加了TwilioRequestValidationOptions ,通常用於[ValidateRequest]屬性,但是在此示例中,它用於您自己檢索請求驗證配置。然後在/SMS端點的內部,使用IsValidTwilioRequest方法來驗證請求。 IsValidTwilioRequest從DI檢索請求驗證選項,並執行與[ValidateRequest]對MVC請求所做的相同邏輯。如果請求不有效,則返回HTTP狀態代碼403,否則,將返回twiml返回Twilio。