鍍金池/ 教程/ C#/ http://www.asp.net/web-api/overview/formats-and-model-binding/mo
前言
在本節(jié),你將開始為app定義HTML,并在HTML和視圖模型間添加數據綁定。
在本節(jié),你將使用HTML、JavaScript和Knockout.js庫為應用程序創(chuàng)建客戶端。我們將按如下步驟建立客戶端應用:
前言
前言
http://www.asp.net/web-api/overview/formats-and-model-binding/mo
在本節(jié),你將添加讓用戶可以創(chuàng)建新book的功能。在app.js中,添加如下代碼到視圖模型:
在本節(jié),你將添加查看每本書的詳細信息的功能。在app.js中,添加以下代碼到視圖模型:
前言
這篇文章描述了ASP.NET Web API如何將HTTP請求發(fā)送(路由)到控制器。
前言
前言
這篇文章描述了ASP.NET Web API如何將HTTP請求路由到控制器上的特定動作。
前言
在這最后一節(jié)中,你將把應用程序發(fā)布到Azure。在Solution Explorer中,右擊項目并選擇Publish。
前言
總結

http://www.asp.net/web-api/overview/formats-and-model-binding/mo

現(xiàn)在,我們的Web API暴露數據庫實體給客戶端,而客戶端接收直接映射到你的數據庫表的數據。然而,這不永遠都是個好辦法。有時候你可以想要改變發(fā)送到客戶端的數據的形式。例如,你可以想要: 1, 移除環(huán)形引用(見上一章) 2, 隱藏客戶端不應該看到的特定屬性 3, 為了減少有效載荷而省略一些屬性 4, 拼接包含嵌套的對象圖,以使它們對客戶端更便利 5, 避免”over-posting”漏洞(查看Model Validation(http://www.asp.net/web-api/overview/formats-and-model-binding/model-validation-in-aspnet-web-api)關于over-posting的討論) 6, 對你的服務層和數據層進行解耦

為了完成它,你應該定義一個數據傳輸對象(DTO,data transfer object)。DTO是一個定義了數據將會如何在網絡上傳輸的對象。讓我們來看看它如何工作于Book實體。在Models文件夾下,添加兩個DTO類:

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; }
    }
}

BookDetailDTO類包含了Book模型的所有屬性,除了用于承載作者姓名的字符串AuthorName。BookDTO類包含了BookDetailDTO的屬性的子集。

下一步,在BooksController類中替換兩個返回DTO的GET方法。我們將使用LINQ的Select語句將Book實體轉換到DTO。

// 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);
} 

這是新的GetBooks方法所生成的SQL查詢。你可以查看EF從LINQ Select轉換到SQL Select的語句。

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]

最后,修改PostBook方法以返回DTO。

[ResponseType(typeof(Book))]
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);
}

總結:在這個教程中,我們在代碼中手動地轉換到DTO。另一種方式是使用像AutoMapper這樣的庫來處理自動轉換。