API در MVC Core

9/16/2017 MVC
2324

به تازگی سفارشهایی داریم که مشتری هم وب سایت میخواد و هم در سفارش خود اظهار میکنه که در اینده برای پروژه خود اپلیکیشن های گوشی های هوشمند هم داشته باشد برای این بهترین  کار از نظر خودم پیاده سازی اولیه پروژه به صورت api  است و این api را در همین راستا با mvc core  پیاده کردم

اول : نصب

Microsoft.EntityFrameworkCore.Tools
Microsoft.EntityFrameworkCore.SqlServer.Design 

 

دوم اضافه کردن

Updated:نیاز داشتم تا اعتبار سنجی نیز انجام شود برای همین applicationUser  نیز اضافه شد./ 

 

public class ApplicationUser : IdentityUser
    {
    }

    public class DatesContext : IdentityDbContext<ApplicationUser>
    {
        public DatesContext(DbContextOptions<DatesContext> options) : base(options)
        {


        }
    }

 سوم اضافه کردن :

        public void ConfigureServices(IServiceCollection services)
        {
            
            services.AddMvc();

            //add by me for use cach 
            services.AddMemoryCache();
            var connection = @"Server=***.***.***.***;Database=aspnet***;Integrated Security=false;Initial Catalog=aspnet***;User ID=***;Password=******;";
            services.AddDbContext<DatesContext>(options => options.UseSqlServer(connection, b => b.MigrationsAssembly("Dates.Api")));
            services.AddSingleton<ICustomerRepository, CustomerRepository>();
            services.AddScoped<ICustomerRepository, CustomerRepository>();

            services.AddSingleton<ICustomerTypeRepository, CustomerTypeRepository>();
            services.AddScoped<ICustomerTypeRepository, CustomerTypeRepository>();
        }

اضافه کردن ICostomerTypeRepository to "Contracts" folder

اضافه کردن CostomerTypeRepository به پوشه Repositories که ICustomerTypeRepository را پیاده سازی میکند 

هر دو فایل ذکر شده 

public interface ICustomerTypeRepository
    {
        void Add(CustomerType item);
        IEnumerable<CustomerType> GetAll();
        CustomerType Find(int key);
        CustomerType Delete(int key);
        void Update(CustomerType item);
    }

و

 public class CustomerTypeRepository:ICustomerTypeRepository
    {
        private DatesContext _db;
        public IMemoryCache _cache;
        public CustomerTypeRepository(DatesContext context,IMemoryCache memoryCach)
        {
            _db = context;
            _cache = memoryCach;
        }
        public void Add(CustomerType item)
        {
            _db.CustomerType.Add(item);
            _cache.Set(item.Id, item, new MemoryCacheEntryOptions
            {
                AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(60)
            });
            _db.SaveChanges();
        }

        public IEnumerable<CustomerType> GetAll() => _db.CustomerType;
        

        public CustomerType Find(int key)
        {
            CustomerType cacheCustomerType = null;
            if (_cache.TryGetValue(key, out cacheCustomerType))
            {
                return cacheCustomerType;
            }
            else
            {
                return _db.CustomerType.SingleOrDefault(a => a.Id == key);
            }
        }

        public CustomerType Remove(int key)
        {
            var item = _db.CustomerType.SingleOrDefault(a => a.Id == key);
            _db.CustomerType.Remove(item);
            _db.SaveChanges();
            return item;
        }

        public void Update(CustomerType item)
        {
            _db.CustomerType.Update(item);
            _db.SaveChanges();
        }
    }

 برای اضافه کردن Controller  بهترین  کار این است که روی پوشه controller  راست کلیک کنیم و از قسمت scaffold  گزینه Api Controller with actions, using Entity frame work  را انتخاب کنید ، 

 

[Produces("application/json")]
    [Route("api/CustomerTypes")]
    public class CustomerTypesController : Controller
    {
        private readonly DatesContext _context;

        public CustomerTypesController(DatesContext context)
        {
            _context = context;
        }

        // GET: api/CustomerTypes
        [HttpGet]
        public IEnumerable<CustomerType> GetCustomerType()
        {
            return _context.CustomerType;
        }
       // GET: api/CustomerTypes/5
        [HttpGet("{id}")]
        public async Task<IActionResult> GetCustomerType([FromRoute] int id)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            var customerType = await _context.CustomerType.SingleOrDefaultAsync(m => m.Id == id);

            if (customerType == null)
            {
                return NotFound();
            }

            return Ok(customerType);
        }
}

 به صورت پیشفرض scaffold به صورت بالا  عمل خواهد کرد اما برای اینکه بتوانیم از injection  استفاده کنیم بهتر است تغییراتی به این صورت اعمال کنیم 

 

[Produces("application/json")]
    [Route("api/CustomerTypes")]
    public class CustomerTypesController : Controller
    {
        //private readonly DatesContext _context;
        private ICustomerTypeRepository CustomertyperItem { get; set; }

        public CustomerTypesController(ICustomerTypeRepository customerTypeRepository)
        {
            CustomertyperItem = customerTypeRepository;
        }

        // GET: api/CustomerTypes
        [HttpGet]
        public IEnumerable<CustomerType> GetCustomerType() => CustomertyperItem.GetAll();
        // GET: api/CustomerTypes/5
        [HttpGet("{id}", Name = "GetCustomerType") ]
        public async Task<IActionResult> GetCustomerType([FromRoute] int id)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            var item = CustomertyperItem.Find(id);
            return new ObjectResult(item);
        }
 }

و در قسمت GetCustomerType ایتدا در  attribute خاصیت نام را اضافه میکنیم.

 از آنجایی که نیاز داشتم تا اطلاعات با بانک اطلاعاتی تعامل برقرار کنه تغییرات خاصی را اعمال شد:

1- add-migration init 

2- update-database 

 در جداول من بین دو جدول Customer و province  ارتباط برقرار بود به همین دلیل خطای عدم امکان حذف میداد در نتیجه این قطعه کد ر ا اضافه کردم 

   protected override void OnModelCreating(ModelBuilder builder)
        {
            foreach (var relationship in builder.Model.GetEntityTypes().SelectMany(e => e.GetForeignKeys()))
            {
                relationship.DeleteBehavior = DeleteBehavior.Restrict;
            }
            base.OnModelCreating(builder);
           

        }

 فقط یاد اور شوم که این تغییر را قبل از Add-migration  انجام دهید و یا اگر add-migration  را قبلا انجام داده اید آن را پاک کنید و بعد از پاک کردن کد دوباره آن را ایجاد کنید.

قطعه کد قسمت service در start.cs  به روز رسانی شد و علاوه بر Connection string  برای remote server این قطعه کد نیز اصلاح شد و دلیل اصلاح ان این بود که با توجه به اینکه ما از چند پروژه به عنوان یک پروژه استفاده میکنیم نیاز است تا نوع پروژه را مشخص کنیم 

 

            services.AddDbContext<DatesContext>(options => options.UseSqlServer(connection, b => b.MigrationsAssembly("Dates.Api")));

آپدیت:

اضافه کردن Install-Package Microsoft.AspNet.Mvc به پروژه مودال