尝试从int映射时无效的强制转换异常?枚举?

时间:2011-09-01 04:25:56

标签: c# asp.net-mvc-3 automapper petapoco

我有一个用户想要选择他的性别而不是必填字段的情况。在我的ui中,性别列在下拉列表中,其中有两个选项男性女性,并且具有可选标签 Gender 。但是性别是我项目中的枚举,所以如果用户没有选择任何性别,则必须在数据库中输入空值,但遗憾的是由于某些强制转换异常,我无法做到这一点可以任何机构给我一个帮助解决这个问题?

我使用petapoco作为我的orm,所以我的用户实体看起来像这样

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using Helpers;
using PetaPoco;
using StructureMap;

[TableName("User")]
[PrimaryKey("UserId")]
[ExplicitColumns]
public class User
{
    [Column("UserId")]
    public int Id { get; set; }

    [Column]
    [Required]
    public Guid Identifier { get; set; }

    [Column("UserStatusId")]
    [Required]
    public UserStatus UserStatus { get; set; }

    [Column]
    [Required]
    public int RoleId { get; set; }

    [Column]
    public int? SchoolId { get; set; }

    [Column]
    public int? LanguageId { get; set; }

    [Column("TitleId")]
    [Required]
    public Title Title { get; set; }

    [Column("GenderId")]
    [Required]
    public Gender? Gender { get; set; }

    [Column]
    [Required]
    [StringLength(35)]
    public string Username { get; set; }

    [StringLength(100)]
    public string Password { get; set; }

    [Column]
    [StringLength(100)]
    public string PasswordEncrypted { get; set; }

    [Column]
    [StringLength(10)]
    public string PasswordSalt { get; set; }

    [Column]
    [Required]
    [DataType(DataType.EmailAddress)]
    [StringLength(255)]
    public string Email { get; set; }

    [Column]
    [Required]
    [StringLength(35)]
    public string FirstName { get; set; }

    [Column]
    [Required]
    [StringLength(35)]
    public string LastName { get; set; }

    public string FullName { 
        get
        {
            return string.Concat(FirstName, " ", LastName);
        }
    }

    [Column]
    public DateTime? DateOfBirth { get; set; }

    [Column]
    public bool Subscribed { get; set; }

    [Column]
    public bool TermsAgreed { get; set; }

    [Column]
    public DateTime? TermsAgreedDate { get; set; }

    [Column]
    public DateTime CreatedDate { get; set; }

    [Column]
    public DateTime ModifiedDate { get; set; }

    [Column]
    public DateTime? LoginDate { get; set; }

    public Role Role { get; set; }

    public School School { get; set; }

    public Language Language { get; set; }
}

我的性别枚举就像这样

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;

public enum Gender
{
    /// <summary>
    /// Male
    /// </summary>
    [Description("Male")]
    Male = 1,

    /// <summary>
    /// Female
    /// </summary>
    [Description("Female")]
    Female
}

我的视图模型看起来像这样

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;

/// <summary>
/// Model for edit view model user
/// </summary>
public class UserEditViewModel
{
    /// <summary>
    /// Gets or sets the User id
    /// </summary>
    public int Id { get; set; }

    /// <summary>
    /// Gets or sets Title Id
    /// </summary>
    public int UserTitle { get; set; }

    /// <summary>
    /// Gets or sets the school Name
    /// </summary>
    public string Username { get; set; }

    /// <summary>
    /// Gets or sets the School first name
    /// </summary>
    public string FirstName { get; set; }

    /// <summary>
    /// Gets or sets the school last name
    /// </summary>
    public string LastName { get; set; }

    /// <summary>
    /// Gets or sets the school address line1
    /// </summary>
    public string Password { get; set; }

    /// <summary>
    /// Gets or sets the school address line2
    /// </summary>        
    public string ConfirmPassword { get; set; }

    /// <summary>
    /// Gets or sets the email address of the school
    /// </summary>
    public string Email { get; set; }

    /// <summary>
    /// Gets or sets the  created date
    /// </summary>
    public DateTime CreatedDate { get; set; }

    /// <summary>
    /// Gets or sets user status id
    /// </summary>
    public int UserStatus { get; set; }

    /// <summary>
    /// Gets or sets SchoolName
    /// </summary>
    public string SchoolDetails { get; set; }

    /// <summary>
    /// Gets or sets Language Id
    /// </summary>
    public int LanguageId { get; set; }

    /// <summary>
    /// Gets or sets Langauge list
    /// </summary>
    public IList<Language> Langauges { get; set; }

    /// <summary>
    /// Gets or sets RoleId
    /// </summary>        
    public int RoleId { get; set; }

    /// <summary>
    /// Gets or sets SchoolId
    /// </summary>
    public int SchoolId { get; set; }

    /// <summary>
    /// Gets or sets DateOfBirth
    /// </summary>
    public DateTime DateOfBirth { get; set; }

    /// <summary>
    /// Gets or sets Gender
    /// </summary>
    public int? Gender { get; set; }

    /// <summary>
    /// Gets UserGender list 
    /// </summary>
    public Dictionary<int, string> Genders
    {
        get
        {
            var listitems = new Dictionary<int, string>();
            foreach (Gender r in Enum.GetValues(typeof(Gender)))
            {
                listitems.Add((int)r, r.ToString());
            }

            return listitems;
        }
    }

    /// <summary>
    /// Gets Title list
    /// </summary>
    public Dictionary<int, string> Titles
    {
        get
        {
            var listitems = new Dictionary<int, string>();
            foreach (Title r in Enum.GetValues(typeof(Title)))
            {
                listitems.Add((int)r, r.ToString());
            }

            return listitems;
        }
    }

    /// <summary>
    /// Gets UserStatus list 
    /// </summary>
    public Dictionary<int, string> UserStatuses
    {
        get
        {
            var listitems = new Dictionary<int, string>();
            foreach (UserStatus r in Enum.GetValues(typeof(UserStatus)))
            {
                listitems.Add((int)r, r.ToString());
            }

            return listitems;
        }
    }

    /// <summary>
    /// Gets or sets a value indicating whether Subscribed
    /// </summary>
    public bool Subscribed { get; set; }

    /// <summary>
    /// Gets or sets a value indicating whether TermsAgreed
    /// </summary>
    public bool TermsAgreed { get; set; }
}

我正在使用automapper从User映射到UserEditviewModel,反之亦然

   Mapper.CreateMap<User, UserEditViewModel>().ForMember(
           dest => dest.Langauges, opt => opt.Ignore()).ForMember(
           dest => dest.Password, opt => opt.Ignore()).ForMember(
           dest => dest.ConfirmPassword, opt => opt.Ignore()).ForMember(
           dest => dest.SchoolDetails, opt => opt.MapFrom(src =>
               (!string.IsNullOrEmpty(src.School.SchoolDetails.Region)) ?
               string.Concat(src.School.Name, ", ",
               src.School.SchoolDetails.City, ", ",
               src.School.SchoolDetails.Region, ", ",
               src.School.SchoolDetails.PostalCode) :
               string.Concat(src.School.Name, ", ",
               src.School.SchoolDetails.City, ", ",
               src.School.SchoolDetails.PostalCode))).ForMember(
          dest => dest.Titles, opt => opt.Ignore()).ForMember(
          dest => dest.UserStatuses, opt => opt.Ignore()).ForMember(
          dest => dest.UserTitle, opt => opt.MapFrom(src => src.Title)).ForMember(
          dest => dest.Genders, opt => opt.Ignore()).ForMember(
          dest => dest.Gender, opt => opt.MapFrom(src =>
              src.Gender == null ? (int?)null : (int)src.Gender));            

 Mapper.CreateMap<UserEditViewModel, User>().ForMember(
            dest => dest.Username, opt => opt.MapFrom(src =>
                HttpUtility.HtmlDecode(src.Username))).ForMember(
            dest => dest.FirstName, opt => opt.MapFrom(src =>
                HttpUtility.HtmlDecode(src.FirstName))).ForMember(
            dest => dest.LastName, opt => opt.MapFrom(src =>
                HttpUtility.HtmlDecode(src.LastName))).ForMember(
            dest => dest.Password, opt => opt.MapFrom(src =>
                HttpUtility.HtmlDecode(src.Password))).ForMember(
            dest => dest.Email, opt => opt.MapFrom(src =>
                HttpUtility.HtmlDecode(src.Email))).ForMember(
            dest => dest.Role, opt => opt.Ignore()).ForMember(
            dest => dest.RoleId, opt => opt.Ignore()).ForMember(
            dest => dest.ModifiedDate, opt => opt.Ignore()).ForMember(
            dest => dest.School, opt => opt.Ignore()).ForMember(
            dest => dest.Language, opt => opt.Ignore()).ForMember(
            dest => dest.LoginDate, opt => opt.Ignore()).ForMember(
            dest => dest.PasswordEncrypted, opt => opt.Ignore()).ForMember(
            dest => dest.PasswordSalt, opt => opt.Ignore()).ForMember(
            dest => dest.TermsAgreedDate, opt => opt.Ignore()).ForMember(
            dest => dest.Identifier, opt => opt.Ignore()).ForMember(
            dest => dest.Title, opt => opt.MapFrom(src => src.UserTitle)).ForMember(
            dest => dest.Gender, opt => opt.MapFrom( src =>
                src.Gender == null ? (Gender?)null : (Gender)src.Gender));

但是在完成所有这些之后我会得到这样的异常   从'System.Int32'到'System.Nullable`1 的无效演员

有人可以帮忙吗?

4 个答案:

答案 0 :(得分:4)

老鼠的巢。但我敢打赌你必须改变这段代码

(int)src.Gender

(int?)src.Gender

或整行(两个地方你都这样做)

dest => dest.Gender, opt => opt.MapFrom(src =>
          src.Gender == null ? (int?)null : (int?)src.Gender));  

答案 1 :(得分:4)

public int? Gender { get; set; }

此行将gender声明为nullable int

(int)src.Gender行尝试强制转换为int

答案 2 :(得分:0)

出于调试原因,请忽略性别映射

dest => dest.Gender, opt => opt.Ignore()

但我认为问题出在SchoolId和LanguageId上,你应该正确映射它们。
所有关于故障映射的必要信息都应该是堆栈跟踪。

答案 3 :(得分:0)

您在模型中没有使用Enum的任何特殊原因?

我总是这样做,没有任何问题,Flag Enum Model Binder MVC甚至可以毫不费力地处理标记枚举!