I'm purposely not posting any code here as I'm really just looking for some guidance to the following problem:
I have created a three new fields in my AspNetUsers table - FirstName, LastName, and NickName. I also created a composite key using those three fields. When I try to create a new user that has all three of these fields the same, the application throws an error as expected when the unique rule is violated.
I would like it to simply post back to the Register User form indicating that the NickName must be changed to something else.
Do I need to implement a Custom User Store? Is there a simpler way?
Thank you for any suggestions.
Related
I've been working through Adrian Hall's book on integrating Xamarin and Azure Mobile Apps. In Chapter 3 he adds a User table to facilitate "Friends" data. In his implementation, the client authenticates the user and then makes a request to a custom endpoint that either adds the user to the database or updates their record. Here's an abridged version of the method in the custom controller:
[HttpGet]
public async Task<IHttpActionResult> Get()
{
// ...Obtain user info
User user = new User()
{
Id = sid,
Name = name,
EmailAddress = email
};
dbContext.Users.AddOrUpdate(user);
dbContext.SaveChanges();
// ...
}
The trouble is, the 2nd time the same user logs in to the app, this code throws an exception saying
Modifying a column with the 'Identity' pattern is not supported. Column: 'CreatedAt'. Table: 'CodeFirstDatabaseSchema.User'.
This StackOverflow Answer explains that this is because the AddOrUpdate() method nulls out any properties not set on the entity, including CreatedAt, which is an identity column. This leaves me with a couple of questions:
What is the right way to Add or Update an entity if the CreatedAt value cannot be edited? The same SO thread suggests a helper method to look up the existing CreatedAt and apply it to the entity before trying to save it. This seems cumbersome.
Why is this implemented as a custom auth controller that returns a new Auth token when it only needs to add or update a User in a database? Why not use a normal entity controller to add/update the new user and allow the client to continue using the Auth token it already has?
For the CustomAuthController.cs code, see here.
When you focus on what you are trying to do from SQL perspective it would be like:
update dbo.some_table set some_primary_key = new_primary_key where some_primary_key = ...
which would result in cannot update identity column some_primary_key which makes sense.
But if you do have a reason to update the PK you still can do it if you set the identity insert
SET IDENTITY_INSERT dbo.some_table ON;
Then after you made an insert you set it off using similar syntax.
But this is rather exceptional scenario.
Usually there is no need to manually insert PKs.
Now going back to EF.
The error you are getting is telling you that you cannot modify a column with PK, most likely user_id and/or some other columns if you have composite PK.
So, first time round a new user gets created. Second time round, because you are suing GetOrUpdate a user gets udpated but because you are passing PK it breaks.
Solution?
AddOrUpdate was meant to help with seeding the migrations only.
Given its destructive nature I would not recommend using GetOrUpdate anywhere near production.
You can replace GetOrUpdate with two operations Get and Update
Fetch user and then
if not exists then create a new one
or if it does exist then update it
When regsitering in my site (ASP.Net MVC application), the users get inserted into the aspnet_users table. Since its a shopping site, I would want the users to have a customer id and all their details provided by them at registration in this Customer table as well. How do I link these 2 tables? Is it recommended to use the aspnet_user's UserId(Guid) in the application for other business processes.
Also, I would like to know when should a new record be inserted into the customers table.
I mean, when should a new customer be created. I guess its not good to create a record as ans when users are registered? Here, I want to know whats the norm? I felt it would be better to add it when a user adds an item to the shopping cart. Pls guide me.
Thanks in advance.
Add the UserId field into your customer table and then make a foreign key relationship back to the UserId in the aspnet_users table if you want to enforce relational integrity.
I'm not sure what you mean about when to insert the customer record. As long as you insert it after you have created the user (so that you have the user ID), you should be fine. It can happen in the same postback.
I'm not sure how you are saving the user. As in are you using one of the built-in ASP.Net controls or making the call manually?
If you are using the Membership provider as it sounds like you are, you can save the member using:
var user = Membership.CreateUser;
Guid userKey = user.ProviderUserKey;
//Populate your customer object.
//now use whatever EF/ADO/etc... to save your customer record.
Does anyone have some code or a link as to how to create the user login name as a parameter during a sql query in ASP.NET?
Basically I want to use the default membership structure with a new field ClubID, then I want to add a new table called aspnet_Clubs which contains things such as Club Name, stadium name, Balance etc etc... and then use a relationship between ClubID and a field in the aspnet_Clubs table to tie things together.
Then when each user logs in they should see the clubs information specific to their loginID.
I know the syntax to use for the query, its getting the loginname parameter and being able to use/assign it as part of the search that is causing me the problem.
In general it is not recommended to break the default schema of the aspnetdb where the Membership data is stored. It can bring you to unexpected consequences in the future.
I had a similar question a couple of days ago, please check it here, may be you will be able to adopt something from the discussion to your situation.
In the standard forms authentication, users are identified by a Guid. I want to give my users an UserId of type int (doesn't have to be the primary key, just something to do lookup's on).
Is it safe to add an additional column to the aspnet_users table, or should I create a new table which FKs to the UserId column and has a Unique column which generates the integer ID?
The later sounds like a bad performance hit to take just for the sake of an int!
EDIT
I want to create URLs like those on stackoverflow. eg. https://stackoverflow.com/users/23590/greg-b where the User ID is an int. For that reason I don't want to use Guids.
I'd create profiles and store the associated urlID there. Web Forms don't have Profiles available out of the box, but you can see a workaround here:
http://www.codersbarn.com/post/2008/06/01/ASPNET-Web-Site-versus-Web-Application-Project.aspx
The advantage of using Profiles is that you can tap into all the existing logic and won't have to write as much custom code yourself, aside from constructing the URL.
You could combine this with Routing for friendly URLs, if you're using ASP.NET 3.5 or up.
UPDATE: kinda similar question:
Shorter GUID using CRC
I'm pretty new to MVC 2 using the Entity Framework. I have two tables Company {ID int identity PK,Name nvarchar} and User {ID int identity PK,UserName nvarchar,CompanyID int FK}. A Foreign Key exists between User and Company.
I generated my ADO.NET Entity Data Model, a Controller and a view to insert a record. My HTML form has the fields Company and UserName and the idea is when I click save a Company and User is inserted into the database. Sounds straight forward right!
My question is as follows:
I created a strongly-typed view derived from my 'User' entity. I'm using the the html helper Html.TextBoxFor(model => model.Organisation.Name) but the html name attribute for this input field is 'Organisation.Name'. My problem with this is that the dot throws up all sorts of issues in JQuery, which sees this as a property. If I want to change the name I read that I can use DataAnnotations but because I used the Entity Designer this involves using Buddy Classes. Seems like a bit of overkill just to change the html name attribute on this input field. Am I approaching this the right way or am I missing something here?
Thanks for the help !
I resolved this by taking a step back and reevaluating the way I was structuring my data. The end result was that my business entities were too closely coupled to my database schema and didn't reflect the domain I was working in. I redesigned my app. using POCO's to represent my business entities that better reflected my domain and this had the effect of 'flattening' the relational structure in this scenario, so instead of model.Organisation.Name I now have model.OrganisationName.