-
-
Notifications
You must be signed in to change notification settings - Fork 158
Potential Bug Serializing Id's? #363
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@RKennedy9064 thanks for reporting this. Does your model inherit from JsonApiDotNetCore/src/JsonApiDotNetCore/Models/Identifiable.cs Lines 32 to 34 in 74667eb
If this is the case, then you can:
protected override string GetStringId(object value)
{
// since we're in the concrete type, we know the type of the Id
// and can dispense with the base implementation type handling
return value.ToString();
} I'll need to do some more research into whether or not we actually need the empty string id. I remember there was a use case around how to handle the unset case ( |
@jaredcnance Thanks for the quick response and taking time out your day to help me out. Currently my models all inherit from Identifiable and I've been doing Identifiable and such for keys that aren't int's. I figured |
@jaredcnance I was able to test overriding GetStringId and the response now sends 0 as the Id with the model. Just figured I'd give you a heads up, not sure if you want to keep this open or not. |
Leaving it open because I'd like to revisit this later. |
I would like to add some extra information to this issue. I had the exact same problem and unfortunately did not see this issue in my search, but after solving it I figured I would leave my experience. I started by removing the This started out fine, but created an issue: whenever I submitted a POST request it failed because 0 was being submitted as the ID when it should have been empty (identity key column) My solution was to have the model inherit from Not sure what fix would be available other than requiring all Identifiable types to be nullable, but I figured I would leave this info here in the hopes someone else may stumble upon it. To summarize my steps to resolving all issues: To resolve GET requests correctly, change:
To the following:
To resolve POST requests: |
@czemanek-arm you shouldn't have to make ids nullable. This sounds like an issue with your DbContext setup. I suspect EF is not aware this is an autogenerated identity column and as such is issuing requests like |
It's possible. I did have the column set to Identity in the EF model, but the black box of EF knows no master. |
Can you show me how you're doing this? Also, can you enable verbose logging on EF and paste the logs you get during the POST request? |
As far as I know there is no "Identity" attribute, but EF is supposed to detect it from an integer key, so I'm just doing: Oh yeah I'll look into doing that, will probably be some time before I can sit down and play with it again. |
Ah I see. Unfortunately, the
Was the database created by EF or was it pre-existing? This may be part of the issue. I would recommend trying this: protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Book>()
.Property(book => book.Id)
.ForSqlServer()
.UseIdentity();
} Or this: public class Book
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
} I also recommend reading the docs on Value generated on add:
|
Gotcha, I'll take a look at refactoring some of this next time I get the chance, thanks for the pointers! |
How about this issue? I have a table with the primary (int --not identity) column. The data there has a value of 0 on ID column. But when executed, the error message "Value cannot be null. (Parameter 'id')" appears (something like that). Environment
|
I think the quote from EF Core (mentioned above) says it all:
So it you want 0 to be treated as an actual value, you need to make sure it differs from the default value. In other words, make it nullable. The next special handling was removed months ago, so I expect that workarounds are no longer needed: return stringValue == "0" ? string.Empty : stringValue; I haven't tried, but would expect both GET and POST to work properly for 0 values when inheriting your resource from If any additional issues remain, please post your model, along with the request/response data. And in case of errors, include the full stack trace (which you'll get by enabling it in options). |
Thank you for the instructions. For the int data type, it can be handled using Example models:
Once again, thank you for the instructions. |
I would think the same rule applies. "" is not equal to null (the default value for string) so it should just work, unless EF Core itself treats strings differently. Are you running into any issues or unexpected behavior? |
By this model:
With examples of data such as:
I sent a request:
The empty string handling should be the same as the |
Interesting. Can you include the stack trace? Enable it in startup options to include it in the response. |
And which database are you using? |
The following is the stack trace I got:
By startup config:
and, the database I use is SQL Server 2017. Thanks for the quick response. |
Has the empty string issue been fixed? When is the next beta scheduled? |
I did some Note though that empty string IDs are unlikely to work properly in general. For example, in URLs there is no distinction between empty string and missing. So you cannot fetch a row by ID when that ID is an empty string. And when creating a resource using a client-generated ID that is an empty string, the returned Location header is wrong (it contains no ID value, so it points to a collection endpoint: /articles/ instead of /articles/1). I don't see how we can solve these. |
I've been messing around with JsonApiDotNetCore a lot recently and encountered something strange. For some reason the database I'm working with has some tables where the Primary Key starts at 0 and I'm noticing some strange results. For any row where the Id is 0, it looks like it's not serializing the Id with the response. Is this intended behavior, or am I doing something wrong? For example, here is my request and response for an id of 1.
and here is my request and response for an id of 0.
It's able to find the case-status-class in the database with an Id of 0, but for some reason it's not sending the Id back with the response. When trying to bind my models in Ember it's giving me issues since there's no id.
Is this an actual issue with how JsonApiDotNetCore is sending data back, or is it a user error and I have something messed up in my configuration? Just figured I'd bring it up since I noticed it. Any help would be greatly appreciated.
The text was updated successfully, but these errors were encountered: