.NET Core开发:项目实践
初始化项目
本来想详细讲一讲dotnet core的,但我对于dotnet core的研究还不到一星期,半吊子,脑子又笨,就不写那些理论出来误人子弟了,还是直接来一篇实践给大家做个参考。废话不多说,直接上项目,这里我设计了一个简单的控制台应用程序,抓取
的双色球信息,并持久化到SQL Server,同时还引用了Json.NET和Dapper两个外部组件。
使用dotnet new新建项目,并入下图所示新建Common、Persistent、Service三个文件夹:

- Common文件夹中用于存放公共组件类;
- Persistent用于存放实体和实体操作类;
- Service用于处理实现抓取业务并将数据通过Common将数据插入到数据库总。
接着,我们需要引入Json.NET和Dapper两个外部组件,传统的.net项目可以通过nuget来管理,.net core项目也是如此,但是他并不会像.net项目那样把package下载到项目的根目录下,而是package下载到用户根目录下集中管理(例:C:\Users\Administrator\.nuget),不得不说,这一套和maven很像,这样的好处是管理起来方便,实现了依赖包的复用,项目看起来也更为清爽,不过如果你需要引入自己开发的项目,就需要使用dotnet pack先对项目进行打包后再做本地引入,project.json的配置如下:
{
"version": "1.0.0-*",
"buildOptions": {
"debugType": "portable",
"emitEntryPoint": true,
"copyToOutPut": "appconfig.json"
},
"dependencies": {
"Newtonsoft.Json": "9.0.1",
"Dapper": "1.50.2",
"System.Data.SqlClient": "4.1.0",
"Microsoft.Extensions.Configuration": "1.0.0-rc2-final",
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0-rc2-final",
"Microsoft.Extensions.Configuration.Json": "1.0.0-rc2-final",
"System.Text.Encoding.CodePages": "4.0.1"
},
"frameworks": {
"netcoreapp1.0": {
"dependencies": {
"Microsoft.NETCore.App": {
"version": "1.0.0"
}
},
"imports": "dnxcore50"
}
},
"runtimes": {
"win7-x64": {},
"osx.10.11-x64": {}
},
"publishOptions": {
"include": [
"appconfig.json"
]
}
}
我们可以看到在project.json的dependencies节点中定义了项目依赖,以"Dapper": "1.50.2"为例,Dapper是我们需要引用的包的名称,1.50.2是引入的版本号,不过请务必使用 https://www.nuget.org 上的名称和版本号,并确认当前包包是否支持.net core。按照微软的官方说法是他们打算在未来启用这个project.json,不过有兴趣的同学可以访问:
https://docs.microsoft.com/en-us/dotnet/articles/core/tools/project-json
查看有关它的详细介绍。

数据库设计
创建Lotto数据库,并执行脚本如下:
USE [Lotto]
CREATE TABLE [dbo].[UnionLotto](
,) NOT NULL,
[SN] [bigint] NOT NULL,
[PublishDate] [datetime] NOT NULL,
[Red1] [int] NOT NULL,
[Red2] [int] NOT NULL,
[Red3] [int] NOT NULL,
[Red4] [int] NOT NULL,
[Red5] [int] NOT NULL,
[Red6] [int] NOT NULL,
[Blue1] [int] NOT NULL,
CONSTRAINT [PK_UnionLotto] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
编码实现
在Common文件夹下新建QuickConfig和QuickBrowser类,QuickBrowser用于发起Http请求抓取数据,QuickConfig用于获取系统配置:
using System;
using System.IO;
using System.Net;
using System.Threading;
namespace JokeBuy.Common
{
/// <summary>
/// Http请求工具类。
/// </summary>
public class QuickBrowser
{
public static string BrowseByGet(string url)
{
);
}
public static string BrowseByPost(string url)
{
);
}
static ManualResetEvent allDone = new ManualResetEvent(false);
static string Browse(string url, string method, int timeout, string contenttype = "application/x-www-form-urlencoded")
{
HttpWebRequest hwr = (HttpWebRequest)WebRequest.Create(url);
hwr.Method = method.ToLower();
hwr.ContinueTimeout = timeout;
hwr.ContentType = contenttype;
BrowserContext bc = new BrowserContext();
bc.BrowseRequest = hwr;
var asyncR = hwr.BeginGetResponse(new AsyncCallback(ResponseCallback), bc);
allDone.WaitOne();
using (Stream repStream = bc.BrowseResponse.GetResponseStream())
{
using (StreamReader sr = new StreamReader(repStream))
{
return sr.ReadToEnd();
}
}
}
static void ResponseCallback(IAsyncResult asyncR)
{
try
{
var bc = (BrowserContext)asyncR.AsyncState;
bc.BrowseResponse = (HttpWebResponse)bc.BrowseRequest.EndGetResponse(asyncR);
Stream repStream = bc.BrowseResponse.GetResponseStream();
return;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
allDone.Set();
}
}
}
public class BrowserContext
{
public HttpWebRequest BrowseRequest { get; set; }
public HttpWebResponse BrowseResponse { get; set; }
}
}
QuickBrowser
在QuickBrowser中,可以看到我并未使用WebRequest.GetResponse()去抓取使用,而是使用了BeginGetResponse的异步方法进行操作,因为.net core中并未发现GetResponse()方法,看来微软在重新设计.net core时,该方法被摒弃了,所以在使用.net core时还是小心为好。
using System;
using Microsoft.Extensions.Configuration;
namespace JokeBuy.Common
{
public class QuickConfig
{
static IConfiguration AppConfig;
static object Lock = new object();
public static string GetConfig(string key)
{
key = string.Format("AppSettings:{0}", key);
if (string.IsNullOrEmpty(key))
throw new ArgumentNullException("配置键不能为空值!");
if (AppConfig == null)
{
lock (Lock)
{
if (AppConfig == null)
{
AppConfig = new ConfigurationBuilder().AddJsonFile(@"appconfig.json").Build();
}
}
}
return AppConfig[key];
}
}
}
QuickConfig
在QuickConfig中,我们可以看到配置文件的获取方式也和.net有了很大的不同,可以使用mermory、json、xml等多种方式,具体可以参考博客园大神
http://www.cnblogs.com/artech/p/new-config-system-01.html
的文章,本例中会去加载自定义的appconfig.josn文件。
使用VS Code新建Class真的很麻烦,namespace和class的声明均需要自己去拼写,不知道有没有人知道什么简便的方法。
在Presistent下新建UnionLotto、UnionLottoFactory和UnionLottoDbWork类:
using System;
namespace JokeBuy.Presistent
{
/// <summary>
/// 双色球实体。
/// </summary>
public class UnionLotto
{
/// <summary>
/// 标识。
/// </summary>
public long Id { get; set; }
/// <summary>
/// 批次号。
/// </summary>
public long SN { get; set; }
/// <summary>
/// 公布日期。
/// </summary>
public DateTime PublishDate { get; set; }
/// <summary>
/// 红球1。
/// </summary>
public int Red1 { get; set; }
/// <summary>
/// 红球1。
/// </summary>
public int Red2 { get; set; }
/// <summary>
/// 红球1。
/// </summary>
public int Red3 { get; set; }
/// <summary>
/// 红球1。
/// </summary>
public int Red4 { get; set; }
/// <summary>
/// 红球1。
/// </summary>
public int Red5 { get; set; }
/// <summary>
/// 红球1。
/// </summary>
public int Red6 { get; set; }
/// <summary>
/// 蓝球1。
/// </summary>
public int Blue1 { get; set; }
}
}
UnionLotto
using System;
namespace JokeBuy.Presistent
{
/// <summary>
/// 双色球实体操作工厂。
/// </summary>
public class UnionLottoFactory
{
/// <summary>
/// 创建双色球。
/// </summary>
/// <returns>双色球实体。</returns>
public static UnionLotto CreateUnionLotto(
long sn,
DateTime pd,
int red1,
int red2,
int red3,
int red4,
int red5,
int red6,
int blue1
)
{
|| red2 < || red3 < || red4 < || red5 < || red6 < || blue1 < )
throw new Exception("Create failed,wrong number!");
|| red2 > || red3 > || red4 > || red5 > || red6 > || blue1 > )
throw new Exception("Create failed,wrong number!");
return new UnionLotto
{
SN = sn,
PublishDate = pd,
Red1 = red1,
Red2 = red2,
Red3 = red3,
Red4 = red4,
Red5 = red5,
Red6 = red6,
Blue1 = blue1
};
}
}
}
UnionLottoFactory
using System.Collections.Generic;
using System.Data.Common;
using System.Data.SqlClient;
using System.Linq;
using Dapper;
using JokeBuy.Common;
namespace JokeBuy.Presistent
{
/// <summary>
///
/// </summary>
public class UnionLottoDbWork
{
public static void AddUnionLotto(UnionLotto entity)
{
using (DbConnection conn = (DbConnection)new SqlConnection(QuickConfig.GetConfig("DbConnStr")))
{
conn.Open();
string insertSql = "INSERT INTO UnionLotto(SN,PublishDate,Red1,Red2,Red3,Red4,Red5,Red6,Blue1)VALUES(@SN,@PublishDate,@Red1,@Red2,@Red3,@Red4,@Red5,@Red6,@Blue1)";
conn.Execute(insertSql, entity);
conn.Close();
}
}
public static UnionLotto GetUnionLottoBySN(long sn)
{
using (DbConnection conn = (DbConnection)new SqlConnection(QuickConfig.GetConfig("DbConnStr")))
{
conn.Open();
string querySql = "select * from UnionLotto where SN=@sn";
var info = conn.Query<UnionLotto>(querySql, new { sn = sn }).SingleOrDefault();
conn.Close();
return info;
}
}
public static void BatchAddUnionLotto(List<UnionLotto> entities)
{
foreach (var entity in entities)
{
if (GetUnionLottoBySN(entity.SN) == null)
{
AddUnionLotto(entity);
}
}
}
}
}
UnionLottoDbWork
在Servie下新建DataSpiderService和UnionLottoService类:
using System;
using System.Collections.Generic;
using JokeBuy.Common;
using JokeBuy.Presistent;
using Newtonsoft.Json;
namespace JokeBuy.Service
{
internal class DataSpiderService
{
/// <summary>
/// 从百度抓取数据。
/// </summary>
/// <returns>数据集合。</returns>
public static List<UnionLotto> BaiduSpider()
{
List<UnionLotto> lottos = new List<UnionLotto>();
return lottos;
}
/// <summary>
/// 从Api抓取数据。
/// </summary>
/// <returns>数据集合。</returns>
public static List<UnionLotto> ApiPlusSpider()
{
List<UnionLotto> lottos = new List<UnionLotto>();
try
{
var json = QuickBrowser.BrowseByGet(QuickConfig.GetConfig("PlusApi"));
var jsonObj = JsonConvert.DeserializeObject<dynamic>(json);
)
{
List<PlusSSQ> ssqs = JsonConvert.DeserializeObject<List<PlusSSQ>>(jsonObj.data.ToString());
; i < ssqs.Count; i++)
{
var nums = ssqs[i].opencode.Split(new char[] { ',', '+' }, StringSplitOptions.RemoveEmptyEntries);
lottos.Add(UnionLottoFactory.CreateUnionLotto(
ssqs[i].expect,
ssqs[i].opentime,
]), ]), ]), ]), ]), ]), ])));
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return lottos;
}
}
internal class PlusSSQ
{
public long expect;
public string opencode;
public DateTime opentime;
}
}
DataSpiderService
using JokeBuy.Presistent;
namespace JokeBuy.Service
{
public class UnionLottoService
{
public static void DataInitial()
{
}
/// <summary>
/// 从API中同步数据。
/// </summary>
public static void DataSync()
{
var lottos = DataSpiderService.ApiPlusSpider();
UnionLottoDbWork.BatchAddUnionLotto(lottos);
}
}
}
UnionLottoService
在根目录下添加appconfig.json文件:
{
"AppSettings": {
"DbConnStr": "Data Source=.\\SQL2012;Initial Catalog=Lotto;Persist Security Info=True;User ID=sa;Password=1234567;",
"PlusApi": "http://f.apiplus.cn/ssq-1.json"
}
}
appconfig.json
appconfig.json中定义了项目数据库链接和api抓取地址,回顾一下project.json中的配置,我们可以发现publishOptions.include配置,因为发布时appconfig.json并不会被拷贝到发布包中,需要手动将其引入进来。
执行
最后在Program中调用:
using System;
using System.Text;
using JokeBuy.Service;
namespace ConsoleApplication
{
public class Program
{
public static void Main(string[] args)
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); //主要用于解决控制台中文输出乱码问题
UnionLottoService.DataSync();
Console.WriteLine("执行完毕!");
Console.ReadLine();
}
}
}
Program
使用dotnet publish后,在..\bin\Debug\netcoreapp1.0\win7-x64\publish下找到JokeBuy.exe执行后,数据成功插入到数据库:

执行成功!
.NET Core开发:项目实践的更多相关文章
- 使用Asp.Net Core MVC 开发项目实践[第一篇:项目结构说明]
先从下图看整体项目结构: Mango.Manager: 为后台管理项目 Mango.Web: 为前台项目 Mango.Framework.Core: 为常用的基础操作类项目 Mango.Framewo ...
- 使用Asp.Net Core MVC 开发项目实践[第五篇:缓存的使用]
项目中我们常常会碰到一些数据,需要高频率用到但是又不会频繁变动的这类,我们就可以使用缓存把这些数据缓存起来(比如说本项目的导航数据,帖子频道数据). 我们项目中常用到有Asp.Net Core 本身提 ...
- 使用Asp.Net Core MVC 开发项目实践[第二篇:EF Core]
在项目中使用EF Core还是比较容易的,在这里我们使用的版本是EF Core 2.2. 1.使用nuget获取EF Core包 这个示例项目使用的是SQLSERVER,所以还需要下载Microsof ...
- 使用Asp.Net Core MVC 开发项目实践[第三篇:基于EF Core的扩展]
上篇我们说到了EFCore的基础使用,这篇我们将讲解下基于EFCore的扩展. 我们在Mango.Framework.EFCore类库项目中创建一个类名EFExtended的扩展类,并且引入相关的命名 ...
- 使用Asp.Net Core MVC 开发项目实践[第四篇:基于EF Core的扩展2]
上篇我们说到了基于EFCore的基础扩展,这篇我们讲解下基于实体结合拉姆达表达式的自定义更新以及删除数据. 先说下原理:其实通过实体以及拉姆达表达式生成SQL语句去执行 第一种更新扩展: 自定义更新字 ...
- 基于 Vue.js 之 iView UI 框架非工程化实践记要 使用 Newtonsoft.Json 操作 JSON 字符串 基于.net core实现项目自动编译、并生成nuget包 webpack + vue 在dev和production模式下的小小区别 这样入门asp.net core 之 静态文件 这样入门asp.net core,如何
基于 Vue.js 之 iView UI 框架非工程化实践记要 像我们平日里做惯了 Java 或者 .NET 这种后端程序员,对于前端的认识还常常停留在 jQuery 时代,包括其插件在需要时就引 ...
- Entity Framework Core Code First 项目实践
Entity Framework Core Code First 实践 任何一种技术的出现都是为了解决一系列特定的问题,只有了解了技术所要解决的关键问题,才能理解它的真正用途,之后,才能在实践中用好它 ...
- 《ASP.NET Core应用开发入门教程》与《ASP.NET Core 应用开发项目实战》正式出版
“全书之写印,实系初稿.有时公私琐务猬集,每写一句,三搁其笔:有时兴会淋漓,走笔疾书,絮絮不休:有时意趣萧索,执笔木坐,草草而止.每写一段,自助覆阅,辄摇其首,觉有大不妥者,即贴补重书,故剪刀浆糊乃不 ...
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(四)
系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...
- 使用VS Code开发调试.NET Core 多项目
使用Visual Studio Code(VS Code)开发调试.NET Core和ASP.NET Core 多项目multiple project. 之前讲解过如果使用Visual Studio ...
随机推荐
- 在MyEclipse中使用debug模式
转:http://blog.csdn.net/competerh_programing/article/details/6773371 1, 首先在一个java文件中设断点,然后运行,当程序走到断点 ...
- Websphere 手动模拟删除应用操作
Websphere 手动模拟删除应用操作 切记:不要在程序还在运行的时候,直接的remove掉应用程序,不然,会发生意外的错误. 最近,在项目中,不小心手动移除了正在运行的应用,发现se ...
- 如何像Uber一样给工程师派单 解放外包落后的生产力
2014年,陈柯好的第一个创业项目失败,半年之内,陈柯好以技术合伙人的方式游走于旅游.电商.团购.票务等各种领域.正当他对职业方向感到迷茫时,“大众创业.万众创新”的口号被提了出来 一时间,技术需求被 ...
- 基于libVLC的视频播放器
本文来自于:http://blog.csdn.net/leixiaohua1020/article/details/42363079 最简单的基于libVLC的例子:最简单的基于libVLC的视频播放 ...
- python第一周:python初识、流程控制
编译性语言:在将源代码编译完毕生成一个可执行文件后才能运行 解释性语言:在代码的运行期间进行编译 动态类型语言:在运行期间才去做数据检查的语言,也就是说在使用动态类型语言时不用指定数据类型 静态类型语 ...
- 用Js写贪吃蛇
使用Javascript做贪吃蛇小游戏, 1.自定义地图宽高,蛇的初始速度 2.食物随机出现 3.蛇的样式属性 4.贪吃蛇玩法(吃食物,碰到边界,吃食物后加速,计分,) <!DOCTYPE ht ...
- 获取DATA的数据
num=DataTable("参数名",dtGlobalSheet) 'systemutil.Run "C:\Program Files (x86)\HP\QuickTe ...
- JSON 基础学习1
http://www.360doc.com/content/10/0809/22/2633_44873063.shtml JSON转字符串: json.stringify(jsonobj); 字符串转 ...
- HDU 1575 EASY
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> ...
- plsql解决64位解决办法
plsql解决64位解决办法 设置PLSQL Developer访问本机64位Oracle 由于在本机Windows Server 2008 R2 X64上安装了64位的Oracle 11.2.0.1 ...