简体   繁体   中英

Entity Framework | Error: InvalidCastException: The field of type System.Int32 must be a string, array or ICollection type

Issue

I'm receiving the following error when I submit (or post) a request to my Home Controller, for a method called NewsletterSignup. The error is prompted after my newsletter form is submitted and prior to when this method is called and the object, capturing form data, is created, creating a situation where it's difficult to troubleshoot, and identify where this exact issue is propagating.

Error

An unhandled exception occurred while processing the request.

InvalidCastException : The field of type System.Int32 must be a string, array or ICollection type. ... System.ComponentModel.DataAnnotations.MaxLengthAttribute.IsValid(object value)

... System.ComponentModel.DataAnnotations.ValidationAttribute.IsValid(object value, ValidationContext validationContext)

... System.ComponentModel.DataAnnotations.ValidationAttribute.GetValidationResult(object value, ValidationContext validationContext)

Files

AppDbContext.cs

Application Database Context

namespace KingsEye.Data
{
    public class AppDbContext : IdentityDbContext
    {
        public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)  { }

        public DbSet<Home>       Home       { get; set; }
        public DbSet<Pages>      Pages      { get; set; }
        public DbSet<Newsletter> Newsletter { get; set; }
    }
}

CollectionModel.cs

View Model used on index.cshtml and shared newsletter.cshtml view

namespace KingsEye.Models
{
    public class CollectionModel
    {
        public Home       Home       { get; set; }
        public Pages      Pages      { get; set; }
        public Newsletter Newsletter { get; set; }
    }
}

Newsletter.cs

Newsletter View Model

namespace KingsEye.Models
{
    public class Newsletter
    {
        #region Newsletter
        [Display(Name = "Newsletter ID: ")]
        [Required(ErrorMessage = "Newsletter ID Required!")]
        public int     Id     { get; set; }

        [Display(Name = "Full Name: ")]
        [DataType(DataType.Text)]
        public string   Fname  { get; set; }

        [Display(Name = "E-Mail Address: ")]
        [DataType(DataType.EmailAddress)]
        public string   Email  { get; set; }

        [Display(Name = "Phone Number: ")]
        [DataType(DataType.PhoneNumber)]
        public int      Phone  { get; set; }

        [Display(Name = "Active: ")]
        [MaxLength(1)]
        public int      Active { get; set; }

        [Display(Name = "GUID: ")]
        [MaxLength(37)]
        public string   GUID { get; set; }

        [Display(Name = "Created: ")]
        [DataType(DataType.DateTime)]
        public DateTime Create { get; set; }

        [Display(Name = "Updated: ")]
        [DataType(DataType.DateTime)]
        public DateTime Update { get; set; }
        #endregion
    }
}

HomeController.cs

Home Controller

[HttpPost]
public async Task<IActionResult> NewsletterSignup(CollectionModel model)
{ 
    <= Error: is prompting prior to the body of this method being called, 
              and the parameter object being populated with post data!!!

    var newsletter = new Newsletter
    {
        Id     = 0,
        Fname  = model.Newsletter.Fname,
        Email  = model.Newsletter.Email,
        Phone  = model.Newsletter.Phone,
        Active = 0,
        GUID   = Guid.NewGuid().ToString(),
        Create = DateTime.Now,
        Update = DateTime.Now
    };

    ...
}

_Newsletter.cshtml

Shared view for the newsletter form

@model CollectionModel

<div id="newsletter">

    @if (User.Identity.IsAuthenticated)
    {
        <header>
            <i class="far fa-envelope-open"></i>
            <div class="text">Newsletter</div>
            <i class="far fa-envelope-open"></i>
        </header>

        <main>Subscribe to our newsletter</main>

        <footer>
            <form asp-controller="Home" asp-action="NewsletterSignup" method="post" id="newsletter-form" class="text-danger input-form">
                <div asp-validation-summary="ModelOnly"></div>

                <div class="form-group">
                    <input asp-for="@Model.Newsletter.Id" type="hidden" value="0" />
                </div>

                <div class="form-group">
                    <input asp-for="@Model.Newsletter.Fname" id="email-signed" class="form-control" placeholder="Your Name" />
                    <span asp-validation-for="@Model.Newsletter.Fname"></span>
                </div>

                <div class="form-group">
                    <input asp-for="@Model.Newsletter.Email" type="hidden" value="place@holder.com" />
                </div>

                <div class="form-group">
                    <input asp-for="@Model.Newsletter.Phone" id="email-signed" class="form-control" placeholder="(000) 000-0000" />
                    <span asp-validation-for="@Model.Newsletter.Phone"></span>
                </div>

                <div class="form-group input-submit">
                    <input id="newsletter-subscribe" type="submit" value="Subscribe" class="btn material-button" />
                </div>

                <div class="form-group">
                    <input asp-for="@Model.Newsletter.Active" type="hidden" value="0" />
                </div>

                <div class="form-group">
                    <input asp-for="@Model.Newsletter.GUID" type="hidden" value="0" />
                </div>

                <div class="form-group">
                    <input asp-for="@Model.Newsletter.Create" type="hidden" value="0" />
                </div>

                <div class="form-group">
                    <input asp-for="@Model.Newsletter.Update" type="hidden" value="0" />
                </div>

            </form>
        </footer>
    }
    else
    {
        <main>
            Please <a asp-controller="Auth" asp-action="Register">Sign-Up</a> to Subscribe for a Newsletter!
        </main>
    }
</div>

Goal

Would like to identify where this error is propagating from so that the exception in question can be debugged accordingly. Any advice or direction would surely be appreciated.

  • Thanks and cheers in advance.

MaxLenght attribute is for a string

    [Display(Name = "Active: ")]
    [MaxLength(1)] // this will fail
    public int      Active { get; set; }

    [Display(Name = "GUID: ")] 
    [MaxLength(37)] //this is okay
    public string   GUID { get; set; }

https://docs.microsoft.com/en-us/dotnet/api/system.componentmodel.dataannotations.maxlengthattribute?view=netframework-4.8

Gets the maximum allowable length of the array or string data.

Maxlengh property is causing trouble in your code.You may dont face any issue while post,delete or get but while updating or editing error will pop out.just get rid of that property add migration and update database.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM