Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
ismcagdas committed Feb 16, 2024
2 parents b82d343 + ccd7a1d commit 65ae7e7
Show file tree
Hide file tree
Showing 6 changed files with 201 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ public override DateOnly Read(ref Utf8JsonReader reader, Type typeToConvert, Jso
}
}

if (DateOnly.TryParse(reader.GetString(), CultureInfo.CurrentUICulture, out var date))
{
return date;
}

return default;
}

Expand Down
23 changes: 17 additions & 6 deletions src/Abp/Json/SystemTextJson/AbpDateTimeConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,10 @@ public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, Jso
}
}

if (reader.TryGetDateTime(out var dateTime))
var dateText = reader.GetString();
if (DateTime.TryParse(dateText, CultureInfo.CurrentUICulture, DateTimeStyles.None, out var date))
{
return Clock.Normalize(dateTime);
return Clock.Normalize(date);
}

throw new JsonException("Can't get datetime from the reader!");
Expand Down Expand Up @@ -73,15 +74,19 @@ public AbpNullableDateTimeConverter(List<string> inputDateTimeFormats = null, st
InputDateTimeFormats = inputDateTimeFormats ?? new List<string>();
OutputDateTimeFormat = outputDateTimeFormat;
}



public override DateTime? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (!InputDateTimeFormats.IsNullOrEmpty())
{
if (reader.TokenType == JsonTokenType.String)
{
var s = reader.GetString();
if (s.IsNullOrEmpty())
{
return null;
}

foreach (var format in InputDateTimeFormats)
{
if (DateTime.TryParseExact(s, format, CultureInfo.CurrentUICulture, DateTimeStyles.None, out var outDateTime))
Expand All @@ -96,9 +101,15 @@ public AbpNullableDateTimeConverter(List<string> inputDateTimeFormats = null, st
}
}

if (reader.TryGetDateTime(out var dateTime))
var dateText = reader.GetString();
if (dateText.IsNullOrEmpty())
{
return null;
}

if (DateTime.TryParse(dateText, CultureInfo.CurrentUICulture, DateTimeStyles.None, out var date))
{
return Clock.Normalize(dateTime);
return Clock.Normalize(date);
}

return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,26 @@ public CalculatePriceOutput CalculatePrice(CalculatePriceDto input)
OrderDate = input.OrderDate.ToString(),
};
}

public string TestDate(TestDateDto input)
{
return input.TestDate.ToString();
}

public string NullableTestDate(NullableTestDateDto input)
{
if (!input.TestDate.HasValue)
{
return string.Empty;
}

return input.TestDate.ToString();
}

public string DateOnlyTestDate(DateOnlyTestDateDateDto input)
{
return input.TestDate.ToString();
}
}

public class CalculatePriceDto
Expand All @@ -32,4 +52,19 @@ public class CalculatePriceOutput

public string Culture { get; set; }
}

public class TestDateDto
{
public DateTime TestDate { get; set; }
}

public class NullableTestDateDto
{
public DateTime? TestDate { get; set; }
}

public class DateOnlyTestDateDateDto
{
public DateOnly TestDate { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
using System.Net.Http;
using System.Net.Http.Json;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Abp.Web.Models;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Net.Http.Headers;
using Shouldly;
using Xunit;
using JsonSerializer = System.Text.Json.JsonSerializer;

namespace AbpAspNetCoreDemo.IntegrationTests.Tests;

public class DateTimeFormatterControllerTests : IClassFixture<WebApplicationFactory<Startup>>
{
private readonly WebApplicationFactory<Startup> _factory;
private const string BaseUrl = "/api/date-time-format/";

public DateTimeFormatterControllerTests(WebApplicationFactory<Startup> factory)
{
_factory = factory;
}

[Theory]
[InlineData("tr", "14.02.2024")]
[InlineData("en-US", "2/14/2024")]
[InlineData("en-GB", "14/02/2024")]
public async Task DateTimeFormat_Controller_Test(string culture, string datetime)
{
var client = _factory.CreateClient();

// Arrange
client.DefaultRequestHeaders.Add(HeaderNames.AcceptLanguage, culture);
var content = new StringContent("{\"TestDate\": \"" + datetime + "\" }", Encoding.UTF8, "application/json");

// Act
var response = await client.PostAsync("/api/services/app/ModelBinding/TestDate", content);

// Assert
response.EnsureSuccessStatusCode();
var responseContent = await response.Content.ReadAsStringAsync();
var output = JsonSerializer.Deserialize<AjaxResponse<string>>(responseContent, new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
});

output.Result.Substring(0, datetime.Length).ShouldBe(datetime);
}

[Theory]
[InlineData("tr", "14.02.2024")]
[InlineData("en-US", "2/14/2024")]
[InlineData("en-GB", "14/02/2024")]
public async Task DateTimeFormat_Controller_Nullable_Test(string culture, string datetime)
{
var client = _factory.CreateClient();

// Arrange
client.DefaultRequestHeaders.Add(HeaderNames.AcceptLanguage, culture);
var content = new StringContent("{\"TestDate\": \"" + datetime + "\" }", Encoding.UTF8, "application/json");

// Act
var response = await client.PostAsync("/api/services/app/ModelBinding/NullableTestDate", content);

// Assert
response.EnsureSuccessStatusCode();
var responseContent = await response.Content.ReadAsStringAsync();
var output = JsonSerializer.Deserialize<AjaxResponse<string>>(responseContent, new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
});

output.Result.Substring(0, datetime.Length).ShouldBe(datetime);
}

[Theory]
[InlineData("tr", "14.02.2024")]
[InlineData("en-US", "2/14/2024")]
[InlineData("en-GB", "14/02/2024")]
public async Task DateTimeFormat_Controller_DateOnly_Test(string culture, string datetime)
{
var client = _factory.CreateClient();

// Arrange
client.DefaultRequestHeaders.Add(HeaderNames.AcceptLanguage, culture);
var content = new StringContent("{\"TestDate\": \"" + datetime + "\" }", Encoding.UTF8, "application/json");

// Act
var response = await client.PostAsync("/api/services/app/ModelBinding/DateOnlyTestDate", content);

// Assert
response.EnsureSuccessStatusCode();
var responseContent = await response.Content.ReadAsStringAsync();
var output = JsonSerializer.Deserialize<AjaxResponse<string>>(responseContent, new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
});

output.Result.Substring(0, datetime.Length).ShouldBe(datetime);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System;
using Abp.Application.Services.Dto;
using Microsoft.AspNetCore.Mvc;

namespace AbpAspNetCoreDemo.Controllers
{
public class DateTimeFormatController : DemoControllerBase
{
[Route("api/date-time-format/test")]
[HttpPost]
public string TestGetArray(TestInputDto model)
{
return model.TestDate.ToString("yyyy-MM-dd");
}

public class TestInputDto : EntityDto
{
public DateTime TestDate { get; set; }
}
}
}
29 changes: 21 additions & 8 deletions test/aspnet-core-demo/AbpAspNetCoreDemo/Startup.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Threading;
using Abp.AspNetCore;
using Abp.AspNetCore.Configuration;
Expand Down Expand Up @@ -73,14 +74,26 @@ public IServiceProvider ConfigureServices(IServiceCollection services)
opts.AddRouteComponents("odata", edmModel);
});

services.Configure<JsonOptions>(options =>
{
options.JsonSerializerOptions.Converters.Add(new CultureInvariantDecimalJsonConverter());
options.JsonSerializerOptions.Converters.Add(new CultureInvariantNullableDecimalJsonConverter());
options.JsonSerializerOptions.Converters.Add(new CultureInvariantDoubleJsonConverter());
options.JsonSerializerOptions.Converters.Add(new CultureInvariantNullableDoubleJsonConverter());
options.JsonSerializerOptions.Converters.Add(new Abp.Json.SystemTextJson.DateOnlyJsonConverter());
});
services.AddOptions<JsonOptions>()
.Configure<IServiceProvider>((options, rootServiceProvider) =>
{
options.JsonSerializerOptions.ReadCommentHandling = JsonCommentHandling.Skip;
options.JsonSerializerOptions.AllowTrailingCommas = true;
options.JsonSerializerOptions.Converters.Add(new AbpStringToEnumFactory());
options.JsonSerializerOptions.Converters.Add(new AbpStringToBooleanConverter());
options.JsonSerializerOptions.Converters.Add(new AbpStringToGuidConverter());
options.JsonSerializerOptions.Converters.Add(new AbpNullableStringToGuidConverter());
options.JsonSerializerOptions.Converters.Add(new AbpNullableFromEmptyStringConverterFactory());
options.JsonSerializerOptions.Converters.Add(new ObjectToInferredTypesConverter());
options.JsonSerializerOptions.Converters.Add(new Abp.Json.SystemTextJson.DateOnlyJsonConverter());
options.JsonSerializerOptions.Converters.Add(new CultureInvariantDecimalJsonConverter());
options.JsonSerializerOptions.Converters.Add(new CultureInvariantDoubleJsonConverter());
var aspNetCoreConfiguration = rootServiceProvider.GetRequiredService<IAbpAspNetCoreConfiguration>();
options.JsonSerializerOptions.TypeInfoResolver = new AbpDateTimeJsonTypeInfoResolver(aspNetCoreConfiguration.InputDateTimeFormats, aspNetCoreConfiguration.OutputDateTimeFormat);
});

services.Configure<MvcOptions>(x => x.AddAbpHtmlSanitizer());

Expand Down

0 comments on commit 65ae7e7

Please sign in to comment.