
Mit der Twilio Helper Library für ASP.NET (Twilio.aspnet) können Sie die offizielle Twilio SDK für C# und .NET in Ihre ASP.NET -Anwendungen integrieren. Die Bibliothek unterstützt ASP.NET MVC auf .NET Framework und ASP.NET Core.
Diese Bibliothek hilft Ihnen dabei, auf Webhooks zu reagieren, den Twilio -Client zum Abhängigkeitsinjektionsbehälter hinzuzufügen und die HTTP -Anfrage zu validieren, die von Twilio stammt.
Benötigt .net 6.0 oder höher.
Führen Sie den folgenden Befehl aus, um das Paket mit der .NET -CLI zu installieren:
dotnet add package Twilio.AspNet.CoreFühren Sie aus der Paket -Manager -Konsole oder Entwickler PowerShell den folgenden Befehl aus, um die neueste Version zu installieren:
Install-Package Twilio.AspNet.CoreVerwenden Sie alternativ den Nuget -Paket -Manager für Visual Studio oder das Nuget -Fenster für JetBrains Rider, suchen Sie dann nach Twilio.aspnet.core und installieren Sie das Paket.
Benötigt .NET 4.6.2 oder höher.
Führen Sie aus der Package Manager Console oder Developer PowerShell den folgenden Befehl aus, um die neueste Version zu installieren:
Install-Package Twilio.AspNet.MvcVerwenden Sie alternativ den Nuget -Paket -Manager für Visual Studio oder das Nuget -Fenster für JetBrains Rider, suchen Sie dann nach Twilio.aspnet.mvc und installieren Sie das Paket.
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 ) ;
}
} Dieser Controller leitet das SMS -Webhook ab. Die Details der eingehenden SMS werden an den SmsRequest request gebunden. Durch Erben des TwilioController erhalten Sie Zugriff auf die TwiML -Methode, mit der Sie mit Twiml antworten können.
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 ) ;
}
} Dieser Controller leitet das Voice Webhook ab. Die Details des eingehenden Sprachanrufs werden an den Parameter VoiceRequest request gebunden. Durch Erben des TwilioController erhalten Sie Zugriff auf die TwiML -Methode, mit der Sie mit Twiml antworten können.
TwiML -Erweiterungsmethoden anstatt von TwilioController zu erben Wenn Sie nicht von der TwilioController -Klasse erben können, können Sie die TwiML -Erweiterungsmethoden verwenden.
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 ) ;
}
} Dieses Beispiel TwiML dem vorherigen SMS -Webhook -Beispiel, aber anstatt von TwilioController zu erben, erbt der SmsController von der ASP.NET MVC bereitgestellt Controller und verwendet this.TwiML .
Twilio.aspnet.core unterstützt auch minimale APIs.
Dieses Beispiel zeigt Ihnen, wie Sie einen SMS -Webhook mit HTTP GET und Post übernehmen können.
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 ( ) ; Bei herkömmlichen MVC -Controllern wären die SmsRequest , VoiceRequest und andere typisierte Anforderungsobjekte gebunden, aber minimale APIs unterstützt nicht die gleiche Modellbindung.
Stattdessen können Sie individuelle Parameter für HTTP -GET -Anforderungen mit dem Attribut FromQuery binden. Wenn Sie das Attribut von Fragemery nicht angeben, werden mehrere Quellen zusätzlich zu den Parametern der Abfragezeichenfolge angesehen. Für HTTP -Postanforderungen können Sie das Formular abrufen und dann einzelne Parameter per String -Index abrufen.
Verwenden Sie mit Twiml die Results.Extensions.TwiML -Methoden.
Twilio.aspnet wird mit mehreren Klassen geliefert, mit denen Sie die Daten von Webhooks an stark typisierte .NET -Objekte binden können. Hier ist die Liste der Klassen:
SmsRequest : Hält Daten für eingehende SMS -Webhook -AnfragenSmsStatusCallbackRequest : Hält Daten zur Verfolgung des Zustellstatus eines ausgehenden Twilio SMS oder MMSStatusCallbackRequest : Hält Daten für die Verfolgung des Status eines ausgehenden Twilio -SprachanrufsVoiceRequest : Hält Daten für eingehende SprachanrufeBeachten Sie nur, dass MVC -Controller und Rasierseiten die Modellbindung an typisierte .NET -Objekte unterstützen. In minimalen APIs und anderen Szenarien müssen Sie Code schreiben, um die Parameter selbst zu extrahieren.
Das folgende Beispiel zeigt, wie eingehende SMS akzeptiert, reagiert und den Status der SMS -Antwort verfolgt.
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 ) ;
}
} Wie im obigen Beispiel gezeigt, können Sie einen SmsRequest als Parameter hinzufügen, und MVC binden das Objekt für Sie. Der Code reagiert dann mit einem SMS mit dem Parameter status und method . Wenn sich der Status der SMS ändert, sendet Twilio eine HTTP -Postanforderung an StatusCallback -Aktion. Sie können einen SmsStatusCallbackRequest als Parameter hinzufügen, und MVC wird das Objekt für Sie binden.
In ASP.NET Core können Sie den Twilio -REST -API -Client den Diensten von ASP.NET Core mit der .AddTwilioClient -Methode wie folgt hinzufügen:
using Twilio . AspNet . Core ;
var builder = WebApplication . CreateBuilder ( args ) ;
builder . Services . AddTwilioClient ( ) Jetzt können Sie ITwilioRestClient und TwilioRestClient per Abhängigkeitsinjektion anfordern.
Sie können den Twilio -Client mit der folgenden Konfiguration konfigurieren:
{
"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
}
}
}Ein paar Notizen:
Twilio:Client:AuthToken fällt auf Twilio:AuthToken . Sie müssen nur einen von ihnen konfigurieren.Twilio:Client:CredentialType hat die folgenden gültigen Werte: Unspecified , AuthToken oder ApiKey .Twilio:Client:CredentialType ist optional und standardmäßig Unspecified . Wenn Unspecified , wird festgestellt, ob Sie einen API -Schlüssel oder ein Auth -Token konfiguriert haben.Wenn Sie den Twilio -Client nicht mit der .NET -Konfiguration konfigurieren möchten, können Sie dies manuell tun:
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 ;
} ) ;WARNUNG CODEN Sie Ihr Auth-Token- oder API-Key-Geheimnis nicht in Code und überprüfen Sie sie nicht in der Quellensteuerung. Wir empfehlen, den Secrets Manager für die lokale Entwicklung zu verwenden. Alternativ können Sie Umgebungsvariablen, einen Tresordienst oder andere sichere Techniken verwenden.
Wenn Sie standardmäßig .AddTwilioClient aufrufen, wird ein HTTP -Client -Werk konfiguriert, mit dem der Twilio REST -Client einen HttpClient bereitstellt. Wenn Sie diesen HTTP -Client anpassen möchten, können Sie dies tun, indem Sie die HTTP -Client -Fabrik "Twilio" überschreiben, nachdem Sie .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 verlangen, dass Ihr Endpunkt öffentlich verfügbar ist. Dies führt jedoch auch das Risiko ein, dass schlechte Akteure Ihre Webhook -URL finden und versuchen, sie zu missbrauchen.
Zum Glück können Sie überprüfen, ob eine HTTP -Anfrage aus Twilio stammt. Die Twilio.AspNet -Bibliothek enthält ein Attribut, das die Anfrage für Sie in MVC validiert. Die Implementierung unterscheidet sich zwischen der Bibliothek Twilio.AspNet.Core und Twilio.AspNet.Mvc .
Fügen Sie die .AddTwilioRequestValidation -Methode beim Start hinzu:
using Twilio . AspNet . Core ;
var builder = WebApplication . CreateBuilder ( args ) ;
builder . Services . AddTwilioRequestValidation ( ) ;Konfigurieren Sie dann die Anforderungsvalidierung:
{
"Twilio" : {
"AuthToken" : " [YOUR_AUTH_TOKEN] " ,
"RequestValidation" : {
"AuthToken" : " [YOUR_AUTH_TOKEN] " ,
"AllowLocal" : false ,
"BaseUrlOverride" : " https://??????.ngrok.io "
}
}
}Ein paar Notizen zur Konfiguration:
Twilio:RequestValidation:AuthToken fällt auf Twilio:AuthToken . Sie müssen nur einen von ihnen konfigurieren.AllowLocal überspringt die Validierung, wenn die HTTP -Anfrage von Localhost stammt.BaseUrlOverride , falls Ihre App hinter einem Reverse -Proxy oder einem Tunnel wie NGROK steckt. Der Pfad der aktuellen Anfrage wird zur Anfrage zur Validierung an die BaseUrlOverride angehängt.Info , anstatt die
BaseUrlOverridezu konfigurieren, können Sie mit den weitergeleiteten Header Middleware das richtige Schema, den Port, den Host usw. auf der aktuellen HTTP -Anforderung festlegen.
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 ( ) ; Infolgedessen müssen Sie BaseUrlOverride nicht konfigurieren, wenn Sie NGROK neu starten, oder die Reverse -Proxy -URLs ändern. Befolgen Sie die Anleitung von Microsoft, um die weitergeleitete Header Middleware sicher zu konfigurieren.
Sie können auch die Anforderungsvalidierung manuell konfigurieren:
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" ;
} ) ;WARNUNG CODEN SIE IHREM AUTH-Token in Code nicht und überprüfen Sie sie nicht in der Quellensteuerung. Wir empfehlen, den Secrets Manager für die lokale Entwicklung zu verwenden. Alternativ können Sie Umgebungsvariablen, einen Tresordienst oder andere sichere Techniken verwenden.
Sobald die Anforderungsvalidierung konfiguriert wurde, können Sie das Attribut [ValidateRequest] in MVC verwenden. Sie können das Attribut weltweit auf MVC -Bereiche, -Controller und Aktionen anwenden. Hier ist ein Beispiel, in dem das Attribut auf die Index angewendet wird:
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 führt das Konzept der Endpunktfilter ein, das Sie auf jeden ASP.NET -Kernendpunkt anwenden können. Die Helfer -Bibliothek für ASP.NET Core fügte einen Endpunktfilter hinzu, um Twilio -Anforderungen zu validieren, die als ValidateTwilioRequestFilter bezeichnet werden.
Sie können diesen Filter zu einer beliebigen Endpunkt- oder Endpunktgruppe hinzufügen, indem Sie die ValidateTwilioRequest -Methode:
// 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" , ( ) => .. . ) ;Alternativ können Sie den Endpunktfilter selbst hinzufügen:
app . MapPost ( "/sms" , ( ) => .. . )
. AddEndpointFilter < ValidateTwilioRequestFilter > ( ) ; Wenn Sie den [ValidateRequest] -Filter oder ValidateTwilioRequestFilter nicht verwenden können, können Sie stattdessen die ValidateTwilioRequestMiddleware verwenden. Sie können den ValidateTwilioRequestFilter wie folgt hinzufügen:
app . UseTwilioRequestValidation ( ) ;
// or the equivalent: app.UseMiddleware<ValidateTwilioRequestMiddleware>(); Diese Middleware führt die Validierung für alle Anfragen durch. Wenn Sie die Validierung nicht auf alle Anfragen anwenden möchten, können Sie app.UseWhen() verwenden, um die Middleware bedingt auszuführen.
Hier ist ein Beispiel dafür, wie Anfragen validieren, die mit Path /Twilio-Media beginnen, um Mediendateien zu schützen, auf die nur der Twilio-Proxy zugreifen sollte:
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 ( ) ; In Ihrem Web.config können Sie die Anforderungsvalidierung wie unten gezeigt konfigurieren:
<? 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 >Sie können die Anforderungsvalidierung auch mit den App -Einstellungen konfigurieren:
<? 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 > Wenn Sie die Anforderungsvalidierung mithilfe von beiden Arten konfigurieren, überschreibt die App -Einstellung das twilio/requestValidation -Konfigurationselement.
Ein paar Notizen zur Konfiguration:
allowLocal überspringt die Validierung, wenn die HTTP -Anfrage von Localhost stammt.baseUrlOverride für den Fall, dass Sie sich vor einem Reverse -Proxy oder einem Tunnel wie NGROK befinden. Der Pfad der aktuellen Anfrage wird zur Anfrage zur Validierung an die baseUrlOverride angehängt.WARNUNG CODEN SIE IHREM AUTH-Token in Code nicht und überprüfen Sie sie nicht in der Quellensteuerung. Verwenden Sie den
UserSecretsConfigBuilderfür die lokale Entwicklung oder einen der anderen Konfigurationsbauer. Alternativ sollten Sie die Konfigurationsabschnitte, die Geheimnisse wie das Auth -Token enthalten, verschlüsseln.
Verwenden Sie nun das Attribut [ValidateRequest] . Sie können das Attribut weltweit auf MVC -Bereiche, -Controller und Aktionen anwenden. Hier ist ein Beispiel, in dem das Attribut auf die Index angewendet wird:
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 ) ;
}
} Das Attribut [ValidateRequest] funktioniert nur für MVC. Wenn Sie Anfragen außerhalb von MVC validieren müssen, können Sie die von Twilio.AspNet bereitgestellte RequestValidationHelper -Klasse verwenden. Alternativ kann die RequestValidator -Klasse aus dem Twilio SDK Ihnen auch dabei helfen.
Hier ist ein minimales API -Beispiel, das die eingehende Anfrage validiert, die von Twilio stammt:
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 fügt die TwilioRequestValidationOptions hinzu, die normalerweise für das [ValidateRequest] -attribut verwendet wird. In diesem Beispiel wird jedoch verwendet, um die Konfiguration der Anforderungsvalidierung selbst abzurufen. Innerhalb des /SMS -Endpunkts wird die IsValidTwilioRequest -Methode verwendet, um die Anforderung zu validieren. IsValidTwilioRequest ruft die Anforderungsvalidierungsoptionen von DI ab und führt dieselbe Logik aus wie [ValidateRequest] für MVC -Anforderungen. Wenn die Anforderung nicht gültig ist, wird der HTTP -Statuscode 403 zurückgegeben, andernfalls wird einige Twiml an Twilio zurückgegeben.