0

I'm working on a feature that allows a user to submit a post via a form, it successfully obtains the user Id from AspNetUsers. I have implemented a radio button that gives a user the option to become an anonymous submission. The code is as follows,

protected void AddPost(object sender, EventArgs e)
{



    var User = System.Web.HttpContext.Current.User.Identity.GetUserId();
    if (Convert.ToBoolean(Int32.Parse(inputAnonymous.SelectedValue)))
    {
        User = "anonymous";
    }

    Post newPost = new Post()
    {
        postTitle = inputTitle.Text,
        postBody = inputBody.Text,
        postDescription = inputDescription.Text,
        postCategory = inputCategory.SelectedValue,
        postAnonymous = Convert.ToBoolean(Int32.Parse(inputAnonymous.SelectedValue)),
        Id = User
    };

    using (var _dbContext = new ApplicationDbContext())
    {
        _dbContext.Posts.Add(newPost);
        _dbContext.SaveChanges();
    }
}

When the option "No" is selected for user anonymousity, the post is submitted normally, and it posts the id into the database etc, but when I click on "Yes" as I follow the debugger, it says that it is recognizing that it is anonymous, and that it should change the userId to the string "anonymous" and submit that to as the Id in the database, but I keep getting this error that prevents me that is as follows

SqlException: The INSERT statement conflicted with the FOREIGN KEY constraint "FK_dbo.Posts_dbo.AspNetUsers_Id". The conflict occurred in database "aspnet-WebEnterprise-20190201040107", table "dbo.AspNetUsers", column 'Id'. The statement has been terminated.

UPDATE: I've added this bit of code to my configuration.cs

 {
                var passwordHash = new PasswordHasher();
                string password = passwordHash.HashPassword("Anonymous@123");
                context.Users.AddOrUpdate(u => u.UserName,
                    new ApplicationUser
                    {
                        UserName = "Anonymous@Anonymous.com",
                        PasswordHash = password,
                        PhoneNumber = "12345678911",
                        Email = "Anonymous@Anonymous.com"
                    });
                context.Roles.AddOrUpdate(
                    new IdentityRole { Id = "a1f04ba5-5600-4a6e-be43-ae0d6360c0ab", Name = "Anonymous" }
                    );
            }

but when I update-database on the nuget packet manager, I get the following error

"An error occurred while updating the entries. See the inner exception for details."

zadders
  • 428
  • 1
  • 8
  • 30
  • My guess is that there is no user with ID "anonymous" and you get an error because of that. Try to put any random integer ID instead of "anonymous" and you should get the same error if there is no user with that random ID. – Matt Mar 13 '19 at 12:39
  • 2
    The error is rather clear - the `AspNetUsers` doesn't contain any user whose `ID` is anonymous. There's nothing wrong with this code, apart from using an `Id` value that doesn't exist. – Panagiotis Kanavos Mar 13 '19 at 12:39
  • That FOREIGN KEY constraint would leave me to believe that there is a FK on Post enforcing the constraint that a post be made by a user from the AspNetUsers table. Perhaps you need to impersonate a AspNetUser when posting anonymously. – Ross Bush Mar 13 '19 at 12:40
  • Also, if 'User' is an object, what does User = "anonymous" do? – Matt Mar 13 '19 at 12:41
  • @Matt User "Anonymous" is supposed to create a mask or something so when you'd view the "Posts" database, the admins can't see the user Id used to submit that post. – zadders Mar 13 '19 at 12:42
  • @zadders so it creates new User object? What ID does that User have? As all of comments said, there is a problem with foreign key. You can't bind non existing user to a post. – Matt Mar 13 '19 at 12:46
  • @Matt well the software uses Identity to create a user Id, which is a long hashed key. Would there any way for me to allow an "anonymous" mode then without trying to change the user's actually id in the database? – zadders Mar 13 '19 at 12:48
  • 2
    @zadders My suggestion is to create an Anonymous user, get his ID and bind that ID to all posts that should be anonymous. All anonymous post would then have the same ID, but that should not matter because they are anonymous anyway. – Matt Mar 13 '19 at 12:51
  • @Matt Would you happen to know of a way I can create a user using Code-first with the configuration.cs migration? I use that technique to add pre-made departments etc but I'm unsure how to do it with the AspNetUsers – zadders Mar 13 '19 at 13:14
  • @Matt But the anonymous user idea is actually a smart one, sounds like that would fix this issue – zadders Mar 13 '19 at 13:14
  • @zadders Does this help? https://stackoverflow.com/questions/19280527/mvc-5-seed-users-and-roles or this: https://forums.asp.net/t/2135919.aspx?Seed+Users+and+Roles+in+an+ASP+NET+MVC+Application – Matt Mar 13 '19 at 13:27
  • @Matt I've added the next error that's popped up from following one of those fixes. I updated my question above to see the changes I made. – zadders Mar 13 '19 at 13:58
  • @zadders And what is in inner exception? – Matt Mar 13 '19 at 14:05
  • @Matt Sorry for the noobie question, but how would I check the inner exception? – zadders Mar 13 '19 at 14:06
  • @zadders try-catch(Exception ex){string innerEx = ex.InnerException.message} – Matt Mar 13 '19 at 14:10
  • @Matt Where would I insert that? – zadders Mar 13 '19 at 14:11
  • @zadders https://dotnetfiddle.net/h8JTVX – Matt Mar 13 '19 at 14:15
  • @Matt Ahh I think the error is going back to the original one for the Foreign key clash with Id, am I meant to remove the " // Foreign key to customer [ForeignKey("Department")]" " part on the IdentityModel? – zadders Mar 13 '19 at 14:29
  • @Matt Where is the message of the inner exception supposed to be displayed? – zadders Mar 13 '19 at 14:33
  • @zadders Run program in debug mode. When exception is thrown, hover over exception pop-up and check messages. Also, be sure to understand foreign keys https://www.w3schools.com/sql/sql_foreignkey.asp – Matt Mar 13 '19 at 14:46
  • 1
    @Matt I realized that there was a conflict with the departmentId too, but once I changed that it all worked perfectly :D Thank you so much for being patient and helping out – zadders Mar 13 '19 at 15:04
  • @zadders No problem :) I am going to write a summary of this conversation as an answer and would appreciate if you would accept it as an answer. – Matt Mar 13 '19 at 15:33

1 Answers1

1

There is no user with ID "anonymous" and you get an error because of that. The AspNetUsers doesn't contain any user whose ID is "anonymous". There's nothing wrong with this code, apart from using an Id value that doesn't exist.

As far as that problem goes, my suggestion is to create an Anonymous user, get his ID and bind that ID to all posts that should be anonymous. All anonymous post would then have the same ID, but that should not matter because they are anonymous anyway. Check this and this link for more info how to insert users via code-first architecture

Matt
  • 1,245
  • 2
  • 17
  • 32