Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Tutorial wird gezeigt, wie Sie zusätzliche Medienformate in ASP.NET-Web-API unterstützen.
Internetmedientypen
Ein Medientyp, der auch als MIME-Typ bezeichnet wird, gibt das Format eines Datenteils an. In HTTP beschreiben Medientypen das Format des Nachrichtentexts. Ein Medientyp besteht aus zwei Zeichenfolgen, einem Typ und einem Untertyp. Zum Beispiel:
- text/html
- image/png
- Anwendung/json
Wenn eine HTTP-Nachricht einen Entitätstext enthält, gibt der Content-Type-Header das Format des Nachrichtentexts an. Dadurch wird dem Empfänger mitgeteilt, wie der Inhalt des Nachrichtentexts analysiert werden soll.
Wenn beispielsweise eine HTTP-Antwort ein PNG-Bild enthält, kann die Antwort die folgenden Header aufweisen.
HTTP/1.1 200 OK
Content-Length: 95267
Content-Type: image/png
Wenn der Client eine Anforderungsnachricht sendet, kann er einen Accept-Header enthalten. Der Accept-Header teilt dem Server mit, welche Medientypen der Client vom Server wünscht. Zum Beispiel:
Accept: text/html,application/xhtml+xml,application/xml
Dieser Header teilt dem Server mit, dass der Client HTML, XHTML oder XML wünscht.
Der Medientyp bestimmt, wie die Web-API den HTTP-Nachrichtentext serialisiert und deserialisiert. Die Web-API verfügt über integrierte Unterstützung für XML-, JSON-, BSON- und Formular-URLencoded-Daten, und Sie können zusätzliche Medientypen unterstützen, indem Sie einen Medienformatierer schreiben.
Um einen Medienformatierer zu erstellen, leiten Sie von einer der folgenden Klassen ab:
- MediaTypeFormatter. Diese Klasse verwendet asynchrone Lese- und Schreibmethoden.
- BufferedMediaTypeFormatter. Diese Klasse leitet sich von MediaTypeFormatter ab, verwendet jedoch synchrone Lese-/Schreibmethoden.
Das Ableiten von BufferedMediaTypeFormatter ist einfacher, da es keinen asynchronen Code gibt, aber es bedeutet auch, dass der aufrufende Thread während der E/A blockieren kann.
Beispiel: Erstellen eines CSV-Medienformatierers
Das folgende Beispiel zeigt einen Medientypformatierer, der ein Product-Objekt in ein CSV-Format (Kommagetrennte Werte) serialisieren kann. In diesem Beispiel wird der Produkttyp verwendet, der im Tutorial Erstellen einer Web-API definiert ist, die CRUD-Vorgänge unterstützt. Hier ist die Definition des Product-Objekts:
namespace ProductStore.Models
{
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string Category { get; set; }
public decimal Price { get; set; }
}
}
Um einen CSV-Formatter zu implementieren, definieren Sie eine Klasse, die von BufferedMediaTypeFormatter abgeleitet ist:
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using ProductStore.Models;
namespace ProductStore.Formatters
{
public class ProductCsvFormatter : BufferedMediaTypeFormatter
{
}
}
Fügen Sie im Konstruktor die vom Formatierer unterstützten Medientypen hinzu. In diesem Beispiel unterstützt der Formatierer den einzelnen Medientyp "text/csv":
public ProductCsvFormatter()
{
// Add the supported media type.
SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/csv"));
}
Überschreiben Sie die CanWriteType-Methode , um anzugeben, welche Typen der Formatierer serialisieren kann:
public override bool CanWriteType(System.Type type)
{
if (type == typeof(Product))
{
return true;
}
else
{
Type enumerableType = typeof(IEnumerable<Product>);
return enumerableType.IsAssignableFrom(type);
}
}
In diesem Beispiel kann der Formatierer einzelne Product
Objekte sowie Sammlungen von Product
Objekten serialisieren.
Überschreiben Sie auf ähnliche Weise die CanReadType-Methode , um anzugeben, welche Typen der Formatierer deserialisieren kann. In diesem Beispiel unterstützt der Formatierer die Deserialisierung nicht, sodass die Methode einfach false zurückgibt.
public override bool CanReadType(Type type)
{
return false;
}
Überschreiben Sie schließlich die WriteToStream-Methode . Diese Methode serialisiert einen Typ, indem er in einen Stream geschrieben wird. Wenn Ihr Formatierer deserialisierung unterstützt, überschreiben Sie auch die ReadFromStream-Methode .
public override void WriteToStream(Type type, object value, Stream writeStream, HttpContent content)
{
using (var writer = new StreamWriter(writeStream))
{
var products = value as IEnumerable<Product>;
if (products != null)
{
foreach (var product in products)
{
WriteItem(product, writer);
}
}
else
{
var singleProduct = value as Product;
if (singleProduct == null)
{
throw new InvalidOperationException("Cannot serialize type");
}
WriteItem(singleProduct, writer);
}
}
}
// Helper methods for serializing Products to CSV format.
private void WriteItem(Product product, StreamWriter writer)
{
writer.WriteLine("{0},{1},{2},{3}", Escape(product.Id),
Escape(product.Name), Escape(product.Category), Escape(product.Price));
}
static char[] _specialChars = new char[] { ',', '\n', '\r', '"' };
private string Escape(object o)
{
if (o == null)
{
return "";
}
string field = o.ToString();
if (field.IndexOfAny(_specialChars) != -1)
{
// Delimit the entire field with quotes and replace embedded quotes with "".
return String.Format("\"{0}\"", field.Replace("\"", "\"\""));
}
else return field;
}
Hinzufügen eines Medienformatierers zur Web-API-Pipeline
Um der Web-API-Pipeline einen Medientypformatierer hinzuzufügen, verwenden Sie die Formatters-Eigenschaft für das HttpConfiguration-Objekt .
public static void ConfigureApis(HttpConfiguration config)
{
config.Formatters.Add(new ProductCsvFormatter());
}
Zeichencodierungen
Optional kann ein Medienformatierer mehrere Zeichencodierungen wie UTF-8 oder ISO 8859-1 unterstützen.
Fügen Sie im Konstruktor der SupportedEncodings-Auflistung einen oder mehrere System.Text.Encoding-Typen hinzu. Legen Sie die Standardcodierung an erster Stelle.
public ProductCsvFormatter()
{
SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/csv"));
// New code:
SupportedEncodings.Add(new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
SupportedEncodings.Add(Encoding.GetEncoding("iso-8859-1"));
}
Rufen Sie in den Methoden WriteToStream und ReadFromStreamMediaTypeFormatter.SelectCharacterEncoding auf, um die bevorzugte Zeichencodierung auszuwählen. Diese Methode gleicht die Anforderungsheader mit der Liste der unterstützten Codierungen ab. Verwenden Sie die zurückgegebene Codierung , wenn Sie aus dem Stream lesen oder schreiben:
public override void WriteToStream(Type type, object value, Stream writeStream, HttpContent content)
{
Encoding effectiveEncoding = SelectCharacterEncoding(content.Headers);
using (var writer = new StreamWriter(writeStream, effectiveEncoding))
{
// Write the object (code not shown)
}
}