Endpoint object serialisation overlooks a public field
Is there an existing issue for this?
- [X] I have searched the existing issues
Describe the bug
After returning from the endpoint GET /issue/1 i expect the json to contain the field project with the value 1.
As this is the value set in the DTO.
But it holds {}
Expected Behavior
I expect the serialisation to contain all fields with their value as described in the DTO Project.
Steps To Reproduce
- Given the attached project, start the project
- Setup an issue at the endpoint
curl -X 'POST' \
'https://localhost:7174/issue/1' \
-H 'accept: */*' \
-H 'Content-Type: multipart/form-data' \
-F 'author=a' \
-F 'comment=b'
- Retrieve the issue via
GET /issue/1. Now i expect thatprojectIdis set to 1 in the first element of the list
Exceptions (if any)
No response
.NET Version
7.0.100-preview.6.22352.1
Anything else?
.NET SDK:
Version: 7.0.100-preview.6.22352.1
Commit: 492644e08e
Runtime Environment:
OS Name: Mac OS X
OS Version: 12.5
OS Platform: Darwin
RID: osx.12-x64
Base Path: /usr/local/share/dotnet/sdk/7.0.100-preview.6.22352.1/
Host:
Version: 7.0.0-preview.6.22324.4
Architecture: x64
Commit: d3fa592f6d
.NET SDKs installed:
6.0.400 [/usr/local/share/dotnet/sdk]
7.0.100-preview.6.22352.1 [/usr/local/share/dotnet/sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 6.0.8 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 7.0.0-preview.6.22330.3 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 6.0.7 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.8 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 7.0.0-preview.6.22324.4 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Other architectures found:
None
Environment variables:
Not set
global.json file:
/Users/user/Documents/backend/global.json
Learn more:
https://aka.ms/dotnet/info
Download .NET:
https://aka.ms/dotnet/download
As far as i could find the serialisation of responses is described here
And therefore the DataMemberAttribute should be in effect but it seems not to be.
Also swagger notices the id field
@javiercn is this just missconfiguration, or dose aspnet really drop attributes?
@brunolins16 is there a quick fix available?
@Hu1buerger sorry for the delay in answering your question.
As far as i could find the serialisation of responses is described here
And therefore the
DataMemberAttributeshould be in effect but it seems not to be. Also swagger notices the id field
The documentation you provide targets ASP.NET Web API and not ASP.NET Core. Here some docs that might cover the same:
- https://docs.microsoft.com/en-us/aspnet/core/web-api/action-return-types?view=aspnetcore-7.0
- https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-customize-properties?pivots=dotnet-7-0
- https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-ignore-properties?pivots=dotnet-7-0
Also, I looked at your application and probably you are already aware of, but the problem is MVC, to keep the polymorphic behavior, will try to get the runtime type to serialize your result. That means, in your case the runtime type is Issue not IssueDTO and the Issue.Project does not have a public property ProjectId (it does have a public field).
https://github.com/dotnet/aspnetcore/blob/7fac52dea79a90143715201d2b1f62289d1ef608/src/Mvc/Mvc.Core/src/Formatters/SystemTextJsonOutputFormatter.cs#L75
I think your goal is to use the DTO (make totally sense) however you could not cast an IEnumerable<Issue> to IEnumerable<IssueDTO> and the easier way, but not the best performance, is to create a new list. Something like this:
[HttpGet("{projectId}")]
public ActionResult<IEnumerable<IssueDto>> IssuesByProject(int projectId){
if (_projectService.ProjectById(projectId).IsNone)
return BadRequest("project dosnt exist");
var issues = _issueService.Issues(projectId);
return Ok(issues.Select(i => (IssueDto)i));
}
Hi @Hu1buerger. We have added the "Needs: Author Feedback" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.
This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 4 days. It will be closed if no further activity occurs within 3 days of this comment. If it is closed, feel free to comment when you are able to provide the additional information and we will re-investigate.
See our Issue Management Policies for more information.
@brunolins16 will try that one out
@Hu1buerger let us know in case you need any additional information, Thanks
This issue has been resolved and has not had any activity for 1 day. It will be closed for housekeeping purposes.
See our Issue Management Policies for more information.
Works. @brunolins16 why isnt the implicit operation performed before the serialisation? IMHO the projection should be performed transparently. What edge case am i overlooking?
There should be an implicit operation defined on Issue with
public static implicit operator IssueDto(Issue i) => new IssueDto(i.Project.ProjectId.ToString(), i.IssueId,
i.Comments.Select(c => new IssueCommentDto(new Author(c.Author), c.CreatedAt, c.Comment)).ToList());