diff --git a/ExamNETIntermediate/Form1.Designer.cs b/ExamNETIntermediate/Form1.Designer.cs index ece918a..f5eb920 100644 --- a/ExamNETIntermediate/Form1.Designer.cs +++ b/ExamNETIntermediate/Form1.Designer.cs @@ -28,12 +28,306 @@ protected override void Dispose(bool disposing) /// private void InitializeComponent() { - this.components = new System.ComponentModel.Container(); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(800, 450); - this.Text = "Form1"; + listBoxMenu = new ListBox(); + buttonRefresh = new Button(); + labelNotification = new Label(); + buttonAdd = new Button(); + tableLayoutPanel1 = new TableLayoutPanel(); + label1 = new Label(); + label2 = new Label(); + label3 = new Label(); + label4 = new Label(); + textBoxTitle = new TextBox(); + label5 = new Label(); + textBoxArtist = new TextBox(); + comboBoxGenre = new ComboBox(); + numericUpDown1 = new NumericUpDown(); + numericUpDown2 = new NumericUpDown(); + checkIsAvailable = new CheckBox(); + label6 = new Label(); + dateTimeRelease = new DateTimePicker(); + buttonUpdate = new Button(); + buttonDelete = new Button(); + textBoxSearch = new TextBox(); + label7 = new Label(); + buttonReset = new Button(); + tableLayoutPanel1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)numericUpDown1).BeginInit(); + ((System.ComponentModel.ISupportInitialize)numericUpDown2).BeginInit(); + SuspendLayout(); + // + // listBoxMenu + // + listBoxMenu.FormattingEnabled = true; + listBoxMenu.Location = new Point(28, 12); + listBoxMenu.Name = "listBoxMenu"; + listBoxMenu.Size = new Size(200, 184); + listBoxMenu.TabIndex = 0; + listBoxMenu.SelectedIndexChanged += listBoxMenu_SelectedIndexChanged; + // + // buttonRefresh + // + buttonRefresh.Location = new Point(246, 328); + buttonRefresh.Name = "buttonRefresh"; + buttonRefresh.Size = new Size(94, 38); + buttonRefresh.TabIndex = 1; + buttonRefresh.Text = "Refresh"; + buttonRefresh.UseVisualStyleBackColor = true; + buttonRefresh.Click += buttonRefresh_Click; + // + // labelNotification + // + labelNotification.AutoSize = true; + labelNotification.Location = new Point(246, 379); + labelNotification.Name = "labelNotification"; + labelNotification.Size = new Size(43, 20); + labelNotification.TabIndex = 2; + labelNotification.Text = "Idle..."; + // + // buttonAdd + // + buttonAdd.Location = new Point(247, 283); + buttonAdd.Name = "buttonAdd"; + buttonAdd.Size = new Size(94, 39); + buttonAdd.TabIndex = 3; + buttonAdd.Text = "Add"; + buttonAdd.UseVisualStyleBackColor = true; + buttonAdd.Click += buttonAdd_Click; + // + // tableLayoutPanel1 + // + tableLayoutPanel1.ColumnCount = 2; + tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F)); + tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F)); + tableLayoutPanel1.Controls.Add(label1, 0, 0); + tableLayoutPanel1.Controls.Add(label2, 0, 1); + tableLayoutPanel1.Controls.Add(label3, 0, 2); + tableLayoutPanel1.Controls.Add(label4, 0, 3); + tableLayoutPanel1.Controls.Add(textBoxTitle, 1, 0); + tableLayoutPanel1.Controls.Add(label5, 0, 5); + tableLayoutPanel1.Controls.Add(textBoxArtist, 1, 1); + tableLayoutPanel1.Controls.Add(comboBoxGenre, 1, 2); + tableLayoutPanel1.Controls.Add(numericUpDown1, 0, 4); + tableLayoutPanel1.Controls.Add(numericUpDown2, 1, 4); + tableLayoutPanel1.Controls.Add(checkIsAvailable, 1, 5); + tableLayoutPanel1.Controls.Add(label6, 0, 6); + tableLayoutPanel1.Controls.Add(dateTimeRelease, 1, 6); + tableLayoutPanel1.Location = new Point(247, 12); + tableLayoutPanel1.Name = "tableLayoutPanel1"; + tableLayoutPanel1.RowCount = 8; + tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 49.2753639F)); + tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 50.7246361F)); + tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute, 33F)); + tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute, 32F)); + tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute, 30F)); + tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute, 34F)); + tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute, 36F)); + tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute, 33F)); + tableLayoutPanel1.Size = new Size(320, 265); + tableLayoutPanel1.TabIndex = 4; + // + // label1 + // + label1.AutoSize = true; + label1.Location = new Point(3, 0); + label1.Name = "label1"; + label1.Size = new Size(38, 20); + label1.TabIndex = 0; + label1.Text = "Title"; + // + // label2 + // + label2.AutoSize = true; + label2.Location = new Point(3, 33); + label2.Name = "label2"; + label2.Size = new Size(44, 20); + label2.TabIndex = 1; + label2.Text = "Artist"; + // + // label3 + // + label3.AutoSize = true; + label3.Location = new Point(3, 66); + label3.Name = "label3"; + label3.Size = new Size(48, 20); + label3.TabIndex = 2; + label3.Text = "Genre"; + // + // label4 + // + label4.AutoSize = true; + label4.Location = new Point(3, 99); + label4.Name = "label4"; + label4.Size = new Size(90, 20); + label4.TabIndex = 3; + label4.Text = "Length (m:s)"; + // + // textBoxTitle + // + textBoxTitle.Location = new Point(163, 3); + textBoxTitle.Name = "textBoxTitle"; + textBoxTitle.Size = new Size(125, 27); + textBoxTitle.TabIndex = 7; + // + // label5 + // + label5.AutoSize = true; + label5.Location = new Point(3, 161); + label5.Name = "label5"; + label5.Size = new Size(81, 20); + label5.TabIndex = 4; + label5.Text = "IsAvailable"; + // + // textBoxArtist + // + textBoxArtist.Location = new Point(163, 36); + textBoxArtist.Name = "textBoxArtist"; + textBoxArtist.Size = new Size(125, 27); + textBoxArtist.TabIndex = 8; + // + // comboBoxGenre + // + comboBoxGenre.FormattingEnabled = true; + comboBoxGenre.Location = new Point(163, 69); + comboBoxGenre.Name = "comboBoxGenre"; + comboBoxGenre.Size = new Size(151, 28); + comboBoxGenre.TabIndex = 9; + // + // numericUpDown1 + // + numericUpDown1.Location = new Point(3, 134); + numericUpDown1.Name = "numericUpDown1"; + numericUpDown1.Size = new Size(150, 27); + numericUpDown1.TabIndex = 10; + // + // numericUpDown2 + // + numericUpDown2.Location = new Point(163, 134); + numericUpDown2.Name = "numericUpDown2"; + numericUpDown2.Size = new Size(150, 27); + numericUpDown2.TabIndex = 11; + // + // checkIsAvailable + // + checkIsAvailable.AutoSize = true; + checkIsAvailable.Location = new Point(163, 164); + checkIsAvailable.Name = "checkIsAvailable"; + checkIsAvailable.Size = new Size(18, 17); + checkIsAvailable.TabIndex = 12; + checkIsAvailable.UseVisualStyleBackColor = true; + // + // label6 + // + label6.AutoSize = true; + label6.Location = new Point(3, 195); + label6.Name = "label6"; + label6.Size = new Size(96, 20); + label6.TabIndex = 13; + label6.Text = "Release Date"; + // + // dateTimeRelease + // + dateTimeRelease.Location = new Point(163, 198); + dateTimeRelease.Name = "dateTimeRelease"; + dateTimeRelease.Size = new Size(154, 27); + dateTimeRelease.TabIndex = 14; + // + // buttonUpdate + // + buttonUpdate.Location = new Point(347, 283); + buttonUpdate.Name = "buttonUpdate"; + buttonUpdate.Size = new Size(94, 39); + buttonUpdate.TabIndex = 5; + buttonUpdate.Text = "Update"; + buttonUpdate.UseVisualStyleBackColor = true; + buttonUpdate.Click += buttonUpdate_Click; + // + // buttonDelete + // + buttonDelete.Location = new Point(447, 284); + buttonDelete.Name = "buttonDelete"; + buttonDelete.Size = new Size(94, 38); + buttonDelete.TabIndex = 6; + buttonDelete.Text = "Delete"; + buttonDelete.UseVisualStyleBackColor = true; + buttonDelete.Click += buttonDelete_Click; + // + // textBoxSearch + // + textBoxSearch.Location = new Point(28, 222); + textBoxSearch.Name = "textBoxSearch"; + textBoxSearch.Size = new Size(125, 27); + textBoxSearch.TabIndex = 7; + textBoxSearch.TextChanged += textBoxSearch_TextChanged; + // + // label7 + // + label7.AutoSize = true; + label7.Location = new Point(28, 199); + label7.Name = "label7"; + label7.Size = new Size(53, 20); + label7.TabIndex = 8; + label7.Text = "Search"; + // + // buttonReset + // + buttonReset.Location = new Point(346, 327); + buttonReset.Name = "buttonReset"; + buttonReset.Size = new Size(94, 39); + buttonReset.TabIndex = 9; + buttonReset.Text = "Reset"; + buttonReset.UseVisualStyleBackColor = true; + buttonReset.Click += buttonReset_Click; + // + // Form1 + // + AutoScaleDimensions = new SizeF(8F, 20F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(620, 422); + Controls.Add(buttonReset); + Controls.Add(label7); + Controls.Add(textBoxSearch); + Controls.Add(tableLayoutPanel1); + Controls.Add(buttonAdd); + Controls.Add(labelNotification); + Controls.Add(buttonRefresh); + Controls.Add(listBoxMenu); + Controls.Add(buttonDelete); + Controls.Add(buttonUpdate); + Name = "Form1"; + Text = "Form1"; + tableLayoutPanel1.ResumeLayout(false); + tableLayoutPanel1.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)numericUpDown1).EndInit(); + ((System.ComponentModel.ISupportInitialize)numericUpDown2).EndInit(); + ResumeLayout(false); + PerformLayout(); } #endregion + + private ListBox listBoxMenu; + private Button buttonRefresh; + private Label labelNotification; + private Button buttonAdd; + private TableLayoutPanel tableLayoutPanel1; + private Label label1; + private Label label2; + private Label label3; + private Label label4; + private Label label5; + private Button buttonUpdate; + private Button buttonDelete; + private TextBox textBoxTitle; + private TextBox textBoxArtist; + private ComboBox comboBoxGenre; + private NumericUpDown numericUpDown1; + private NumericUpDown numericUpDown2; + private CheckBox checkIsAvailable; + private Label label6; + private DateTimePicker dateTimeRelease; + private TextBox textBoxSearch; + private Label label7; + private Button buttonReset; } } diff --git a/ExamNETIntermediate/Form1.cs b/ExamNETIntermediate/Form1.cs index 3302c50..6a85a7c 100644 --- a/ExamNETIntermediate/Form1.cs +++ b/ExamNETIntermediate/Form1.cs @@ -1,10 +1,344 @@ +using ExamNETIntermediate.Models; +using Newtonsoft; +using Newtonsoft.Json; +using System.ComponentModel.DataAnnotations; +using System.Diagnostics; +using System.Text.Json; +using System.Windows.Forms; + namespace ExamNETIntermediate { public partial class Form1 : Form { + public List Menus { get; set; } = new List(); + public List Genres { get; set; } = new List(); + public HttpClient _httpClient { get; set; } = new HttpClient(); public Form1() { InitializeComponent(); + PopulateListBox(); + PopulateComboBox(); + } + + public void ClearForm() + { + textBoxTitle.Text = string.Empty; + textBoxArtist.Text = string.Empty; + comboBoxGenre.SelectedItem = null; + checkIsAvailable.Checked = false; + numericUpDown1.Value = 0M; + numericUpDown2.Value = 0M; + dateTimeRelease.Value = DateTime.Now; + listBoxMenu.SelectedIndex = -1; + textBoxSearch.Text = string.Empty; + } + + public async void PopulateComboBox() + { + var response = await _httpClient.GetAsync("https://new-dev.accelist.com:10000/api/genre"); + + var jsonContent = await response.Content.ReadAsStringAsync(); + var options = new JsonSerializerOptions + { + PropertyNameCaseInsensitive = true, + }; + + var genres = System.Text.Json.JsonSerializer.Deserialize>(jsonContent, options); + + if (genres != null) + { + Genres = genres; + } + + comboBoxGenre.Items.Clear(); + comboBoxGenre.Items.AddRange(Genres.ToArray()); + comboBoxGenre.DisplayMember = "GenreName"; + } + + public async void PopulateListBox() + { + var response = await _httpClient.GetAsync("https://new-dev.accelist.com:10000/api/song"); + response.EnsureSuccessStatusCode(); + var jsonContent = await response.Content.ReadAsStringAsync(); + var content = JsonConvert.DeserializeObject>(jsonContent); + + if (content != null) + { + Menus = content; + } + + listBoxMenu.Items.Clear(); + listBoxMenu.Items.AddRange(Menus.ToArray()); + listBoxMenu.DisplayMember = "Title"; + } + + private void buttonRefresh_Click(object sender, EventArgs e) + { + PopulateListBox(); + labelNotification.Text = "Data updated"; + } + + private async void buttonAdd_Click(object sender, EventArgs e) + { + if (listBoxMenu.SelectedItem != null) + { + MessageBox.Show("Please unselect the current item before adding a new one", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + var tittle = textBoxTitle.Text; + var artist = textBoxArtist.Text; + int minutes = (int)numericUpDown1.Value; + int seconds = (int)numericUpDown2.Value; + int totalSeconds = (minutes * 60) + seconds; + var selectedGenre = comboBoxGenre.SelectedItem as GenreModel; + DateTime selectedDate = dateTimeRelease.Value.ToUniversalTime(); + DateTime sevenDaysFromNow = DateTime.UtcNow.AddDays(7); + + if (string.IsNullOrEmpty(tittle)) + { + MessageBox.Show("Title can't be empty", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + if (string.IsNullOrEmpty(artist)) + { + MessageBox.Show("Artist can't be empty", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + if (selectedGenre == null) + { + MessageBox.Show("Genre can't be empty", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + if (minutes < 0 || minutes > 59 || seconds < 0 || seconds > 59) + { + MessageBox.Show("Invalid input for minutes or seconds", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + if (!int.TryParse(numericUpDown1.Text, out minutes) || !int.TryParse(numericUpDown2.Text, out seconds)) + { + MessageBox.Show("Invalid input for minutes or seconds", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + if (!checkIsAvailable.Checked) + { + MessageBox.Show("Song must be available to add", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + if (selectedDate > sevenDaysFromNow) + { + MessageBox.Show("Selected date can't be more than 7 days from today", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + var menuModel = new SongModelInput + { + Title = tittle, + Artist = artist, + GenreId = selectedGenre.GenreId, + Length = totalSeconds, + IsAvailable = checkIsAvailable.Checked, + ReleaseDate = dateTimeRelease.Value, + }; + + var jsonString = JsonConvert.SerializeObject(menuModel); + var content = new StringContent(jsonString); + content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); + + + var response = await _httpClient.PostAsync("https://new-dev.accelist.com:10000/api/song", content); + + response.EnsureSuccessStatusCode(); + + if (response.IsSuccessStatusCode) + { + labelNotification.Text = "Success to Insert data"; + ClearForm(); + } + else + { + labelNotification.Text = "Failed to Insert data"; + } + PopulateListBox(); + } + + private void listBoxMenu_SelectedIndexChanged(object sender, EventArgs e) + { + var selectedItem = listBoxMenu.SelectedItem as SongModel; + + if (selectedItem == null) + { + return; + } + + textBoxTitle.Text = selectedItem.Title; + textBoxArtist.Text = selectedItem.Artist; + checkIsAvailable.Checked = selectedItem.IsAvailable; + + var currentGenre = Genres.FirstOrDefault(Q => Q.GenreName == selectedItem.GenreName); + + comboBoxGenre.SelectedItem = currentGenre; + + int totalSeconds = selectedItem.Length; + int minutes = totalSeconds / 60; + int seconds = totalSeconds % 60; + numericUpDown1.Value = minutes; + numericUpDown2.Value = seconds; + + dateTimeRelease.Value = selectedItem.ReleaseDate.LocalDateTime; + } + + private async void buttonDelete_Click(object sender, EventArgs e) + { + if (listBoxMenu.SelectedItem == null) + { + MessageBox.Show("No item selected", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + var selectedMenu = listBoxMenu.SelectedItem as SongModel; + + if (selectedMenu == null) + { + labelNotification.Text = "Can't delete empty item"; + return; + } + + var response = await _httpClient.DeleteAsync($"https://new-dev.accelist.com:10000/api/song/{selectedMenu.SongId}"); + + if (response.IsSuccessStatusCode) + { + labelNotification.Text = "Success to deleting data"; + ClearForm(); + } + else + { + labelNotification.Text = "Failed to deleting data"; + } + PopulateListBox(); + } + + private async void buttonUpdate_Click(object sender, EventArgs e) + { + if (listBoxMenu.SelectedItem == null) + { + MessageBox.Show("Please select a song to update", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + var title = textBoxTitle.Text; + var artist = textBoxArtist.Text; + int minutes = (int)numericUpDown1.Value; + int seconds = (int)numericUpDown2.Value; + int totalSeconds = (minutes * 60) + seconds; + var selectedSong = listBoxMenu.SelectedItem as SongModel; + var selectedGenre = comboBoxGenre.SelectedItem as GenreModel; + DateTime selectedDate = dateTimeRelease.Value.ToUniversalTime(); + DateTime sevenDaysFromNow = DateTime.UtcNow.AddDays(7); + + if (string.IsNullOrEmpty(title)) + { + MessageBox.Show("Title can't be empty", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + if (string.IsNullOrEmpty(artist)) + { + MessageBox.Show("Artist can't be empty", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + if (selectedGenre == null) + { + MessageBox.Show("Genre can't be empty", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + if (minutes < 0 || minutes > 59 || seconds < 0 || seconds > 59) + { + MessageBox.Show("Invalid input for minutes or seconds", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + if (!int.TryParse(numericUpDown1.Text, out minutes) || !int.TryParse(numericUpDown2.Text, out seconds)) + { + MessageBox.Show("Invalid input for minutes or seconds", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + if (!checkIsAvailable.Checked) + { + MessageBox.Show("Song must be available to update", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + if (selectedDate > sevenDaysFromNow) + { + MessageBox.Show("Selected date can't be more than 7 days from today", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + var updatedModel = new SongModelInput + { + SongId = selectedSong.SongId, + Title = title, + Artist = artist, + GenreId = selectedGenre.GenreId, + Length = totalSeconds, + IsAvailable = checkIsAvailable.Checked, + ReleaseDate = dateTimeRelease.Value, + }; + + var jsonString = JsonConvert.SerializeObject(updatedModel); + var contentHttp = new StringContent(jsonString); + contentHttp.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); + Debug.WriteLine(contentHttp); + + var response = await _httpClient.PutAsync("https://new-dev.accelist.com:10000/api/song", contentHttp); + + if (response.IsSuccessStatusCode) + { + labelNotification.Text = "Success to Updating data"; + ClearForm(); + } + else + { + labelNotification.Text = "Failed to Updating data"; + } + + PopulateListBox(); + } + + private async void textBoxSearch_TextChanged(object sender, EventArgs e) + { + var searchSongName = textBoxSearch.Text; + + var response = await _httpClient.GetAsync($"https://new-dev.accelist.com:10000/api/song"); + response.EnsureSuccessStatusCode(); + var jsonContent = await response.Content.ReadAsStringAsync(); + + var allSongs = JsonConvert.DeserializeObject>(jsonContent); + + var filteredSongs = allSongs.Where(song => + song.Title.Contains(searchSongName, StringComparison.OrdinalIgnoreCase) || + song.Artist.Contains(searchSongName, StringComparison.OrdinalIgnoreCase)) + .ToList(); + + listBoxMenu.Items.Clear(); + listBoxMenu.Items.AddRange(filteredSongs.ToArray()); + listBoxMenu.DisplayMember = "Title"; + } + + + private void buttonReset_Click(object sender, EventArgs e) + { + ClearForm(); } } -} +} \ No newline at end of file diff --git a/ExamNETIntermediate/Form1.resx b/ExamNETIntermediate/Form1.resx new file mode 100644 index 0000000..af32865 --- /dev/null +++ b/ExamNETIntermediate/Form1.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/ExamNETIntermediate/GenreModel.cs b/ExamNETIntermediate/GenreModel.cs new file mode 100644 index 0000000..b011d1c --- /dev/null +++ b/ExamNETIntermediate/GenreModel.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ExamNETIntermediate.Models +{ + public class GenreModel + { + public int GenreId { get; set; } + public string GenreName { get; set; } + } +} diff --git a/ExamNETIntermediate/SongModel.cs b/ExamNETIntermediate/SongModel.cs new file mode 100644 index 0000000..bb9fcf3 --- /dev/null +++ b/ExamNETIntermediate/SongModel.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ExamNETIntermediate.Models +{ + public class SongModel + { + public int SongId { get; set; } + public string Title { get; set; } = string.Empty; + public string Artist { get; set; } = string.Empty; + public string GenreName { get; set; } + public int Length { get; set; } + public DateTimeOffset ReleaseDate { get; set; } + public bool IsAvailable { get; set; } + } + + public class SongModelInput + { + public int SongId { get; set; } + public string Title { get; set; } = string.Empty; + public string Artist { get; set; } = string.Empty; + public int GenreId { get; set; } + public int Length { get; set; } + public DateTimeOffset ReleaseDate { get; set; } = DateTimeOffset.UtcNow; + public bool IsAvailable { get; set; } + } +}