2

I'm quite new to ASP and I'm creating a simple ASP.NET MVC App that stores personal info in a database. Using a DB First approach, I created the following db table:

CREATE TABLE [dbo].[Author] (
[PersonID]  INT           IDENTITY (1, 1) NOT NULL,
[MobileNum] NVARCHAR (50) NULL,
[Location]  NVARCHAR (50) NULL,
[LinkedIn]  NVARCHAR (50) NULL,
[FaceBook]  NVARCHAR (50) NULL,
[Picture]   IMAGE         NULL,
[Name]      NVARCHAR (50) NULL,
[Email]     NVARCHAR (50) NULL,
PRIMARY KEY CLUSTERED ([PersonID] ASC)

);

I use PersonID as a PrimaryKey and I want EF to autogenerate this for me, but for some reason this does not happen. I adjusted the identity options manually among the properties:

PersonID marked as identity

and I also attached the necessary attributes to my model (although I read somewhere that autogeneration is supposed to work without them as well):

public partial class Author
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int PersonID { get; set; }
    public string MobileNum { get; set; }
    public string Location { get; set; }
    public string LinkedIn { get; set; }
    public string FaceBook { get; set; }
    public byte[] Picture { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
}

Yet, the ModelState of the db is always false during the creation of a new entry:

ModeslState is false

and taking a closer look at it in the debugger, the problem seems to be that EF expects PersonID to be assigned by the user.

I have the following View belonging to the Create Action:

<div class="form-group">
    @Html.HiddenFor(model => model.PersonID, htmlAttributes: new { @class = "control-label col-md-2" })
</div>

Is there something else I'm supposed to do to enable the autogeneration of PersonIDs? What am I missing? Pointing me to a beginner level, DB First article is also much appreciated, since most articles I found did not make any mention of this problem whatsoever (e.g., here, here, or here).

oneManArmin
  • 606
  • 6
  • 24
  • It would be really great, if you could post your create table script instead of using a picture, so we can reproduce it more easily by just copy pasting everything in. – Marco Feb 02 '18 at 20:53
  • Possible duplicate https://stackoverflow.com/questions/16079217/how-to-generate-and-auto-increment-id-with-entity-framework – Lalithanand Barla Feb 02 '18 at 20:53
  • Code looks valid. What is the value of a.PersonID when you hit the post? You might want to consider using [ViewModels](http://stevemichelotti.com/aspnet-mvc-view-model-patterns/) with automapper. That cleans up a lot of these issues. – Steve Greene Feb 02 '18 at 21:15
  • Marco: true, I update my post, @Lalithanand Barla: I have an int autoporperty and I started up with no annotations, so I have a different problem. – oneManArmin Feb 02 '18 at 21:39
  • @SteveGreene: PersonID is 0, while my IdentitySeed is 1, so this is probably becuase of the default value of an int. – oneManArmin Feb 02 '18 at 21:43
  • I see that you have set the state to added ok but where have you called db.savechanges are you sure its the primary key causing the issue could it not be the Picture field as its a byte column. You just have a catch consider using catch(exception ex) and then put a brakepoint on the ex and check the inner exception. – c-sharp-and-swiftui-devni Feb 02 '18 at 21:46
  • I do not have an exception, it's that the ModelState of the db is false, so I never get to do the saveChanges which would be, of course, inside the `if` block. In the Picture column, the `IMAGE` is supposed to be fine, Visual Studio recognised it and implemented it with the corresponding `byte[]` property accordingly. – oneManArmin Feb 02 '18 at 22:11
  • I would suggest you have a look at the queries being generated using SQL profiler (or Express Profiler) it should give you some hint on why the query is failing. – Charanraj Golla Feb 03 '18 at 02:45
  • As code looks okay, try to check a couple different things: are you connecting to the right database? Is your model synchronized with the database? Run `add-migration` and see if this generates a non-empty migration. Run `update-database -script` and take a look at the generated sql. Double-check your connection string in your debugging environment. – Diana Feb 03 '18 at 12:40
  • Also, check the table creation code in the migration that originally created it. How is the PersonId field defined there? – Diana Feb 03 '18 at 12:43

2 Answers2

1

Thank you for all your suggestions in the comment section, but surprisingly, the problem had nothing to do with the DB or the Model: I recreated the whole DB, but still got the same error. Turns out, the problem was in the view responsible for prompting input from the user upon creating a new entry, to be more specific, this was the problematic part:

<div class="form-group">
    @Html.HiddenFor(model => model.PersonID, htmlAttributes: new { @class = "control-label col-md-2" })
</div>

SOLUTION: I just deleted the whole <div> with the @Html.HiddenFor html helper for the id and the db now accepts new entries. Simple as that.

What I think caused the problem is that the db seemed to expect ID to be provided by the user even though the helper was set to hidden and I suppose, this is why ModelState.IsValid was always false. I used @Html.HiddenFor in the Edit feature (I wrote edit before create to test the db with mock data) and it had no problems, so I thought by disallowing the user to interact with a piece of data, ASP will automatically know not to expect it from the user, but clearly, I was wrong.

oneManArmin
  • 606
  • 6
  • 24
0

Try this code to declare primary key

[PersonID] int IDENTITY(1,1) PRIMARY KEY