记开发个人图书收藏清单小程序开发(五)Web开发

决定先开发Web端试试。

新增Web应用:

选择ASP.NET Core Web Application,填写好Name和Location,然后点击OK。

注意红框标出来的,基于.NET Core 2.1版本。登录认证用了微软自带的Identity。Template选择Web Application,也即最新的Razor Pages试图引擎模式。

创建完毕,因为该Template自带的bootstrap还是3.3.7,所以从中文网站下载最新的bootstrap 4.x,同时还需要下载的是popper js插件(如果用到dropdown组件的话,不大明白为何新版Bootstrap不自带这个)。_Layout中的css和js引用也需要同步更新一下,还有就是Navbar菜单需要更新,因为3.x和4.x用的class样式完全不一样。

下面给出示例代码:

 1 <nav class="navbar navbar-expand-lg navbar-light bg-light fixed-top">
 2     <div class="container">
 3         <a asp-page="/Index" class="navbar-brand">PTager Shelves</a>
 4         <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
 5             <span class="navbar-toggler-icon"></span>
 6         </button>
 7 
 8         <div class="collapse navbar-collapse" id="navbarSupportedContent">
 9             <ul class="navbar-nav mr-auto">
10                 <li class="nav-item active">
11                     <a class="nav-link" asp-page="/Index">Home</a>
12                 </li>
13                 <li class="nav-item">
14                     <a class="nav-link" asp-page="/About">About</a>
15                 </li>
16                 <li class="nav-item">
17                     <a class="nav-link" asp-page="/Contact">Contact</a>
18                 </li>
19             </ul>
20             <partial name="_LoginPartial" />
21         </div>
22     </div>
23 </nav>

到此,Web项目基本改造完成了。

当然,前面说到我还是用PTager的现有的登录DB做登录功能,很简单,直接修改appsettings.json文件中的DB连接字符串就好了(如果没有也没事,直接用本地的空DB,注册的时候会提示如何自己创建DB)。

 1 {
 2   "ConnectionStrings": {
 3     "DefaultConnection": "Server=.\\SQL2017;Database=PTager;Trusted_Connection=True;MultipleActiveResultSets=true"
 4   },
 5   "Logging": {
 6     "LogLevel": {
 7       "Default": "Warning"
 8     }
 9   },
10   "AllowedHosts": "*"
11 }

 

开始新增New Book功能。

先check豆瓣图书的api能不能正常调用。

在Pages文件夹下New Folder:Shelves,继续在Shelves文件夹New Item=>Razor Pages,Name直接改为:New。

为了接受豆瓣图书API获取的参数信息,先定义一个DoubanBookModel:

 1     public class DoubanBookModel
 2     {
 3         public string title { get; set; }
 4         public string subtitle { get; set; }
 5         public IEnumerable<string> author { get; set; }
 6         public IEnumerable<string> translator { get; set; }
 7         public string isbn13 { get; set; }
 8         public string isbn10 { get; set; }
 9         public string author_intro { get; set; }
10         public string summary { get; set; }
11         public string publisher { get; set; }
12         public string binding { get; set; }
13         public string origin_title { get; set; }
14         public int pages { get; set; }
15         public string image { get; set; }
16         public string pubdate { get; set; }
17         public string catalog { get; set; }
18         public IEnumerable<TagItem> tags { get; set; }
19         public RatingItem rating { get; set; }
20 
21 
22         public sealed class TagItem
23         {
24             public int count { get; set; }
25             public string name { get; set; }
26             public string title { get; set; }
27         }
28         public sealed class SeriesItem
29         {
30             public int id { get; set; }
31             public string title { get; set; }
32         }
33         public sealed class RatingItem
34         {
35             public int max { get; set; }
36             public int min { get; set; }
37             public int numRaters { get; set; }
38             public string average { get; set; }
39         }
40     }

/Pages/Sheves/New.cshtml:

 1 @page
 2 @model NewModel
 3 @{
 4     ViewData["Title"] = "New Book";
 5 }
 6 <nav aria-label="breadcrumb">
 7     <ol class="breadcrumb">
 8         <li class="breadcrumb-item"><a asp-page="/Index">Home</a></li>
 9         <li class="breadcrumb-item"><a asp-page="/My Books/Index">My Books</a></li>
10         <li class="breadcrumb-item active" aria-current="page">New Book</li>
11     </ol>
12 </nav>
13 <form method="get">
14     <div class="input-group input-group-lg mb-3">
15         <div class="input-group-prepend">
16             <span class="input-group-text" id="basic-addon1">ISBN #</span>
17         </div>
18         <input name="isbn" class="form-control" autofocus autocomplete="off" placeholder="ISBN #">
19         <div class="input-group-append">
20             <button class="btn btn-secondary btn-lg" type="submit">Search</button>
21         </div>
22     </div>
23 </form>
24 <hr />
25 @if (Model.DoubanBook != null)
26 {
27     var item = Model.DoubanBook;
28     <div class="media">
29         @*<img class="align-self-start mr-3" src="@item.image" alt="Generic placeholder image">*@
30         <div class="media-body">
31             <h3 class="mt-0">@item.title<small class="ml-3">@item.subtitle</small></h3>
32             <p><strong>Origin Title: </strong> @item.origin_title</p>
33             <p><strong>Author: </strong> @string.Join("", item.author)</p>
34             <p><strong>Translator: </strong> @string.Join("", item.translator)</p>
35             <p>
36                 <strong>Pubdate: </strong> @item.pubdate
37                 <strong class="ml-3">Publisher: </strong> @item.publisher
38                 <strong class="ml-3">Binding: </strong> @item.binding
39                 <strong class="ml-3">Pages: </strong> @item.pages
40             </p>
41             <p>
42                 <strong>ISBN: </strong> @item.isbn13
43             </p>
44             <p><strong class="mr-3">Author Intro:</strong> @item.author_intro</p>
45             <p><strong class="mr-3">Summary:</strong>@item.summary</p>
46             @foreach (var tag in item.tags)
47             {
48                 <span class="badge badge-info">@tag.name</span>
49             }
50         </div>
51     </div>
52     <hr />
53     <form method="post">
54         <input type="hidden" asp-page="IsbnNbr">
55         <button class="btn btn-warning" type="submit">Add To My Books</button>
56     </form>
57 }

/Pages/Sheves/New.cshtml.cs:

 1     public class NewModel : PageModel
 2     {
 3         [BindProperty]
 4         public string IsbnNbr { get; set; }
 5         public DoubanBookModel DoubanBook { get; set; }
 6 
 7         public async Task OnGetAsync(string isbn)
 8         {
 9             IsbnNbr = isbn?.Trim() ?? string.Empty;
10             if (validIsbnNbr(IsbnNbr))
11             {
12                 DoubanBook = await getDoubanBook();
13             }
14         }
15         private async Task<DoubanBookModel> getDoubanBook()
16         {
17             var url = $"https://api.douban.com/v2/book/isbn/:{IsbnNbr}";
18             var result = await HttpGetAsync(url);
19             return JsonConvert.DeserializeObject<DoubanBookModel>(result);
20         }
21         public async Task<string> HttpGetAsync(string url, Encoding encoding = null)
22         {
23             using (var httpClient = new HttpClient())
24             {
25                 return await httpClient.GetStringAsync(url);
26             }
27         }
28 
29         private bool validIsbnNbr(string isbn)
30             => !string.IsNullOrEmpty(IsbnNbr) && (IsbnNbr.Length == 10 || IsbnNbr.Length == 13);
31     }

好了,现在可以直接从豆瓣图书API获取到返回结果了,并且能展示在页面:

 

posted @ 2018-06-25 15:57  Jnetart  阅读(609)  评论(0编辑  收藏  举报