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.
Abgeschlossenes Projekt herunterladen
Im Moment macht unsere Web-API die Datenbankentitäten für den Client verfügbar. Der Client empfängt Daten, die ihren Datenbanktabellen direkt zugeordnet sind. Das ist jedoch nicht immer eine gute Idee. Manchmal möchten Sie die Form der Daten ändern, die Sie an den Client senden. Sie könnten zum Beispiel Folgendes tun:
- Entfernen von Zirkelbezügen (siehe vorheriger Abschnitt).
- Blenden Sie bestimmte Eigenschaften aus, die Clients nicht anzeigen sollen.
- Auslassen einiger Eigenschaften, um die Nutzlast zu verringern
- Objektstrukturen, die geschachtelte Objekte enthalten, vereinfachen, um sie für Clients bequemer zu gestalten.
- Vermeiden Sie "Over-Posting"-Sicherheitsrisiken. (Siehe Modellüberprüfung für eine Diskussion über die Überbuchung.)
- Entkoppeln Sie Ihre Dienstebene von Ihrer Datenbankebene.
Dazu können Sie ein Datenübertragungsobjekt (Data Transfer Object , DTO) definieren. Ein DTO ist ein Objekt, das definiert, wie die Daten über das Netzwerk gesendet werden. Sehen wir uns an, wie dies mit der Book-Entität funktioniert. Fügen Sie im Ordner "Models" zwei DTO-Klassen hinzu:
namespace BookService.Models
{
public class BookDto
{
public int Id { get; set; }
public string Title { get; set; }
public string AuthorName { get; set; }
}
}
namespace BookService.Models
{
public class BookDetailDto
{
public int Id { get; set; }
public string Title { get; set; }
public int Year { get; set; }
public decimal Price { get; set; }
public string AuthorName { get; set; }
public string Genre { get; set; }
}
}
Die BookDetailDto Klasse enthält alle Eigenschaften aus dem Book-Modell, mit der Ausnahme, dass AuthorName es sich um eine Zeichenfolge handelt, die den Namen des Autors enthält. Die BookDto Klasse enthält eine Teilmenge von Eigenschaften aus BookDetailDto.
Ersetzen Sie als Nächstes die beiden GET-Methoden in der BooksController Klasse durch Versionen, die DTOs zurückgeben. Wir verwenden die LINQ Select-Anweisung , um aus Book-Entitäten in DTOs zu konvertieren.
// GET api/Books
public IQueryable<BookDto> GetBooks()
{
var books = from b in db.Books
select new BookDto()
{
Id = b.Id,
Title = b.Title,
AuthorName = b.Author.Name
};
return books;
}
// GET api/Books/5
[ResponseType(typeof(BookDetailDto))]
public async Task<IHttpActionResult> GetBook(int id)
{
var book = await db.Books.Include(b => b.Author).Select(b =>
new BookDetailDto()
{
Id = b.Id,
Title = b.Title,
Year = b.Year,
Price = b.Price,
AuthorName = b.Author.Name,
Genre = b.Genre
}).SingleOrDefaultAsync(b => b.Id == id);
if (book == null)
{
return NotFound();
}
return Ok(book);
}
Dies ist die von der neuen Methode generierte SQL.Here is the SQL generated by the new GetBooks method. Sie können sehen, dass EF die LINQ Select in eine SQL SELECT-Anweisung übersetzt.
SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Title] AS [Title],
[Extent2].[Name] AS [Name]
FROM [dbo].[Books] AS [Extent1]
INNER JOIN [dbo].[Authors] AS [Extent2] ON [Extent1].[AuthorId] = [Extent2].[Id]
Ändern Sie schließlich die PostBook Methode, um einen DTO zurückzugeben.
[ResponseType(typeof(BookDto))]
public async Task<IHttpActionResult> PostBook(Book book)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.Books.Add(book);
await db.SaveChangesAsync();
// New code:
// Load author name
db.Entry(book).Reference(x => x.Author).Load();
var dto = new BookDto()
{
Id = book.Id,
Title = book.Title,
AuthorName = book.Author.Name
};
return CreatedAtRoute("DefaultApi", new { id = book.Id }, dto);
}
Hinweis
In dieser Anleitung konvertieren wir DTOs manuell im Code. Eine weitere Option besteht darin, eine Bibliothek wie AutoMapper zu verwenden, die die Konvertierung automatisch behandelt.