Skip to content

Commit 8bc0713

Browse files
committed
fix(): rollback enconding file
1 parent baab26d commit 8bc0713

16 files changed

+483
-244
lines changed

Storage/Bucket.cs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,48 @@
11
using System;
22
using System.Collections.Generic;
3-
using Newtonsoft.Json;
3+
using System.Text.Json.Serialization;
44

55
namespace Supabase.Storage
66
{
77
public class Bucket
88
{
9-
[JsonProperty("id")]
9+
[JsonPropertyName("id")]
1010
public string? Id { get; set; }
1111

12-
[JsonProperty("name")]
12+
[JsonPropertyName("name")]
1313
public string? Name { get; set; }
1414

15-
[JsonProperty("owner")]
15+
[JsonPropertyName("owner")]
1616
public string? Owner { get; set; }
1717

18-
[JsonProperty("created_at")]
18+
[JsonPropertyName("created_at")]
1919
public DateTime? CreatedAt { get; set; }
2020

21-
[JsonProperty("updated_at")]
21+
[JsonPropertyName("updated_at")]
2222
public DateTime? UpdatedAt { get; set; }
2323

2424
/// <summary>
2525
/// The visibility of the bucket. Public buckets don't require an authorization token to download objects,
2626
/// but still require a valid token for all other operations. By default, buckets are private.
2727
/// </summary>
28-
[JsonProperty("public")]
28+
[JsonPropertyName("public")]
2929
public bool Public { get; set; }
3030

3131
/// <summary>
3232
/// Specifies the file size limit that this bucket can accept during upload.
3333
///
3434
/// Expects a string value following a format like: '1kb', '50mb', '150kb', etc.
3535
/// </summary>
36-
[JsonProperty("file_size_limit", NullValueHandling = NullValueHandling.Include)]
36+
[JsonPropertyName("file_size_limit")]
3737
public string? FileSizeLimit { get; set; }
3838

3939
/// <summary>
4040
/// Specifies the allowed mime types that this bucket can accept during upload.
4141
///
4242
/// Expects a List of values such as: ['image/jpeg', 'image/png', etc]
4343
/// </summary>
44-
[JsonProperty("allowed_mime_types", NullValueHandling = NullValueHandling.Ignore)]
44+
[JsonPropertyName("allowed_mime_types")]
45+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
4546
public List<string>? AllowedMimes { get; set; }
4647
}
4748
}

Storage/BucketUpsertOptions.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
using System.Collections.Generic;
2-
using Newtonsoft.Json;
2+
using System.Text.Json.Serialization;
33

44
namespace Supabase.Storage
55
{
@@ -9,23 +9,24 @@ public class BucketUpsertOptions
99
/// The visibility of the bucket. Public buckets don't require an authorization token to download objects,
1010
/// but still require a valid token for all other operations. By default, buckets are private.
1111
/// </summary>
12-
[JsonProperty("public")]
12+
[JsonPropertyName("public")]
1313
public bool Public { get; set; } = false;
1414

1515
/// <summary>
1616
/// Specifies the file size limit that this bucket can accept during upload.
1717
///
1818
/// Expects a string value following a format like: '1kb', '50mb', '150kb', etc.
1919
/// </summary>
20-
[JsonProperty("file_size_limit", NullValueHandling = NullValueHandling.Include)]
20+
[JsonPropertyName("file_size_limit")]
2121
public string? FileSizeLimit { get; set; }
2222

2323
/// <summary>
2424
/// Specifies the allowed mime types that this bucket can accept during upload.
2525
///
2626
/// Expects a List of values such as: ['image/jpeg', 'image/png', etc]
2727
/// </summary>
28-
[JsonProperty("allowed_mime_types", NullValueHandling = NullValueHandling.Ignore)]
28+
[JsonPropertyName("allowed_mime_types")]
29+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
2930
public List<string>? AllowedMimes { get; set; }
3031
}
3132
}

Storage/CreateSignedUrlResponse.cs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,34 @@
1-
using Newtonsoft.Json;
1+
using System.Text.Json.Serialization;
22

33
namespace Supabase.Storage
44
{
5+
/// <summary>
6+
/// Represents the response received when creating a signed URL for file access through Supabase Storage.
7+
/// </summary>
58
public class CreateSignedUrlResponse
69
{
7-
[JsonProperty("signedURL")]
10+
/// <summary>
11+
/// Represents the signed URL returned as part of a response when requesting access to a file
12+
/// stored in Supabase Storage. This URL can be used to access the file directly with
13+
/// the defined expiration and optional transformations or download options applied.
14+
/// </summary>
15+
[JsonPropertyName("signedURL")]
816
public string? SignedUrl { get; set; }
917
}
1018

19+
/// <summary>
20+
/// Represents the extended response received when creating multiple signed URLs
21+
/// for file access through Supabase Storage. In addition to the signed URL, it includes
22+
/// the associated file path.
23+
/// </summary>
1124
public class CreateSignedUrlsResponse: CreateSignedUrlResponse
1225
{
13-
[JsonProperty("path")]
26+
/// <summary>
27+
/// Represents the file path associated with a signed URL in the response.
28+
/// This property indicates the specific file path for which the signed URL
29+
/// was generated, allowing identification of the file within the storage bucket.
30+
/// </summary>
31+
[JsonPropertyName("path")]
1432
public string? Path { get; set; }
1533
}
1634
}

Storage/DownloadOptions.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
using Newtonsoft.Json;
2-
31
namespace Supabase.Storage
42
{
3+
/// <summary>
4+
/// Represents options used when downloading files from storage.
5+
/// </summary>
56
public class DownloadOptions
67
{
78
/// <summary>

Storage/Extensions/HttpClientProgress.cs

Lines changed: 72 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22
using System.Collections.Generic;
33
using System.IO;
44
using System.Net.Http;
5+
using System.Text.Json;
56
using System.Threading;
67
using System.Threading.Tasks;
78
using BirdMessenger;
89
using BirdMessenger.Collections;
9-
using Newtonsoft.Json;
10+
using BirdMessenger.Delegates;
11+
using BirdMessenger.Infrastructure;
1012
using Supabase.Storage.Exceptions;
1113

1214
namespace Supabase.Storage.Extensions
@@ -45,7 +47,10 @@ public static async Task<MemoryStream> DownloadDataAsync(
4547
if (!response.IsSuccessStatusCode)
4648
{
4749
var content = await response.Content.ReadAsStringAsync();
48-
var errorResponse = JsonConvert.DeserializeObject<ErrorResponse>(content);
50+
var errorResponse = JsonSerializer.Deserialize<ErrorResponse>(
51+
content,
52+
Helpers.JsonOptions
53+
);
4954
var e = new SupabaseStorageException(errorResponse?.Message ?? content)
5055
{
5156
Content = content,
@@ -175,12 +180,15 @@ public static async Task<HttpResponseMessage> UploadAsync(
175180
}
176181
}
177182

178-
var response = await client.PostAsync(uri, content, cancellationToken);
183+
var response = await client.PostAsync(uri, content, cancellationToken);
179184

180185
if (!response.IsSuccessStatusCode)
181186
{
182187
var httpContent = await response.Content.ReadAsStringAsync();
183-
var errorResponse = JsonConvert.DeserializeObject<ErrorResponse>(httpContent);
188+
var errorResponse = JsonSerializer.Deserialize<ErrorResponse>(
189+
httpContent,
190+
Helpers.JsonOptions
191+
);
184192
var e = new SupabaseStorageException(errorResponse?.Message ?? httpContent)
185193
{
186194
Content = httpContent,
@@ -273,24 +281,26 @@ private static async Task<HttpResponseMessage> ResumableUploadAsync(
273281
UploadLength = fileStream.Length,
274282
};
275283

276-
var responseCreate = await client.TusCreateAsync(createOption, cancellationToken);
284+
TusCreateResponse? responseCreate;
285+
try
286+
{
287+
responseCreate = await client.TusCreateAsync(createOption, cancellationToken);
288+
}
289+
catch (Exception exception)
290+
{
291+
if (exception is not TusException response)
292+
throw;
293+
294+
throw await HandleResponseError(response);
295+
}
277296

278297
var patchOption = new TusPatchRequestOption
279298
{
280299
FileLocation = responseCreate.FileLocation,
281300
Stream = fileStream,
282301
UploadBufferSize = 6 * 1024 * 1024,
283302
UploadType = UploadType.Chunk,
284-
OnProgressAsync = x =>
285-
{
286-
if (progress == null)
287-
return Task.CompletedTask;
288-
289-
var uploadedProgress = (float)x.UploadedSize / x.TotalSize * 100f;
290-
progress.Report(uploadedProgress);
291-
292-
return Task.CompletedTask;
293-
},
303+
OnProgressAsync = x => ReportProgressAsync(progress, x),
294304
OnCompletedAsync = _ => Task.CompletedTask,
295305
OnFailedAsync = _ => Task.CompletedTask,
296306
};
@@ -300,19 +310,57 @@ private static async Task<HttpResponseMessage> ResumableUploadAsync(
300310
if (responsePatch.OriginResponseMessage.IsSuccessStatusCode)
301311
return responsePatch.OriginResponseMessage;
302312

303-
var httpContent = await responsePatch.OriginResponseMessage.Content.ReadAsStringAsync();
304-
var errorResponse = JsonConvert.DeserializeObject<ErrorResponse>(httpContent);
305-
var e = new SupabaseStorageException(errorResponse?.Message ?? httpContent)
313+
throw await HandleResponseError(responsePatch.OriginResponseMessage);
314+
}
315+
316+
private static Task ReportProgressAsync(
317+
IProgress<float>? progress,
318+
UploadProgressEvent progressInfo
319+
)
320+
{
321+
if (progress == null)
322+
return Task.CompletedTask;
323+
324+
var uploadedProgress = (float)progressInfo.UploadedSize / progressInfo.TotalSize * 100f;
325+
progress.Report(uploadedProgress);
326+
327+
return Task.CompletedTask;
328+
}
329+
330+
private static async Task<SupabaseStorageException> HandleResponseError(
331+
HttpResponseMessage response
332+
)
333+
{
334+
var httpContent = await response.Content.ReadAsStringAsync();
335+
var errorResponse = JsonSerializer.Deserialize<ErrorResponse>(
336+
httpContent,
337+
Helpers.JsonOptions
338+
);
339+
var error = new SupabaseStorageException(errorResponse?.Message ?? httpContent)
340+
{
341+
Content = httpContent,
342+
Response = response,
343+
StatusCode = errorResponse?.StatusCode ?? (int)response.StatusCode,
344+
};
345+
error.AddReason();
346+
347+
return error;
348+
}
349+
350+
private static async Task<SupabaseStorageException> HandleResponseError(
351+
TusException response
352+
)
353+
{
354+
var httpContent = await response.OriginHttpResponse.Content.ReadAsStringAsync();
355+
var error = new SupabaseStorageException(httpContent)
306356
{
307357
Content = httpContent,
308-
Response = responsePatch.OriginResponseMessage,
309-
StatusCode =
310-
errorResponse?.StatusCode
311-
?? (int)responsePatch.OriginResponseMessage.StatusCode,
358+
Response = response.OriginHttpResponse,
359+
StatusCode = (int)response.OriginHttpResponse.StatusCode,
312360
};
361+
error.AddReason();
313362

314-
e.AddReason();
315-
throw e;
363+
return error;
316364
}
317365
}
318366
}

Storage/FileObject.cs

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3-
using Newtonsoft.Json;
3+
using System.Text.Json.Serialization;
44

55
namespace Supabase.Storage
66
{
@@ -10,32 +10,23 @@ public class FileObject
1010
/// Flag representing if this object is a folder, all properties will be null but the name
1111
/// </summary>
1212
public bool IsFolder => !string.IsNullOrEmpty(Name) && Id == null && CreatedAt == null && UpdatedAt == null;
13-
14-
[JsonProperty("name")]
15-
public string? Name { get; set; }
1613

17-
[JsonProperty("bucket_id")]
18-
public string? BucketId { get; set; }
14+
[JsonPropertyName("name")] public string? Name { get; set; }
1915

20-
[JsonProperty("owner")]
21-
public string? Owner { get; set; }
16+
[JsonPropertyName("bucket_id")] public string? BucketId { get; set; }
2217

23-
[JsonProperty("id")]
24-
public string? Id { get; set; }
18+
[JsonPropertyName("owner")] public string? Owner { get; set; }
2519

26-
[JsonProperty("updated_at")]
27-
public DateTime? UpdatedAt { get; set; }
20+
[JsonPropertyName("id")] public string? Id { get; set; }
2821

29-
[JsonProperty("created_at")]
30-
public DateTime? CreatedAt { get; set; }
22+
[JsonPropertyName("updated_at")] public DateTime? UpdatedAt { get; set; }
3123

32-
[JsonProperty("last_accessed_at")]
33-
public DateTime? LastAccessedAt { get; set; }
24+
[JsonPropertyName("created_at")] public DateTime? CreatedAt { get; set; }
3425

35-
[JsonProperty("metadata")]
36-
public Dictionary<string, object> MetaData = new Dictionary<string, object>();
26+
[JsonPropertyName("last_accessed_at")] public DateTime? LastAccessedAt { get; set; }
3727

38-
[JsonProperty("buckets")]
39-
public Bucket? Buckets { get; set; }
28+
[JsonPropertyName("metadata")] public Dictionary<string, object> MetaData = new Dictionary<string, object>();
29+
30+
[JsonPropertyName("buckets")] public Bucket? Buckets { get; set; }
4031
}
41-
}
32+
}

0 commit comments

Comments
 (0)