目录
介绍
使用代码
- 下载源代码696.3 KB
在本文中,我将说明一个端到端解决方案(服务端>后端>前端),以创建新的.NET Core Web服务并在前端使用该服务。我将逐步演示如何在ASP.NET Core中开发RESTful Web服务应用程序,以及如何使用实体框架将该服务连接到SQL Server,以及如何使用JavaScript使用HTML开发的前端UI进行消费。
使用代码在我的完整课程中,我将创建一个培训服务作为示例,以演示Web服务,实体框架和一些前端概念。前端将提供一个UI,以使用REST API的表格形式列出所有培训细节,而另一个表格则以名称,开始日期,结束日期和“确认”按钮作为输入字段。确认后,REST API应将新的培训详细信息保存到数据库中。
让我们从Visual Studio开始,使用.NET Core创建一个新的Web服务(REST)应用程序。
1、打开VS,转到“文件”>“新建”,然后选择“项目”>“ ASP.NET Core Web应用程序”。选择解决方案名称(例如,培训服务)和本地目录的位置。单击确定。
2、使用默认示例valuecontroller(以后可以删除)选择用于创建REST API的API 。您可以取消选中“为HTTPS配置”复选框,因为这将创建基于SSL的项目,并且您必须在URL中使用HTTPS而不是HTTP(这是可选步骤)。
3、单击确定,您将看到以下项目结构:
4、让我们安装SQL Server的实体框架模型来创建一个表,即tblTraining有三个属性,Name(char[256)),StartDate(datetime),EndDate(datetime)。
CREATE TABLE [dbo].[TblTraining] (
[Name] CHAR (256) NOT NULL,
[StartDate] DATETIME NOT NULL,
[EndDate] DATETIME NULL,
PRIMARY KEY CLUSTERED ([Name] ASC));
您也可以使用VS来设置实体框架和模型,在这里我没有为实体框架添加更多步骤,这也不是本文的讨论范围。模型准备就绪后,获取连接字符串。
如果您已经有任何现有框架,则只需添加此新表进行测试并执行以下命令:
scaffold-DBContext "your connection string which start with Data Source= ……………….."
Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -tables tblTraining
public partial class tempdbContext : DbContext
{
public tempdbContext()
{
}
public tempdbContext(DbContextOptions options)
: base(options)
{
}
public virtual DbSet TblTraining { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
#warning To protect potentially sensitive information in your connection string,
#you should move it out of source code.
#See http://go.microsoft.com/fwlink/?LinkId=723263
#for guidance on storing connection strings.
optionsBuilder.UseSqlServer
(@"your connection string starts with Data Source=...........");
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasAnnotation("ProductVersion", "2.2.4-servicing-10062");
modelBuilder.Entity(entity =>
{
entity.HasKey(e => e.Name);
entity.Property(e => e.Name)
.HasMaxLength(256)
.IsUnicode(false)
.ValueGeneratedNever();
entity.Property(e => e.EndDate).HasColumnType("date");
entity.Property(e => e.StartDate).HasColumnType("date");
});
}
}
public partial class TblTraining
{
public string Name { get; set; }
public DateTime StartDate { get; set; }
public DateTime? EndDate { get; set; }
}
public class TrainingViewModel
{
public string EndDate { get; set; }
public string StartDate { get; set; }
public string Name { get; set; }
}
5、打开Startup.cs并为此Web服务设置与数据库的连接。就我而言,我的数据库名称是tempdb,其创建了tempdbContext。在您的ConfigureServices方法中添加以下代码。
// This method gets called by the runtime.
// Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
var connection =@"your connection string starts with Data Source=...........";
services.AddDbContext(o => o.UseSqlServer(connection));
services.AddScoped();
}
6、接下来,您可以使用内部服务/帮助器概念在服务请求数据时读取/验证数据。我已经创建了使用数据库上下文管理数据的ITrainingServices接口和相应的服务类TrainingServices。使用这种方法,您还可以创建一个独立于db上下文的本地服务(LocalTrainingServices),并将值保留在内存中进行测试。如果在这种情况下尚未建立实体框架,则可以在startup.cs中将本地服务作为Scope。用以下代码替换startup.cs中的AddScoped行:
services.AddScoped();
public interface ITrainingServices
{
Task GetTrainingData();
TrainingViewModel GetTrainingData(string name);
bool CreateTraining(TrainingViewModel viewModel);
void Delete(string name);
}
public class TrainingServices : ITrainingServices
{
private readonly tempdbContext dbcontext;
public TrainingServices(tempdbContext context)
{
this.dbcontext = context;
}
public async Task GetTrainingData()
{
return await dbcontext.TblTraining.Select(s => new TrainingViewModel()
{ Name = s.Name, StartDate = s.StartDate.ToString(),
EndDate = s.EndDate.ToString() }).ToListAsync();
}
public TrainingViewModel GetTrainingData(string name)
{
var s = dbcontext.TblTraining.FirstOrDefault(d => d.Name == name);
if (s == null)
{
return null;
}
return new TrainingViewModel { Name = s.Name,
StartDate = s.StartDate.ToString(), EndDate = s.EndDate.ToString() };
}
public async void Delete(string name)
{
var s = dbcontext.TblTraining.FirstOrDefault(d => d.Name == name);
if (s == null)
{
return;
}
dbcontext.TblTraining.Remove(s);
await dbcontext.SaveChangesAsync();
}
public bool CreateTraining(TrainingViewModel viewModel)
{
try
{
var start = DateTime.Parse(viewModel.StartDate);
var end = DateTime.Parse(viewModel.EndDate);
if (start < end)
{
return false;
}
dbcontext.TblTraining.Add(new TblTraining()
{ Name = viewModel.Name, StartDate = start, EndDate = end });
int count = dbcontext.SaveChanges();
if (count > 0)
{
return true;
}
return false;
}
catch (Exception ex)
{
return false;
}
}
}
public class LocalTrainingServices : ITrainingServices
{
private static readonly List
trainingViewModels = new List()
{
new TrainingViewModel()
{Name = "c#", StartDate = "2012-01-01", EndDate = "2012-12-01"},
new TrainingViewModel()
{Name = "java", StartDate = "2013-01-01", EndDate = "2014-12-01"},
new TrainingViewModel()
{Name = "python", StartDate = "2018-01-01", EndDate = "2018-12-01"},
};
public Task GetTrainingData()
{
return new Task(() => trainingViewModels);
}
public TrainingViewModel GetTrainingData(string name) =>
trainingViewModels.FirstOrDefault(d => d.Name == name);
public void Delete(string name)
{
var s = trainingViewModels.FirstOrDefault(d => d.Name == name);
if (s == null)
{
return;
}
trainingViewModels.Remove(s);
}
public bool CreateTraining(TrainingViewModel viewModel)
{
if (GetTrainingData(viewModel.Name) == null)
{
trainingViewModels.Add(viewModel);
return true;
}
return false;
}
}
7、现在,让我们开始真正实现REST API/Web服务。通过右键单击Controller文件夹=> Add => Controller创建一个新的控制器。选择与我们的情况相符的那一项;如果要直接用控制器映射模型实体,则可以选择最后一个选项。即,使用实体框架进行操作的API控制器。但就我而言,我正在使用具有读/写操作的API控制器。选择名称TrainingController,因为它将在最终URL名称中使用该名称来访问服务。
主控制器类。
[Route("api/[controller]")]
[ApiController]
public class TrainingController : ControllerBase
{
private readonly ITrainingServices _trainingService;
public TrainingController(ITrainingServices trainingService)
{
_trainingService = trainingService;
}
// GET: api/Training
[HttpGet]
public async Task Get()
{
return await _trainingService.GetTrainingData();
}
// GET: api/Training/5
[HttpGet("{name}", Name = "Get")]
public TrainingViewModel Get(string name)
{
return _trainingService.GetTrainingData(name);
}
// POST: api/Training
[HttpPost]
public void Post(TrainingViewModel value)
{
if (!_trainingService.CreateTraining(value))
{
ModelState.AddModelError
(value.Name, "End date is greater than start date");
}
}
// DELETE: api/ApiWithActions/5
[HttpDelete("{name}")]
public void Delete(string name)
{
_trainingService.Delete(name);
}
}
8、好了,我们已经使用REST(即HttpGet,HttpPost等)完成了Web服务,您可以在iis中部署此服务,也可以从vs本地部署此服务,选择服务名称,然后点击运行绿色按钮。您最终必须获得该服务的URL,例如https:// localhost:yourportno [default:5001] / api / Training。这里,项目是培训;即访问服务的控制器名称。
9、服务正在运行,让我们尝试使用此服务。在编写UI部分之前,让我们检查该服务是否确实有效,您可以使用Chrome扩展程序“ARC”或类似postman的工具进行验证。只需粘贴URL并检查响应即可。
10、让我们编写一个小型前端应用程序,以HTML格式并使用JavaScript加载此数据。这是代码:
Training
Training Name
Start Date
End Date
Training Name:
Start Date :
End Date :
$('form').submit(function (e) {
e.preventDefault();
const data = {
Name: $('#name').val(),
Startdate: $('#startdate').val(),
EndDate: $('#enddate').val()
}
let tag = '' + data.Name + '';
tag += '' + data.Startdate + '';
tag += '' + data.Enddate + '';
$('table>tbody').append(tag);
const api = 'https://localhost:5001/api/training'
console.log(data);
$.post(api, { Name: data.Name, Startdate:data.Startdate,
EndDate:data.EndDate });
});
JavaScript:
// JavaScript source code
'use strict'
$(document).ready(function ()
{
getpartials('header');
getpartials('footer');
getTraningData();
});
$('form').submit(function (e) {
e.preventDefault();
const data = {
Name: $('#name').val(),
Startdate: $('#startdate').val(),
EndDate: $('#enddate').val()
}
let tag = '' + data.Name + '';
tag += '' + data.Startdate + '';
tag += '' + data.Enddate + '';
$('table>tbody').append(tag);
const api = 'https://localhost:5001/api/training'
console.log(data);
$.post(api, { Name: data.Name, Startdate:data.Startdate, EndDate:data.EndDate });
});
function getpartials(type)
{
$.get('partials/' + type + '.html')
.then(function (data)
{
$(type).html(data);
}).catch(function (err)
{
console.log(err);
});
}
function getTraningData() {
const api = 'https://localhost:5001/api/training'
$.getJSON(api).then(function (data) {
console.log(data);
for (var i = 0, len = data.length; i < len; i++) {
$('table>tbody').append(createTraining(data[i]));
}
}).catch(function (err) {
console.log(err);
});
}
function createTraining(training) {
let tag = `
${training.name}
${training.startDate}
${training.endDate}
`;
return tag;
}
11、使用SQL Server数据的最终输出。