Aracılığıyla paylaş


ASP.NET Core ile yerel mobil uygulamalar için arka uç hizmetleri oluşturma

Tarafından James Montemagno

Mobil uygulamalar ASP.NET Core arka uç hizmetleriyle iletişim kurabilir. iOS simülatörleri ve Android öykünücülerinden yerel web hizmetlerini bağlama yönergeleri için bkz. iOS Simülatörleri ve Android Öykünücüleri'nden Yerel Web Hizmetlerine Bağlan.

Örnek arka uç hizmetleri kodunu görüntüleme veya indirme

Örnek Yerel Mobil Uygulama

Bu öğreticide, yerel mobil uygulamaları desteklemek için ASP.NET Core kullanarak arka uç hizmetlerinin nasıl oluşturulacağı gösterilmektedir. Android, iOS ve Windows için ayrı yerel istemciler içeren yerel istemcisi olarak Xamarin.Forms TodoRest uygulamasını kullanır. Yerel uygulamayı oluşturmak (ve gerekli ücretsiz Xamarin araçlarını yüklemek) ve Xamarin örnek çözümünü indirmek için bağlantılı öğreticiyi izleyebilirsiniz. Xamarin örneği, bu makalenin ASP.NET Core uygulamasının yerini aldığı (istemcinin hiçbir değişiklik gerektirmediği) bir ASP.NET Core Web API hizmetleri projesi içerir.

Android akıllı telefonda çalışan To Do Rest uygulaması

Özellikler

Todo REST uygulaması Yapılacaklar öğelerini listelemeyi, eklemeyi, silmeyi ve güncelleştirmeyi destekler. Her öğenin kimliği, Adı, Notları ve henüz Tamamlanıp Yapılmadığını gösteren bir özelliği vardır.

Önceki örnekte, öğelerin ana görünümü her öğenin adını listeler ve bir onay işaretiyle tamamlanıp bitmediğini gösterir.

Simgeye dokunduğunuzda + öğe ekle iletişim kutusu açılır:

Öğe ekle iletişim kutusu

Ana liste ekranındaki bir öğeye dokunulduğunda, öğenin Ad, Notlar ve Bitti ayarlarının değiştirilebileceği veya öğenin silinebileceği bir düzenleme iletişim kutusu açılır:

Öğeyi düzenle iletişim kutusu

Bilgisayarınızda çalışan bir sonraki bölümde oluşturulan ASP.NET Core uygulamasında test etmek için uygulamanın sabitini güncelleştirin RestUrl .

Android öykünücüleri yerel makinede çalışmaz ve yerel makineyle iletişim kurmak için geri döngü IP'sini (10.0.2.2) kullanır. Doğru URL'yi kullanmak üzere sistemin hangi işletimi çalıştırdığını algılamak için Xamarin.Essentials DeviceInfo kullanın.

TodoREST Projeye gidin ve dosyayı açınConstants.cs. Dosya Constants.cs aşağıdaki yapılandırmayı içerir.

using Xamarin.Essentials;
using Xamarin.Forms;

namespace TodoREST
{
    public static class Constants
    {
        // URL of REST service
        //public static string RestUrl = "https://YOURPROJECT.azurewebsites.net:8081/api/todoitems/{0}";

        // URL of REST service (Android does not use localhost)
        // Use http cleartext for local deployment. Change to https for production
        public static string RestUrl = DeviceInfo.Platform == DevicePlatform.Android ? "http://10.0.2.2:5000/api/todoitems/{0}" : "http://localhost:5000/api/todoitems/{0}";
    }
}

İsteğe bağlı olarak web hizmetini Azure gibi bir bulut hizmetine dağıtabilir ve güncelleştirebilirsiniz RestUrl.

ASP.NET Çekirdek Projesini Oluşturma

Visual Studio'da yeni bir ASP.NET Core Web Uygulaması oluşturun. Web API şablonunu seçin. Projeyi TodoAPI olarak adlandırın.

Web API proje şablonunun seçili olduğu Yeni ASP.NET Web Uygulaması iletişim kutusu

Uygulama, mobil istemcimiz için düz metin HTTP trafiği de dahil olmak üzere 5000 numaralı bağlantı noktasına yapılan tüm isteklere yanıt vermelidir. Güncelleştirme Startup.cs , UseHttpsRedirection geliştirme aşamasında çalışmaz:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        // For mobile apps, allow http traffic.
        app.UseHttpsRedirection();
    }

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

Not

Uygulamayı IIS Express'in arkasında değil doğrudan çalıştırın. IIS Express, yerel olmayan istekleri varsayılan olarak yoksayar. Komut isteminden dotnet çalıştırmasını çalıştırın veya Visual Studio araç çubuğundaki Hata Ayıklama Hedefi açılan listesinden uygulama adı profilini seçin.

Yapılacaklar öğelerini temsil etmek için bir model sınıfı ekleyin. Gerekli alanları şu öznitelikle [Required] işaretleyin:

using System.ComponentModel.DataAnnotations;

namespace TodoAPI.Models
{
    public class TodoItem
    {
        [Required]
        public string ID { get; set; }

        [Required]
        public string Name { get; set; }

        [Required]
        public string Notes { get; set; }

        public bool Done { get; set; }
    }
}

API yöntemleri, verilerle çalışmak için bir yol gerektirir. ITodoRepository Özgün Xamarin örneğinin kullandığı arabirimi kullanın:

using System.Collections.Generic;
using TodoAPI.Models;

namespace TodoAPI.Interfaces
{
    public interface ITodoRepository
    {
        bool DoesItemExist(string id);
        IEnumerable<TodoItem> All { get; }
        TodoItem Find(string id);
        void Insert(TodoItem item);
        void Update(TodoItem item);
        void Delete(string id);
    }
}

Bu örnek için, uygulama yalnızca özel bir öğe koleksiyonu kullanır:

using System.Collections.Generic;
using System.Linq;
using TodoAPI.Interfaces;
using TodoAPI.Models;

namespace TodoAPI.Services
{
    public class TodoRepository : ITodoRepository
    {
        private List<TodoItem> _todoList;

        public TodoRepository()
        {
            InitializeData();
        }

        public IEnumerable<TodoItem> All
        {
            get { return _todoList; }
        }

        public bool DoesItemExist(string id)
        {
            return _todoList.Any(item => item.ID == id);
        }

        public TodoItem Find(string id)
        {
            return _todoList.FirstOrDefault(item => item.ID == id);
        }

        public void Insert(TodoItem item)
        {
            _todoList.Add(item);
        }

        public void Update(TodoItem item)
        {
            var todoItem = this.Find(item.ID);
            var index = _todoList.IndexOf(todoItem);
            _todoList.RemoveAt(index);
            _todoList.Insert(index, item);
        }

        public void Delete(string id)
        {
            _todoList.Remove(this.Find(id));
        }

        private void InitializeData()
        {
            _todoList = new List<TodoItem>();

            var todoItem1 = new TodoItem
            {
                ID = "6bb8a868-dba1-4f1a-93b7-24ebce87e243",
                Name = "Learn app development",
                Notes = "Take Microsoft Learn Courses",
                Done = true
            };

            var todoItem2 = new TodoItem
            {
                ID = "b94afb54-a1cb-4313-8af3-b7511551b33b",
                Name = "Develop apps",
                Notes = "Use Visual Studio and Visual Studio for Mac",
                Done = false
            };

            var todoItem3 = new TodoItem
            {
                ID = "ecfa6f80-3671-4911-aabe-63cc442c1ecf",
                Name = "Publish apps",
                Notes = "All app stores",
                Done = false,
            };

            _todoList.Add(todoItem1);
            _todoList.Add(todoItem2);
            _todoList.Add(todoItem3);
        }
    }
}

uygulamasını içinde Startup.csyapılandırın:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<ITodoRepository, TodoRepository>();
    services.AddControllers();
}

Denetleyici Oluşturma

Projeye todoItemsController adlı yeni bir denetleyici ekleyin. öğesinden ControllerBasedevralmalıdır. Denetleyicinin ile api/todoitemsbaşlayan yollara yapılan istekleri işlediğini belirtmek için bir Route öznitelik ekleyin. [controller] Yoldaki belirteç, denetleyicinin adıyla değiştirilir (sonek atlanırController) ve özellikle genel yollar için yararlıdır. Yönlendirme hakkında daha fazla bilgi edinin.

Denetleyicinin çalışması gerekir ITodoRepository ; denetleyicinin oluşturucusunun üzerinden bu tür bir örnek isteyin. Çalışma zamanında bu örnek, çerçevenin bağımlılık ekleme desteği kullanılarak sağlanır.

[ApiController]
[Route("api/[controller]")]
public class TodoItemsController : ControllerBase
{
    private readonly ITodoRepository _todoRepository;

    public TodoItemsController(ITodoRepository todoRepository)
    {
        _todoRepository = todoRepository;
    }

Bu API, veri kaynağında CRUD (Oluşturma, Okuma, Güncelleştirme, Silme) işlemlerini gerçekleştirmek için dört farklı HTTP fiilini destekler. Bunların en basiti, http GET isteğine karşılık gelen Okuma işlemidir.

Curl kullanarak API'yi test edin

API yöntemini çeşitli araçları kullanarak test edebilirsiniz. Bu öğretici için aşağıdaki açık kaynak komut satırı araçları kullanılır:

  • curl: HTTP ve HTTPS gibi çeşitli protokolleri kullanarak verileri aktarır. curl, bu öğreticide, , POSTPUTve DELETEHTTP yöntemlerini GETkullanarak API'yi çağırmak için kullanılır.
  • jq: JSBU öğreticide, API yanıtından kolayca okunabilmesi için ON verilerini biçimlendirmek JSiçin kullanılan ON işlemcisi.

Curl ve jq yükleme

curl, macOS'a önceden yüklenmiştir ve doğrudan macOS Terminal uygulamasında kullanılır. Curl yükleme hakkında daha fazla bilgi için resmi curl web sitesine bakın.

jq, terminalden brew'dan Homeyüklenebilir:

HomeBrew'ı yükleme ( henüz yüklü değilse) aşağıdaki komutla:

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

Yükleyici tarafından sunulan yönergeleri izleyin.

Aşağıdaki komutla brew kullanarak Homejq yükleyin:

brew install jq

Brew ve jq kurulumu hakkında Homedaha fazla bilgi için bkzHome. brew and jq.

Okuma Öğeleri

Öğe listesi isteğinde bulunmak, yöntemine List yönelik get isteğiyle gerçekleştirilir. [HttpGet] yöntemindeki List özniteliği, bu eylemin yalnızca GET isteklerini işlemesi gerektiğini gösterir. Bu eylemin yolu, denetleyicide belirtilen yoldur. Yolun bir parçası olarak eylem adını kullanmanız gerekmez. Her eylemin benzersiz ve kesin bir yolu olduğundan emin olmanız yeterlidir. Yönlendirme öznitelikleri, belirli yolları oluşturmak için hem denetleyici hem de yöntem düzeylerinde uygulanabilir.

[HttpGet]
public IActionResult List()
{
    return Ok(_todoRepository.All);
}

Terminalde aşağıdaki curl komutunu çağırın:

curl -v -X GET 'http://localhost:5000/api/todoitems/' | jq

Önceki curl komutu aşağıdaki bileşenleri içerir:

  • -v: AYRıNTıLı modu etkinleştirerek HTTP yanıtı hakkında ayrıntılı bilgi sağlar ve API testi ve sorun giderme için kullanışlıdır.
  • -X GET: İstek için HTTP GET yönteminin kullanımını belirtir. Curl genellikle hedeflenen HTTP yöntemini çıkarsasa da, bu seçenek bunu açık hale getirir.
  • 'http://localhost:5000/api/todoitems/': Bu, isteğin hedef URL'sidir. Bu örnekte bir API uç noktasıdır REST .
  • | jq: Bu segment doğrudan curl ile ilgili değildir. Kanal | , sol tarafındaki komuttan çıkışı alan ve bunu sağındaki komuta "kanal" eden bir kabuk işlecidir. jq bir komut satırı JSAÇI işlemcidir. Gerekli olmasa da döndürülen jq ON verilerinin JSokunmasını kolaylaştırır.

yöntemi, List 200 Ok yanıt kodu ve tüm Todo öğelerini on olarak JSseri hale getirerek döndürür:

[
  {
    "id": "6bb8a868-dba1-4f1a-93b7-24ebce87e243",
    "name": "Learn app development",
    "notes": "Take Microsoft Learn Courses",
    "done": true
  },
  {
    "id": "b94afb54-a1cb-4313-8af3-b7511551b33b",
    "name": "Develop apps",
    "notes": "Use Visual Studio and Visual Studio for Mac",
    "done": false
  },
  {
    "id": "ecfa6f80-3671-4911-aabe-63cc442c1ecf",
    "name": "Publish apps",
    "notes": "All app stores",
    "done": false
  }
]

Öğe Oluşturma

Kural gereği, yeni veri öğeleri oluşturma IŞLEMI HTTP POST fiiline eşlenir. yöntemine Create[HttpPost] bir öznitelik uygulanmış ve bir TodoItem örneği kabul eder. item Bağımsız değişken POST gövdesinde geçirildiğinden, bu parametre özniteliğini [FromBody] belirtir.

yönteminin içinde öğe, veri deposunda geçerlilik ve önceden var olup olmadığı denetlenir ve herhangi bir sorun yaşanmazsa depo kullanılarak eklenir. DenetimModelState.IsValid, model doğrulama gerçekleştirir ve kullanıcı girişini kabul eden her API yönteminde yapılmalıdır.

[HttpPost]
public IActionResult Create([FromBody]TodoItem item)
{
    try
    {
        if (item == null || !ModelState.IsValid)
        {
            return BadRequest(ErrorCode.TodoItemNameAndNotesRequired.ToString());
        }
        bool itemExists = _todoRepository.DoesItemExist(item.ID);
        if (itemExists)
        {
            return StatusCode(StatusCodes.Status409Conflict, ErrorCode.TodoItemIDInUse.ToString());
        }
        _todoRepository.Insert(item);
    }
    catch (Exception)
    {
        return BadRequest(ErrorCode.CouldNotCreateItem.ToString());
    }
    return Ok(item);
}

Örnek, mobil istemciye geçirilen bir enum hata kodları içerir:

public enum ErrorCode
{
    TodoItemNameAndNotesRequired,
    TodoItemIDInUse,
    RecordNotFound,
    CouldNotCreateItem,
    CouldNotUpdateItem,
    CouldNotDeleteItem
}

Terminalde, fiilini kullanarak aşağıdaki curl komutunu çağırarak ve isteğin POST Gövdesinde JSyeni nesneyi ON biçiminde sağlayarak yeni öğeler eklemeyi test edin.

curl -v -X POST 'http://localhost:5000/api/todoitems/' \
--header 'Content-Type: application/json' \
--data '{
  "id": "6bb8b868-dba1-4f1a-93b7-24ebce87e243",
  "name": "A Test Item",
  "notes": "asdf",
  "done": false
}' | jq

Önceki curl komutu aşağıdaki seçenekleri içerir:

  • --header 'Content-Type: application/json': üst bilgisini olarak application/jsonayarlar Content-Type ve istek gövdesinin ON verileri içerdiğini JSbelirtir.
  • --data '{...}': belirtilen verileri istek gövdesine gönderir.

yöntemi yanıtta yeni oluşturulan öğeyi döndürür.

Öğeleri Güncelleştirme

Kayıtları değiştirme işlemi HTTP PUT istekleri kullanılarak yapılır. Bu değişiklik dışında, Edit yöntemi neredeyse ile Createaynıdır. Kayıt bulunamazsa, Edit eylem bir NotFound (404) yanıtı döndürür.

[HttpPut]
public IActionResult Edit([FromBody] TodoItem item)
{
    try
    {
        if (item == null || !ModelState.IsValid)
        {
            return BadRequest(ErrorCode.TodoItemNameAndNotesRequired.ToString());
        }
        var existingItem = _todoRepository.Find(item.ID);
        if (existingItem == null)
        {
            return NotFound(ErrorCode.RecordNotFound.ToString());
        }
        _todoRepository.Update(item);
    }
    catch (Exception)
    {
        return BadRequest(ErrorCode.CouldNotUpdateItem.ToString());
    }
    return NoContent();
}

Curl ile test etmek için fiili olarak PUTdeğiştirin. İsteğin Gövdesinde güncelleştirilmiş nesne verilerini belirtin.

curl -v -X PUT 'http://localhost:5000/api/todoitems/' \
--header 'Content-Type: application/json' \
--data '{
  "id": "6bb8b868-dba1-4f1a-93b7-24ebce87e243",
  "name": "A Test Item",
  "notes": "asdf",
  "done": true
}' | jq

Bu yöntem, önceden var olan API ile tutarlılık için başarılı olduğunda bir NoContent (204) yanıt döndürür.

Öğeleri Silme

Kayıtları silme işlemi hizmete istek gönderilerek DELETE ve silinecek öğenin kimliği geçirilerek gerçekleştirilir. Güncelleştirmelerde olduğu gibi, var olmayan öğelere yönelik istekler yanıt alır NotFound . Aksi takdirde, başarılı bir istek ( NoContent 204) yanıtı döndürür.

[HttpDelete("{id}")]
public IActionResult Delete(string id)
{
    try
    {
        var item = _todoRepository.Find(id);
        if (item == null)
        {
            return NotFound(ErrorCode.RecordNotFound.ToString());
        }
        _todoRepository.Delete(id);
    }
    catch (Exception)
    {
        return BadRequest(ErrorCode.CouldNotDeleteItem.ToString());
    }
    return NoContent();
}

HTTP fiilini DELETE olarak değiştirip URL'nin sonunda silinecek veri nesnesinin kimliğini ekleyerek curl ile test edin. İsteğin Gövdesinde hiçbir şey gerekli değildir.

curl -v -X DELETE 'http://localhost:5000/api/todoitems/6bb8b868-dba1-4f1a-93b7-24ebce87e243'

Fazla deftere nakledilmesini engelle

Şu anda örnek uygulama tüm TodoItem nesneyi kullanıma sunar. Üretim uygulamaları genellikle modelin bir alt kümesi kullanılarak giriş ve döndürülen verileri sınırlar. Bunun arkasında birden çok neden vardır ve güvenlik önemli bir nedendir. Modelin alt kümesi genellikle Veri Aktarım Nesnesi (DTO), giriş modeli veya görünüm modeli olarak adlandırılır. DTO bu makalede kullanılmıştır.

DTO, şu durumlarda kullanılabilir:

  • Fazla göndermeyi engelle.
  • İstemcilerin görüntülememesi gereken özellikleri gizleyin.
  • Yük boyutunu küçültmek için bazı özellikleri atlar.
  • İç içe nesneler içeren nesne grafiklerini düzleştirme. Düzleştirilmiş nesne grafikleri istemciler için daha kullanışlı olabilir.

DTO yaklaşımını göstermek için bkz . Fazla göndermeyi engelleme

Yaygın Web API'leri Kuralları

Uygulamanız için arka uç hizmetlerini geliştirirken, çapraz kesme sorunlarını ele almak için tutarlı bir dizi kural veya ilke bulmak isteyeceksiniz. Örneğin, daha önce gösterilen hizmette, bulunamamış belirli kayıtlar için istekler yanıt yerine bir NotFoundBadRequest yanıt aldı. Benzer şekilde, bu hizmete yapılan ve modele bağlı türleri geçen komutlar her zaman denetlenir ModelState.IsValid ve geçersiz model türleri için bir BadRequest döndürür.

API'leriniz için ortak bir ilke belirledikten sonra, bunu genellikle bir filtrede kapsülleyebilirsiniz. ASP.NET Core MVC uygulamalarında yaygın API ilkelerini kapsülleme hakkında daha fazla bilgi edinin.

Ek kaynaklar