如何使用.NET Core,SQL和HTML和JavaScript构建CRUD应用程序

目录

介绍

使用代码


介绍

在本文中,我将说明一个端到端解决方案(服务端>后端>前端),以创建新的.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 APIAPI 。您可以取消选中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<tempdbContext> options)
            : base(options)
        {
        }

        public virtual DbSet<TblTraining> 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<TblTraining>(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<tempdbContext>(o => o.UseSqlServer(connection));

            services.AddScoped<ITrainingServices, TrainingServices>();
        }

6、接下来,您可以使用内部服务/帮助器概念在服务请求数据时读取/验证数据。我已经创建了使用数据库上下文管理数据的ITrainingServices接口和相应的服务类TrainingServices。使用这种方法,您还可以创建一个独立于db上下文的本地服务(LocalTrainingServices),并将值保留在内存中进行测试。如果在这种情况下尚未建立实体框架,则可以在startup.cs中将本地服务作为Scope。用以下代码替换startup.cs中的AddScoped<>行:

services.AddScoped<ITrainingServices, LocalTrainingServices>();

 

public interface ITrainingServices
    {
        Task<IList<TrainingViewModel>> 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<IList<TrainingViewModel>> 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<TrainingViewModel> 
                  trainingViewModels = new List<TrainingViewModel>()
        {
            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<IList<TrainingViewModel>> GetTrainingData()
        {
            return new Task<IList<TrainingViewModel>>(() => 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<IEnumerable<TrainingViewModel>> 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(即HttpGetHttpPost等)完成了Web服务,您可以在iis中部署此服务,也可以从vs本地部署此服务,选择服务名称,然后点击运行绿色按钮。您最终必须获得该服务的URL,例如https// localhostyourportno [default5001] / api / Training。这里,项目是培训;即访问服务的控制器名称。

9、服务正在运行,让我们尝试使用此服务。在编写UI部分之前,让我们检查该服务是否确实有效,您可以使用Chrome扩展程序ARC或类似postman的工具进行验证。只需粘贴URL并检查响应即可。

10、让我们编写一个小型前端应用程序,以HTML格式并使用JavaScript加载此数据。这是代码:

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title>Training</title>
    <!--Styles from Bootstrap-->
    <link rel="stylesheet" 

    href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" 

    integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" 

    crossorigin="anonymous">
</head>
<body>
    <!--<header>Traning Details</header>-->
    <div id="header"></div>
    <main class="container">
        <table class="table">
        <thead>
            <tr>
                <th>
                    Training Name
                </th>
                <th>
                    Start Date
                </th>
                <th>
                    End Date
                </th>
                <th></th>
            </tr>
        </thead>
        <tbody class="tbody">
        </tbody>
    </table>

    <div>
       <!--Get : Query string /url
        Post : Hidden fields-->
        <form method="get" id="form">
            <label>Training Name:</label>
            <input id="name" type="text" width="20"  

            placeholder="enter Traning name" required/> <br />
    
            <label>Start Date     :</label>
            <input id="startdate" type="datetime" 

            width="20"  data-provide="datepicker" /> <br />
    
            <label>End Date       :</label>
            <input id="enddate" type="datetime" 

            width="20" data-provide="datepicker"/><br />

            <input type="submit" value="Submit"/>
            
        </form>
    </div>

    <div id="footer"></div>
    <!--<footer>End of Tranings Details</footer>-->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" 

    integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" 

    crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" 

    integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" 

    crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" 

    integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" 

    crossorigin="anonymous"></script>

    <!--JQuery-->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js">
    </script>

    <script type="text/javascript" charset="utf8" 

    src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.3.3/jstree.min.js"></script>
    <script src="main.js"></script>

    <script>
        $('form').submit(function (e) {
                e.preventDefault();
                const data = {
                    Name: $('#name').val(),
                    Startdate: $('#startdate').val(),
                    EndDate: $('#enddate').val()
                }

                let tag = '<tr><td>' + data.Name + '</td>';
                tag += '<td>' + data.Startdate + '</td>';
                tag += '<td>' + data.Enddate + '</td></tr>';
                $('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 });
            });
    </script>

    </main>
</body>
</html>

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 = '<tr><td>' + data.Name + '</td>';
    tag += '<td>' + data.Startdate + '</td>';
    tag += '<td>' + data.Enddate + '</td></tr>';
    $('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 = `
        <tr>
            <td>
                ${training.name}
            </td>
            <td>
                ${training.startDate}
            </td>
            <td>
               ${training.endDate}
            </td>
        </tr>
    `;

    return tag;
}

11、使用SQL Server数据的最终输出。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值