Roman Sterlin
Roman Sterlin

Reputation: 1617

EF core table wont parse Enum and stays on 0

asp.net core MVC project using EF core, I have an object called Message that has an ENUM called Service. when trying to add the message to the database, (SQL server), it stays on 0.

any ideas?

message class:

using System;
using System.ComponentModel.DataAnnotations;

namespace AutoMatcher.Models
{
    public class Message
    {
        [Key]
        public int MessageId { get; set; }
        public string UserId { get; set; }
        public int Likes { get; set; }
        public Service Service { get; set; }
        public DateTime Time { get; set; }
        public ApplicationUser User { get; set; }

        public Message()
        {

        }
    }
}

enum :

namespace AutoMatcher.Models
{
    public enum Service
    {
        Badoo ,
        Tinder,
        Grinde
    }
}

AppDbContext:

using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;

namespace AutoMatcher.Models
{
    public class AppDbContext : IdentityDbContext<ApplicationUser>
    {
        public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
        {

        }

        protected override void OnModelCreating(ModelBuilder builder)
        {
            builder.Entity<Message>().Property(m => m.Service).HasConversion<int>();
            builder.Entity<ApplicationUser>().HasMany<Message>(m => m.Messages).WithOne(u => u.User).IsRequired();
            base.OnModelCreating(builder);
        }

        public DbSet<Message> Messages { get; set; }
    }
}

migration:

 migrationBuilder.CreateTable(
                name: "Messages",
                columns: table => new
                {
                    MessageId = table.Column<int>(nullable: false)
                        .Annotation("SqlServer:Identity", "1, 1"),
                    UserId = table.Column<string>(nullable: false),
                    Likes = table.Column<int>(nullable: false),
                    Service = table.Column<int>(nullable: false),
                    Time = table.Column<DateTime>(nullable: false)
                },

this is the form that submits the data that I want :

@model Message
@using Models
@inject UserManager<ApplicationUser> signIn

@{
    ViewData["Title"] = "Dashboard";
    Layout = "~/Views/Shared/_Layout.cshtml";

}

    <h1>Dashboard @ViewBag._userId </h1>

    <form asp-action="Schedule" asp-controller="Actions">

        <input asp-for="Likes">
        <select asp-items="Html.GetEnumSelectList<Service>()"></select>
        <input  type="datetime-local" asp-format="{0:yyyy-MM-dd}" class="form-control" />
        <button type="submit">Start</button>

    </form>

and here is the DB snapshot of how it looks like after adding:

enter image description here

Upvotes: 0

Views: 192

Answers (2)

JsonStatham
JsonStatham

Reputation: 10374

I normally handle enum based select lists like this...

Add some extra properties to a view model, dont use your DB model for the view!

public IEnumerable<SelectListItem> YourEnumSelectListProperty { get; set; }
public int SelectedItemId { get; set; }

Populate the select list in your controller like so:

var myEnumSelectList= GetGenericEnumSelectList<ProductsEnum>().OrderByDescending(x => int.Parse(x.Value)),

In your Razor view display the select list like this:

@Html.DropDownListFor(x => x.SelectedItemId, new SelectList(Model.myEnumSelectList, "Value", "Text"), new { @id = "myId", @class = "form-control" })

Some helper methods for setting your enum select list up generically

public static IEnumerable<SelectListItem> GetGenericEnumSelectList<T>()
{
    return (Enum.GetValues(typeof(T)).Cast<Enum>().Select(e => new SelectListItem() { Text = EnumExtensions.GetEnumDescription(e), Value = Convert.ToInt32(e).ToString() })).ToList();
}


public static string GetEnumDescription(Enum value)
{
            FieldInfo fi = value.GetType().GetField(value.ToString());

            DescriptionAttribute[] attributes =
                (DescriptionAttribute[])fi.GetCustomAttributes(
                    typeof(DescriptionAttribute),
                    false);

            if (attributes != null &&
                attributes.Length > 0)
                return attributes[0].Description;

                return value.ToString();
 }

Upvotes: 1

Frederic
Frederic

Reputation: 1028

missing the asp-for

<select asp-for="Service" asp-items="Html.GetEnumSelectList<Service>()"></select>

Upvotes: 1

Related Questions