决定先开发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样式完全不一样。

下面给出示例代码:

 <nav class="navbar navbar-expand-lg navbar-light bg-light fixed-top">
<div class="container">
<a asp-page="/Index" class="navbar-brand">PTager Shelves</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button> <div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" asp-page="/Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" asp-page="/About">About</a>
</li>
<li class="nav-item">
<a class="nav-link" asp-page="/Contact">Contact</a>
</li>
</ul>
<partial name="_LoginPartial" />
</div>
</div>
</nav>

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

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

 {
"ConnectionStrings": {
"DefaultConnection": "Server=.\\SQL2017;Database=PTager;Trusted_Connection=True;MultipleActiveResultSets=true"
},
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*"
}

开始新增New Book功能。

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

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

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

     public class DoubanBookModel
{
public string title { get; set; }
public string subtitle { get; set; }
public IEnumerable<string> author { get; set; }
public IEnumerable<string> translator { get; set; }
public string isbn13 { get; set; }
public string isbn10 { get; set; }
public string author_intro { get; set; }
public string summary { get; set; }
public string publisher { get; set; }
public string binding { get; set; }
public string origin_title { get; set; }
public int pages { get; set; }
public string image { get; set; }
public string pubdate { get; set; }
public string catalog { get; set; }
public IEnumerable<TagItem> tags { get; set; }
public RatingItem rating { get; set; } public sealed class TagItem
{
public int count { get; set; }
public string name { get; set; }
public string title { get; set; }
}
public sealed class SeriesItem
{
public int id { get; set; }
public string title { get; set; }
}
public sealed class RatingItem
{
public int max { get; set; }
public int min { get; set; }
public int numRaters { get; set; }
public string average { get; set; }
}
}

/Pages/Sheves/New.cshtml:

 @page
@model NewModel
@{
ViewData["Title"] = "New Book";
}
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a asp-page="/Index">Home</a></li>
<li class="breadcrumb-item"><a asp-page="/My Books/Index">My Books</a></li>
<li class="breadcrumb-item active" aria-current="page">New Book</li>
</ol>
</nav>
<form method="get">
<div class="input-group input-group-lg mb-3">
<div class="input-group-prepend">
<span class="input-group-text" id="basic-addon1">ISBN #</span>
</div>
<input name="isbn" class="form-control" autofocus autocomplete="off" placeholder="ISBN #">
<div class="input-group-append">
<button class="btn btn-secondary btn-lg" type="submit">Search</button>
</div>
</div>
</form>
<hr />
@if (Model.DoubanBook != null)
{
var item = Model.DoubanBook;
<div class="media">
@*<img class="align-self-start mr-3" src="@item.image" alt="Generic placeholder image">*@
<div class="media-body">
<h3 class="mt-0">@item.title<small class="ml-3">@item.subtitle</small></h3>
<p><strong>Origin Title: </strong> @item.origin_title</p>
<p><strong>Author: </strong> @string.Join("、", item.author)</p>
<p><strong>Translator: </strong> @string.Join("、", item.translator)</p>
<p>
<strong>Pubdate: </strong> @item.pubdate
<strong class="ml-3">Publisher: </strong> @item.publisher
<strong class="ml-3">Binding: </strong> @item.binding
<strong class="ml-3">Pages: </strong> @item.pages
</p>
<p>
<strong>ISBN: </strong> @item.isbn13
</p>
<p><strong class="mr-3">Author Intro:</strong> @item.author_intro</p>
<p><strong class="mr-3">Summary:</strong>@item.summary</p>
@foreach (var tag in item.tags)
{
<span class="badge badge-info">@tag.name</span>
}
</div>
</div>
<hr />
<form method="post">
<input type="hidden" asp-page="IsbnNbr">
<button class="btn btn-warning" type="submit">Add To My Books</button>
</form>
}

/Pages/Sheves/New.cshtml.cs:

     public class NewModel : PageModel
{
[BindProperty]
public string IsbnNbr { get; set; }
public DoubanBookModel DoubanBook { get; set; } public async Task OnGetAsync(string isbn)
{
IsbnNbr = isbn?.Trim() ?? string.Empty;
if (validIsbnNbr(IsbnNbr))
{
DoubanBook = await getDoubanBook();
}
}
private async Task<DoubanBookModel> getDoubanBook()
{
var url = $"https://api.douban.com/v2/book/isbn/:{IsbnNbr}";
var result = await HttpGetAsync(url);
return JsonConvert.DeserializeObject<DoubanBookModel>(result);
}
public async Task<string> HttpGetAsync(string url, Encoding encoding = null)
{
using (var httpClient = new HttpClient())
{
return await httpClient.GetStringAsync(url);
}
} private bool validIsbnNbr(string isbn)
=> !string.IsNullOrEmpty(IsbnNbr) && (IsbnNbr.Length == || IsbnNbr.Length == );
}

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

最新文章

  1. 安卓 android ListView 数据填充
  2. CodeForces 474B E(Contest #1)
  3. ecshop怎么添加配送方式
  4. 5.HBase In Action 第一章-HBase简介(1.1.3 HBase的兴起)
  5. CSS基础知识点(二)——居中
  6. 如何用C#代码查找某个路径下是否包含某个文件
  7. 转:socket编程在windows和linux下的区别
  8. HDU2015校赛 The Country List
  9. 网站卡死,照惯例运行.bat批量处理文件进行重启不起作用
  10. Android中的对话框AlertDialog使用技巧合集-转载
  11. 整理一批 国内外优秀设计团队 &amp; 设计相关网站
  12. java设计模式-----1、简单工厂模式
  13. fasthttp 文档手册
  14. SQL Server分页存储过程通用存储过程
  15. pycharm设置文件编码
  16. 查询的model里面 一般都要有一个要返回的model做属性 ;查询前要传入得参数,查询后返回的参数 都要集合在一个model中
  17. zabbix3.4.7常用监控项
  18. LeetCode--No.008 String to Integer (atoi)
  19. .net Core 依赖注入 Add********说明
  20. Netty入门(四)ByteBuf 字节级别的操作

热门文章

  1. 小程序本作用域下怎么调用全局js
  2. linux-ububtu64位安装docker,及基本命令
  3. React爬坑秘籍(一)——提升渲染性能
  4. Mysql 查询列名
  5. 带入gRPC:gRPC Streaming, Client and Server
  6. python&#39;s decorator&amp;wrapper
  7. java基础三 [深入多态,接口和多态](阅读Head First Java记录)
  8. testng的xml文件说明(TestNG DTD)
  9. react native 触摸Touchable***的区别(TouchableWithoutFeedback、TouchableOpacity、TouchableHighlight、TouchableNativeFeedback)
  10. PHP与Imagemagick