Skip to content
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

Support serialization of Microsoft.Extensions.Primitives.StringValues #1559

Closed
joshmouch opened this issue Sep 27, 2019 · 34 comments
Closed

Comments

@joshmouch
Copy link

I'm switching to System.Text.Json from Json.Net, and the following is no longer serializable:
Microsoft.AspNetCore.Http.FormFile

The exception is:

System.NotSupportedException : The collection type 'Microsoft.AspNetCore.Http.IHeaderDictionary' on 'Microsoft.AspNetCore.Http.FormFile.Headers' is not supported.`

Will this be supported? Are there any workarounds?

@scalablecory
Copy link
Contributor

Are there any workarounds?

Are you able to implement a custom JsonConverter?

@joshmouch
Copy link
Author

@scalablecory Maybe... I was worried I'd be opening a can of worms and writing 20 converters for something Json.Net already supported.

@SimonCropp
Copy link
Contributor

@joshmouch out of curiosity, why are you serializing a FormFile? what is the output of newtonsoft serializing it?

@joshmouch
Copy link
Author

When I expose an Iformfile then generate a swagger client from it, the generated client excepts a Stream type. I have to include a custom type filter for Swashbuckler, though.

@ahsonkhan
Copy link
Member

cc @pranavkm, @rynowak

@rynowak
Copy link
Member

rynowak commented Oct 2, 2019

@joshmouch - just curious.. what do you expect to happen with JSON serialization and IFormFile - I would be really surprised if it did anything useful.

@joshmouch
Copy link
Author

joshmouch commented Oct 3, 2019

@rynowak
In Asp.net Core 2.2 with JSON.Net, you can upload a file to an API operation with an auto-generated swagger definition and a strongly-typed auto generated client.

  1. Include an IFormFile parameter on an API operation call. It needs to have a [FromForm] attribute.
  2. Create a SwashBuckler filter that changes the IFormFile parameter to "In=formData, Type=file". This updates the Swagger.json definition. It's also important the "consumes" is "multipart/form-data", but that's automatically done.
  3. Use AutoRest.exe to generate a client from the Swagger.json definition. This client will have methods that can send files to the API via System.IO.Stream objects.

@rynowak
Copy link
Member

rynowak commented Oct 3, 2019

Use AutoRest.exe to generate a client from the Swagger.json definition. This client will have methods that can send files to the API via System.IO.Stream objects.

That's pretty cool! I didn't realize that Autorest could do that.

Do you have the full callstack of that exception? What part of the code is blowing up. I'm asking because I want to see if we can find a workaround to unblock you.

@joshmouch
Copy link
Author

Sure thing!

System.NotSupportedException : The collection type 'Microsoft.AspNetCore.Http.IHeaderDictionary' on 'Microsoft.AspNetCore.Http.FormFile.Headers' is not supported.
   at System.Text.Json.JsonClassInfo.GetElementType(Type propertyType, Type parentType, MemberInfo memberInfo, JsonSerializerOptions options)
   at System.Text.Json.JsonClassInfo.CreateProperty(Type declaredPropertyType, Type runtimePropertyType, Type implementedPropertyType, PropertyInfo propertyInfo, Type parentClassType, JsonConverter converter, JsonSerializerOptions options)
   at System.Text.Json.JsonClassInfo.AddProperty(Type propertyType, PropertyInfo propertyInfo, Type classType, JsonSerializerOptions options)
   at System.Text.Json.JsonClassInfo..ctor(Type type, JsonSerializerOptions options)
   at System.Text.Json.JsonSerializerOptions.GetOrAddClass(Type classType)
   at System.Text.Json.WriteStackFrame.Initialize(Type type, JsonSerializerOptions options)
   at System.Text.Json.JsonSerializer.WriteAsyncCore(Stream utf8Json, Object value, Type inputType, JsonSerializerOptions options, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
   at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeResultAsync>g__Logged|21_0(ResourceInvoker invoker, IActionResult result)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResultFilterAsync>g__Awaited|29_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
...
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at IdentityServer4.Hosting.IdentityServerMiddleware.Invoke(HttpContext context, IEndpointRouter router, IUserSession session, IEventService events)
   at IdentityServer4.Hosting.MutualTlsTokenEndpointMiddleware.Invoke(HttpContext context, IAuthenticationSchemeProvider schemes)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at IdentityServer4.Hosting.BaseUrlMiddleware.Invoke(HttpContext context)
   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
...
   at Microsoft.AspNetCore.TestHost.HttpContextBuilder.<>c__DisplayClass20_0.<<SendAsync>g__RunRequestAsync|0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.TestHost.ClientHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
...

@rynowak
Copy link
Member

rynowak commented Oct 3, 2019

This callstack implies to me that this API returns an IFileInfo - is that the case?

@joshmouch
Copy link
Author

joshmouch commented Oct 3, 2019

@rynowak ,
You are correct. I had this mixed up. So it's when an IFormFile is returned from an API operation that it's bombing, not when an operation is accepting one. Let me gather some more information and respond on this thread.

@vzalamea
Copy link

I had the same problem serializing Request.Headers (Microsoft.AspNetCore.Http.IHeaderDictionary). Luckily an extension method exists:

var d = Request.Headers.ToDictionary(k=>k.Key, v=>v.Value);

@layomia layomia removed their assignment Dec 3, 2019
@mtirion
Copy link

mtirion commented Dec 19, 2019

I have the same issue. Is there already a solution for this?

@petriashev
Copy link

The same error.

@mtirion
Copy link

mtirion commented Dec 30, 2019

I don't have this issue anymore. The problem was caused by what I RETURNED from the Controller method instead of the parameter of the method.

For the input of the method I want to have the uploaded file IFormFile type, but also the meta data. So what I did was create a base class (CustomFile) with attributes like name and such. Then I created a subclass (UploadFile) that inherits from CustomFile and adds the IFormFile as a field.

As the standard method to implement this is the POST method, the standard return is CreatedAtAction("GetCustomFile", ...). What I did here before was return the UploadFile - and this causes the error. But I don't want to return the file to the client, but just the meta data (CustomFile). When I changed that, error was gone.

Does this help for you? I hope I explained it in a way you can understand it :)

@jigneshpclarion
Copy link

Hi,

Is there any solution for this issue. I have .Net core app developed with 2.2 and Just update it with 3.1 and it breaks the working code. Following is the stack trace of error. Please suggest if any solution for this.

System.NotSupportedException: The collection type 'Microsoft.AspNetCore.Http.IHeaderDictionary' on 'Microsoft.AspNetCore.Http.IFormFile.Headers' is not supported.
at System.Text.Json.JsonClassInfo.GetElementType(Type propertyType, Type parentType, MemberInfo memberInfo, JsonSerializerOptions options)
at System.Text.Json.JsonClassInfo.CreateProperty(Type declaredPropertyType, Type runtimePropertyType, Type implementedPropertyType, PropertyInfo propertyInfo, Type parentClassType, JsonConverter converter, JsonSerializerOptions options)
at System.Text.Json.JsonClassInfo.AddProperty(Type propertyType, PropertyInfo propertyInfo, Type classType, JsonSerializerOptions options)
at System.Text.Json.JsonClassInfo..ctor(Type type, JsonSerializerOptions options)
at System.Text.Json.JsonSerializerOptions.GetOrAddClass(Type classType)
at System.Text.Json.JsonPropertyInfo.get_ElementClassInfo()
at System.Text.Json.JsonSerializer.Write(Utf8JsonWriter writer, Int32 originalWriterDepth, Int32 flushThreshold, JsonSerializerOptions options, WriteStack& state)
at System.Text.Json.JsonSerializer.WriteAsyncCore(Stream utf8Json, Object value, Type inputType, JsonSerializerOptions options, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Mvc.Infrastructure.SystemTextJsonResultExecutor.ExecuteAsync(ActionContext context, JsonResult result)
at Microsoft.AspNetCore.Mvc.Infrastructure.SystemTextJsonResultExecutor.ExecuteAsync(ActionContext context, JsonResult result)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|29_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Logged|17_1(ResourceInvoker invoker)
at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
at ElmahCore.Mvc.ErrorLogMiddleware.Invoke(HttpContext context, Func`1 next)
at ElmahCore.Mvc.BuilderHelper.<>c.<b__0_0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

@mtirion
Copy link

mtirion commented Jan 2, 2020

@jigneshpclarion are you returning an IFormFile in your API method? That's not the way to return a file and might cause this issue.

@jigneshpclarion
Copy link

jigneshpclarion commented Jan 2, 2020

@mtirion - I'm not returning IFromfil in API method. Below is the API method code.

[HttpGet("{id}")]
public async Task<IActionResult> GetItem(int id)
{
var item = await itemService.Get(id);
if (item == null)
{
	return NotFound();
}
return new JsonResult(item);
}

@mtirion
Copy link

mtirion commented Jan 2, 2020

@jigneshpclarion what's the definition of the item? And are you sure it's failing on this method? Your stacktrace shows that there is an issue with the Microsoft.AspNetCore.Http.IFormFile.Headers.

@jigneshpclarion
Copy link

Before upgrading to .net core 3.1 following response returned by this method.


{
  "data": {
    "itemId": 16,
    "elite": true,
    "curatorsPick": true,
    "isActive": true,
    "itemCompleted": false,
    "isLock": true,
    "readyForWebSite": true,
    "previous": 0,
    "next": 0,
    "isTiffOnServer": null,
    "tiffNotes": null,
    "name": "KAUSHIK 1234",
    "itemSubject": "16Subject",
    "itemCreateDateDay": 1,
    "itemCreateDateMonth": 2,
    "itemCreateDateYear": 2001,
    "isApproximateDate": false,
    "itemCreateDateText": "Summer ",
    "itemFromName": 346,
    "itemFromState": null,
    "itemFromCountry": 57,
    "itemFromCity": 335,
    "itemFromAddress": "32685 SBL",
    "itemFromGPSLatitude": null,
    "itemFromGPSLongitude": null,
    "itemToFirstName": "_round",
    "itemToLastName": "_andaround",
    "itemToState": 195,
    "itemToCountry": 256,
    "itemToCity": null,
    "itemToAddress": null,
    "itemToGPSLatitude": null,
    "itemToGPSLongitude": null,
    "itemTypeId": 7,
    "pagesNum": 7,
    "sizeId": 1,
    "itemWidth": 9,
    "itemHeight": 9,
    "itemWidthInch": 9,
    "itemHeightInch": 9,
    "itemImages": [
      {
        "itemPageId": 271,
        "itemId": 16,
        "pageWidth": 190,
        "pageHeight": 150,
        "pageNumber": 1,
        "comment": null,
        "pageUrl": "http://server.blob.core.windows.net/collectioncollection/Scan%5C637019849346478557_58_thumb.jpg",
        "pageName": "58_thumb.jpg",
        "pageTranscript": null,
        "pageTransLowResImageFilename": null
      },
      {
        "itemPageId": 272,
        "itemId": 16,
        "pageWidth": 1200,
        "pageHeight": 962,
        "pageNumber": 2,
        "comment": null,
        "pageUrl": "http://server.blob.core.windows.net/collection/Scan%5C637019849399027141_59_New.jpg",
        "pageName": "59_New.jpg",
        "pageTranscript": null,
        "pageTransLowResImageFilename": null
      },
      {
        "itemPageId": 273,
        "itemId": 16,
        "pageWidth": 254,
        "pageHeight": 150,
        "pageNumber": 3,
        "comment": null,
        "pageUrl": "http://server.blob.core.windows.net/collection/Scan%5C637019849424977408_88_thumb.jpg",
        "pageName": "88_thumb.jpg",
        "pageTranscript": null,
        "pageTransLowResImageFilename": null
      },
      {
        "itemPageId": 290,
        "itemId": 16,
        "pageWidth": 290,
        "pageHeight": 410,
        "pageNumber": 4,
        "comment": null,
        "pageUrl": "http://server.blob.core.windows.net/collection/Scan%5C637129899206841546_nerdy_giraffe.jpg",
        "pageName": "nerdy_giraffe.jpg",
        "pageTranscript": "<p>Nerdy by Nature</p>\n",
        "pageTransLowResImageFilename": null
      }
    ],
    "itemContent": "<p><strong>FOR TESTING PURPOSE </strong></p>",
    "itemPhysicalDescription": "<p></p>\n",
    "categoryId": 39,
    "subCategoryId": 201,
    "theme": [
      {
        "name": "ARC- Architecture",
        "itemThemeId": 84,
        "themeId": 39
      },
      {
        "name": "JP - Jewish Personalities",
        "itemThemeId": 85,
        "themeId": 10
      }
    ],
    "tag": [],
    "itemNote": [],
    "itemDocument": [],
    "journey": [
      {
        "name": "abc1234",
        "journeyId": 30,
        "itemJourneyId": 33,
        "url": "https:///1233.com"
      },
      {
        "name": "Great White Jail1",
        "journeyId": 6,
        "itemJourneyId": 34,
        "url": "http://uii.com"
      },
      {
        "name": "Herzl",
        "journeyId": 9,
        "itemJourneyId": 42,
        "url": "https://Herzl"
      },
      {
        "name": "Ya Basic! The Good Place <3",
        "journeyId": 23,
        "itemJourneyId": 43,
        "url": "https://youtu.be/fpFWPze_nIs"
      }
    ],
    "collection": [],
    "itemBetweenTheLine": [],
    "biography": [],
    "itemCost": null,
    "insuranceValue": null,
    "insuranceValueDate": "2019-05-15T13:00:00",
    "locationId": 21,
    "locationViewDate": "2019-05-14T18:30:00",
    "referenceNumber": null,
    "futureHandlingId": null,
    "dealerId": 62,
    "dealerCatalog": null,
    "dealerDate": "2019-05-14T18:30:00",
    "dealerLotNumber": null,
    "platformId": null,
    "itemRemarks": "<p>ssssssssssss test11696</p>\n",
    "itemStatusId": 2,
    "userId": 6,
    "shortTitle": "Richard",
    "previewText": "test preview text12",
    "websiteFilter": [
      13,
      15
    ],
    "marketingTag": [],
    "relatedItems": [],
    "relatedManus": [],
    "itemMetaTitle": "test",
    "itemMetaDescription": "test description",
    "itemFriendlyUrl": "https://www.youtube.com/watch?v=2F36ENlOggY&list=RD2F36ENlOggY&start_radio=1",
    "optimizedPageText": null,
    "optimizedPageTextDate": null,
    "optimizedPageTextUser": null,
    "optimizedPageTextUserName": "",
    "optimizedInternalLink": 3,
    "optimizedInternalLinkDate": "2019-11-22T18:00:16.9",
    "optimizedInternalLinkUser": 6,
    "optimizedInternalLinkUserName": "string",
    "seoStatus": 1,
    "seoStatusDate": "2019-08-30T11:06:00.873",
    "seoStatusUser": 6,
    "seoStatusUserName": "string",
    "marketingNotes": null,
    "previewWebsiteImageUrl": null,
    "wiki": null,
    "seo": null,
    "xcif": null,
    "country": null,
    "state": null,
    "city": null,
    "loggedInUser": 0,
    "category": "Architecture1",
    "subCategory": "Best Subcategory Eva!"
  },
  "message": null,
  "exception": null,
  "error": false,
  "result": 0,
  "extraData": null
}

@mtirion
Copy link

mtirion commented Jan 2, 2020

What happens when you do a JsonConvert in the method itself and return that as a string? Will that solve your problem?

@ericstj ericstj transferred this issue from dotnet/corefx Jan 9, 2020
@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added area-System.Text.Json untriaged New issue has not been triaged by the area owner labels Jan 9, 2020
@bergi9
Copy link

bergi9 commented Jan 21, 2020

This following code fails for me even when it's empty

class Test
{
    public IList<IFormFile> file { get; set; }
}

...

var str = JsonSerializer.Serialize(new Test());
System.NotSupportedException: The collection type 'Microsoft.AspNetCore.Http.IHeaderDictionary' on 'Microsoft.AspNetCore.Http.IFormFile.Headers' is not supported.
   at System.Text.Json.JsonClassInfo.GetElementType(Type propertyType, Type parentType, MemberInfo memberInfo, JsonSerializerOptions options)
   at System.Text.Json.JsonClassInfo.CreateProperty(Type declaredPropertyType, Type runtimePropertyType, Type implementedPropertyType, PropertyInfo propertyInfo, Type parentClassType, JsonConverter converter, JsonSerializerOptions options)
   at System.Text.Json.JsonClassInfo.AddProperty(Type propertyType, PropertyInfo propertyInfo, Type classType, JsonSerializerOptions options)
   at System.Text.Json.JsonClassInfo..ctor(Type type, JsonSerializerOptions options)
   at System.Text.Json.JsonSerializerOptions.GetOrAddClass(Type classType)
   at System.Text.Json.JsonPropertyInfo.get_ElementClassInfo()
   at System.Text.Json.JsonSerializer.Write(Utf8JsonWriter writer, Int32 originalWriterDepth, Int32 flushThreshold, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.JsonSerializer.WriteCore(Utf8JsonWriter writer, Object value, Type type, JsonSerializerOptions options)
   at System.Text.Json.JsonSerializer.WriteCore(PooledByteBufferWriter output, Object value, Type type, JsonSerializerOptions options)
   at System.Text.Json.JsonSerializer.WriteCoreString(Object value, Type type, JsonSerializerOptions options)
   at System.Text.Json.JsonSerializer.Serialize[TValue](TValue value, JsonSerializerOptions options)

@layomia layomia added this to the 5.0 milestone Feb 20, 2020
@layomia layomia removed the untriaged New issue has not been triaged by the area owner label Feb 20, 2020
@terenceng2010
Copy link

I don't have this issue anymore. The problem was caused by what I RETURNED from the Controller method instead of the parameter of the method.

For the input of the method I want to have the uploaded file IFormFile type, but also the meta data. So what I did was create a base class (CustomFile) with attributes like name and such. Then I created a subclass (UploadFile) that inherits from CustomFile and adds the IFormFile as a field.

As the standard method to implement this is the POST method, the standard return is CreatedAtAction("GetCustomFile", ...). What I did here before was return the UploadFile - and this causes the error. But I don't want to return the file to the client, but just the meta data (CustomFile). When I changed that, error was gone.

Does this help for you? I hope I explained it in a way you can understand it :)

This works for me. Basically the FileInfo that consists of the upload file should NOT be returned to the CreatedAtAction method.

@arham-anees
Copy link

I don't have this issue anymore. The problem was caused by what I RETURNED from the Controller method instead of the parameter of the method.

For the input of the method I want to have the uploaded file IFormFile type, but also the meta data. So what I did was create a base class (CustomFile) with attributes like name and such. Then I created a subclass (UploadFile) that inherits from CustomFile and adds the IFormFile as a field.

As the standard method to implement this is the POST method, the standard return is CreatedAtAction("GetCustomFile", ...). What I did here before was return the UploadFile - and this causes the error. But I don't want to return the file to the client, but just the meta data (CustomFile). When I changed that, error was gone.

Does this help for you? I hope I explained it in a way you can understand it :)

thanks, it helped me.
i was trying to upload file using IFormFile as paramter, process it and at the end send back to client.
during this process, the file uploaded successfully but response was coming with status code 500.
Visual studio thrown that "could not open file '...undefined'
After reading you comment, i just removed the file from response and gave a message in string and it return 200 status code.
may this help someone else too.
thanks again

@layomia
Copy link
Contributor

layomia commented Jul 31, 2020

The issue here is that the element type StringValues is currently not supported for deserialization as it doesn't have a public parameterless ctor. Serialization of this type is supported.

The serializer would need to implement a new convention where we check for ctors that take a T array (T[]). Moving to future as a custom converter can be written to handle this.

@layomia layomia modified the milestones: 5.0.0, 6.0.0 Jul 31, 2020
@binnetramesh
Copy link

binnetramesh commented Oct 16, 2020

The best way to resolve this while retrieving [Get] is to use the [JsonIgnore] attribute,

class FileModel
{
[JsonIgnore]
public List<IFormFile> file { get; set; }
}

@layomia layomia modified the milestones: 6.0.0, 7.0.0 Jul 22, 2021
@eiriktsarpalis
Copy link
Member

eiriktsarpalis commented Oct 15, 2021

The serializer would need to implement a new convention where we check for ctors that take a T array (T[]). Moving to future as a custom converter can be written to handle this.

Note that StringValues exposes two constructors. I don't see how we could resolve the inherent ambiguity here (unless we applied a JsonConstructor attribute on the definition of StringValues itself).

@eiriktsarpalis eiriktsarpalis changed the title System.Text.Json Headers Support serialization of Microsoft.Extensions.Primitives.StringValues Oct 15, 2021
MichalStrehovsky added a commit to MichalStrehovsky/runtime that referenced this issue Dec 9, 2021
This will better detect methods instantiated over unusable things.
@krwq krwq modified the milestones: 7.0.0, 8.0.0 Jul 7, 2022
@krwq
Copy link
Member

krwq commented Jul 7, 2022

Moving to 8.0 as we won't have time to fix this in 7.0 and there seem to be several workarounds for this

@ghost
Copy link

ghost commented Sep 28, 2022

Tagging subscribers to this area: @dotnet/area-extensions-primitives
See info in area-owners.md if you want to be subscribed.

Issue Details

I'm switching to System.Text.Json from Json.Net, and the following is no longer serializable:
Microsoft.AspNetCore.Http.FormFile

The exception is:

System.NotSupportedException : The collection type 'Microsoft.AspNetCore.Http.IHeaderDictionary' on 'Microsoft.AspNetCore.Http.FormFile.Headers' is not supported.`

Will this be supported? Are there any workarounds?

Author: joshmouch
Assignees: -
Labels:

area-System.Text.Json, area-Extensions-Primitives

Milestone: 8.0.0

@krwq
Copy link
Member

krwq commented Sep 28, 2022

We're moving this to Microsoft.Extensions.Primitives. We don't believe this is a good converter to add to System.Text.Json. Microsoft.Extensions.Primitives owner should consider adding JsonConverterAttribute on that class and provide converter. Otherwise it's a won't fix.

@tarekgh
Copy link
Member

tarekgh commented Sep 28, 2022

@krwq if there is enough demand for this, then it makes sense to provide the converter in System.Text.Json like other types supported there. If there is not enough demand for that, the provided workaround should be enough for users. right?

@ghost
Copy link

ghost commented Sep 28, 2022

Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis
See info in area-owners.md if you want to be subscribed.

Issue Details

I'm switching to System.Text.Json from Json.Net, and the following is no longer serializable:
Microsoft.AspNetCore.Http.FormFile

The exception is:

System.NotSupportedException : The collection type 'Microsoft.AspNetCore.Http.IHeaderDictionary' on 'Microsoft.AspNetCore.Http.FormFile.Headers' is not supported.`

Will this be supported? Are there any workarounds?

Author: joshmouch
Assignees: -
Labels:

area-System.Text.Json

Milestone: 8.0.0

@eiriktsarpalis
Copy link
Member

Both System.Text.Json and the Microsoft.Extensions.Primitives libraries target netstandard2.0, as such adding STJ support for StringValues would one way or another require one type to take dependency on the other. There is always the option of using a built-in converter that targets the type using reflection but that won't work well in source gen scenaria.

As already mentioned in this thread, we don't believe that this scenario is common enough to warrant OOTB support. Suggested workaround is writing a custom converter for StringValues.

@eiriktsarpalis eiriktsarpalis closed this as not planned Won't fix, can't repro, duplicate, stale Sep 28, 2022
@krwq
Copy link
Member

krwq commented Sep 29, 2022

If community is interested in us support this the right approach would be to create API suggestion with new library with JsonConverters and compile list of converters you'd like in there. If we were to support this as proposed here we'd need to take dependency just for this specific type or Microsoft.Extensions.Primitives.StringValues would need extra dependency on System.Text.Json which doesn't seem worth it.

@ghost ghost locked as resolved and limited conversation to collaborators Oct 29, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests