iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 27
0
Software Development

三十天利用Angular與.net Core開發實戰一波系列 第 27

Day 27 AngularTri實作-後端Web API

  • 分享至 

  • xImage
  •  

依照之前的後端API規畫,我們來在來實作CRUD一次吧!

  • 我們先用vs2017建一個WEB API專案(TriWebAPI)

  • 使用 NuGet 取得 mongocsharpdriver

  • 新建一個Models資料夾,並新增一個Triathlon.cs的類別,這邊BsonElement是跟MongoDB的Collection欄位一致。
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using System;
using System.Collections.Generic;

namespace TriWebAPI.Models
{
    public class Triathlon
    {
        public ObjectId Id { get; set; }
        [BsonElement("date")]
        public string date { get; set; }
        [BsonElement("year")]
        public string year { get; set; }
        [BsonElement("month")]
        public string month { get; set; }
        [BsonElement("day")]
        public string day { get; set; }
        [BsonElement("place")]
        public string place { get; set; }
        [BsonElement("name")]
        public string name { get; set; }
        [BsonElement("tri_event")]
        public List<Event> tri_event { get; set; }
        [BsonElement("remark")]
        public string remark { get; set; }
        [BsonElement("organizer")]
        public string organizer { get; set; }
        [BsonElement("location")]
        public string location { get; set; }
        [BsonElement("locationmap")]
        public string locationmap { get; set; }
        [BsonElement("applydate")]
        public string applydate { get; set; }
        [BsonElement("onlineapplyurl")]
        public string onlineapplyurl { get; set; }
        [BsonElement("status")]
        public string status { get; set; }
        [BsonDateTimeOptions(Kind = DateTimeKind.Local)]
        public DateTime in_date { get; set; }
        [BsonDateTimeOptions(Kind = DateTimeKind.Local)]
        public DateTime up_date { get; set; }

    }
}

  • 因為我們在tri_event這是一個array,需要建立一個Event.cs
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;

namespace TriWebAPI.Models
{
    public class Event
    {
        [BsonElement("eventgroup")]
        public string eventgroup { get; set; }
        [BsonElement("name")]
        public string name { get; set; }
        [BsonElement("startDate")]
        public string startDate { get; set; }
        [BsonElement("startTime")]
        public string startTime { get; set; }
        [BsonElement("cost")]
        public string cost { get; set; }
        [BsonElement("timelimit")]
        public string timelimit { get; set; }
    }
}

  • 新增一個Response.cs的類別,用途是處理api回傳時的統一格式。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace TriWebAPI.Models
{
    public class Response<T>
    {
        public bool IsSuccess { get; set; }
        public T Data { get; set; }
        public string ErrorMessage { get; set; }
    }
}

  • 在Models中新增一個DataAccess.cs的類別,用途是連線MongoDB與增刪修查。
using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.Builders;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Authentication;
using System.Threading.Tasks;

namespace TriWebAPI.Models
{
    public class DataAccess
    {
        MongoClient _client;
        MongoServer _server;
        MongoDatabase _db;

      string connectionString = @"mongodb://db";// Azure Quick Start

      //string defaultDBstring = "mongodb://localhost:27017";

        public DataAccess()
        {

            MongoClientSettings settings = MongoClientSettings.FromUrl(new MongoUrl(connectionString));
            settings.SslSettings = new SslSettings() { EnabledSslProtocols = SslProtocols.Tls12 };
            _client = new MongoClient(settings);
            _servere = _clientAzure.GetServer();
            _db = _serverAzure.GetDatabase("TriDB");
        }

        public IEnumerable<Triathlon> GetTris()
        {
            return _db.GetCollection<Triathlon>("Triathlon").FindAll();
        }

        public IEnumerable<Triathlon> GetTri(string id, string dateS, string dateE, string place)
        {
            int i = 0;
            var qc = new IMongoQuery[4];
            if (id != "") qc[i++] = Query<Triathlon>.EQ(p => p.Id, new ObjectId(id));
            if (dateS != "") qc[i++] = Query<Triathlon>.GTE(p => p.date, dateS);
            if (dateE != "") qc[i++] = Query<Triathlon>.LTE(p => p.date, dateE);
            if (place != "") qc[i++] = Query<Triathlon>.Matches(p => p.place, place);
            qc = qc.Where(c => c != null).ToArray();
            if (qc.Length > 0)
                return _db.GetCollection<Triathlon>("Triathlon").Find(Query.And(qc));
            else
                return _db.GetCollection<Triathlon>("Triathlon").FindAll();
        }

        public Triathlon CreateTri(Triathlon tri)
        {
            tri.in_date = DateTime.Now;
            tri.up_date = DateTime.Now;
            _db.GetCollection<Triathlon>("Triathlon").Save(tri);
            return tri;
        }

        public bool UpdateTri(ObjectId id, Triathlon tri)
        {
            tri.Id = id;
            tri.up_date = DateTime.Now; 
            var res = Query<Triathlon>.EQ(u => u.Id, id);
            var operation = Update<Triathlon>.Replace(tri);
            var result = _db.GetCollection<Triathlon>("Triathlon").Update(res, operation);
            return !result.HasLastErrorMessage;
        }
        public bool RemoveTri(ObjectId id)
        {
            var res = Query<Triathlon>.EQ(e => e.Id, id);
            var operation = _db.GetCollection<Triathlon>("Triathlon").Remove(res);
            return !operation.HasLastErrorMessage;
        }
    }
}
  • 新增IRepository
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using TriWebAPI.Models;

namespace TriWebAPI.Handler
{
    public interface IRepository
    {
        Response<Triathlon> AddTri(Triathlon u);
        Response<IEnumerable<Triathlon>> GetAllTri();
        Response<bool> DeleteTri(string Id);
        Response<IEnumerable<Triathlon>> GetTriById(string Id,string dateS, string dateE, string place);
        Response<bool> UpdateTri(string Id, Triathlon tri);
    }
}



  • 新增Repository,記得繼承IRepository
using MongoDB.Bson;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using TriWebAPI.Models;

namespace TriWebAPI.Handler
{
    public class Repository : IRepository
    {
        private readonly DataAccess _db;
        public Repository(DataAccess db)
        {
            _db = db;
        }

        public Response<Triathlon> AddTri(Triathlon tri)
        {
            var result = new Response<Triathlon>();
            result.IsSuccess = true;
            try
            {
                result.Data = _db.CreateTri(tri);
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.ErrorMessage = ex.Message;
            }
            return result;
        }

        public Response<bool> DeleteTri(string Id)
        {
            var result = new Response<bool>();
            result.IsSuccess = true;
            try
            {
                var objId = new ObjectId(Id);
                result.Data = _db.RemoveTri(objId);
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.ErrorMessage = ex.Message;
            }

            return result;
        }

        public Response<IEnumerable<Triathlon>> GetAllTri()
        {
            var result = new Response<IEnumerable<Triathlon>>();
            result.IsSuccess = true;
            try
            {
                result.Data = _db.GetTris();
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.ErrorMessage = ex.Message;
            }

            return result;
        }

        public Response<IEnumerable<Triathlon>> GetTriById(string Id, string dateS, string dateE, string place)
        {
            var result = new Response<IEnumerable<Triathlon>>();
            result.IsSuccess = true;
            try
            {
                result.Data = _db.GetTri(Id, dateS, dateE, place);
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.ErrorMessage = ex.Message;
            }
            return result;
        }

        public Response<bool> UpdateTri(string Id, Triathlon tri)
        {
            var result = new Response<bool>();
            result.IsSuccess = true;
            try
            {
                var objId = new ObjectId(Id);
                result.Data = _db.UpdateTri(objId, tri);
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.ErrorMessage = ex.Message;
            }
            return result;
        }
    }
}



  • 新建一個Controllers資料夾,新增TriAPIController.cs的類別
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using TriWebAPI.Handler;
using TriWebAPI.Models;

// For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860

namespace TriWebAPI.Controllers
{
    [Route("api/Triathlon/[action]/")]
    public class TriAPIController : Controller
    {
        private readonly IRepository _repository;

        public TriAPIController(IRepository repository)
        {
            _repository = repository;
        }

        // GET: api/<controller>
        [HttpGet]
        public Response<IEnumerable<Triathlon>> GetAllTri()
        {
            return _repository.GetAllTri();
        }

        // GET api/<controller>/5
        [HttpGet]
        public Response<IEnumerable<Triathlon>> GetTriById(string Id="",string dateS="",string dateE="",string place="")
        {
            var response = _repository.GetTriById(Id,dateS,dateE,place);
            return response;
        }

        // POST api/<controller>
        [HttpPost]
        public Response<Triathlon> AddTri([FromBody]Triathlon tri)
        {
            var response = _repository.AddTri(tri);
            return response;
        }

        [HttpPut]
        public Response<bool> UpdateTri(string Id, [FromBody] Triathlon tri)
        {
            var response = _repository.UpdateTri(Id, tri);
            return response;
        }

        // DELETE api/<controller>/5
        [HttpDelete]
        public Response<bool> DeleteTri(string Id)
        {
            var response = _repository.DeleteTri(Id);
            return response;
        }
    }
}
  • 打開Startup.cs找到ConfigureServices方法,註冊DataAccess與IRepository、Repository。
...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using TriWebAPI.Handler;
using TriWebAPI.Models;

namespace TriWebAPI
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            // Add framework services.
            services.AddSingleton<IRepository, Repository>();
            services.AddTransient<DataAccess>();
            services.AddMvc();
            services.AddCors(options =>
            {
                // CorsPolicy 是自訂的 Policy 名稱
                options.AddPolicy("CorsPolicy", policy =>
                {
                    policy.AllowAnyOrigin().SetPreflightMaxAge(new TimeSpan(86400))
                             .AllowAnyHeader()
                             .AllowAnyMethod()
                             .AllowCredentials();
                });
            });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseCors("CorsPolicy");
            }
            else
            {
                app.UseHsts();
                app.UseCors("CorsPolicy");
            }

            app.UseHttpsRedirection();
            app.UseMvc();
        }
    }
}

  • 開始測試

我們這邊使用Postman測試,測試中有遇到一個問題,postman呼叫API無回應但網頁卻有,Postman下方有提示如何修正。

Self-signed SSL certificates are being blocked:
Fix this by turning off 'SSL certificate verification' in Settings > General


測試結果

找全部
https://localhost:44353/api/Triathlon/GetAllTri

用id找
https://localhost:44353/api/Triathlon/GetTriById?Id=5be4e46cd31f6613c431f55b

新增
https://localhost:44353/api/Triathlon/AddTri

修改user資料
https://localhost:44353/api/Triathlon/UpdateTri?Id=5be4e46cd31f6613c431f55b

刪除user
https://localhost:44353/api/Triathlon/DeleteTri?id=5be4e46cd31f6613c431f55b


上一篇
Day 26 AngularTri 實作-Fake Data
下一篇
Day 28 AngularTri 實作 - 前端頁面(讀取/編輯/修改/確認/刪除/細節)
系列文
三十天利用Angular與.net Core開發實戰一波32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言