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

int64/long support #12

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions samples/WebApi/Controllers/FruitsController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using AspNetCore.Hashids.Mvc;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Linq;
using System.Net.Mime;
using WebApi.Model;

namespace WebApi.Controllers
{
[Route("api/fruits")]
[ApiController]
public class FruitsController : ControllerBase
{
private static readonly IEnumerable<FruitDto> fruits = new FruitDto[]
{
new FruitDto
{
Id = long.MaxValue,
NonHashid = 10000,
NullableId = 66666,
Name = "Apple"
},
new FruitDto
{
Id = 8888,
NonHashid = 20000,
Name = "Banana"
}
};

[HttpGet]
[Route("")]
[Produces(MediaTypeNames.Application.Json)]
public ActionResult<IEnumerable<FruitDto>> Get()
{
return Ok(fruits);
}

[HttpGet]
[Route("{id:hashids}")]
[Produces(MediaTypeNames.Application.Json)]
public ActionResult<FruitDto> Get(
[FromRoute][ModelBinder(typeof(HashidsModelBinder))] long id)
{
return Ok(fruits.SingleOrDefault(c => c.Id == id));
}
}
}
15 changes: 15 additions & 0 deletions samples/WebApi/Model/FruitDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System.Text.Json.Serialization;
using AspNetCore.Hashids.Json;

namespace WebApi.Model
{
public class FruitDto
{
[JsonConverter(typeof(LongHashidsJsonConverter))]
public long Id { get; set; }
[JsonConverter(typeof(NullableLongHashidsJsonConverter))]
public long? NullableId { get; set; }
public long NonHashid { get; set; }
public string Name { get; set; }
}
}
59 changes: 59 additions & 0 deletions src/AspNetCore.Hashids/Json/LongHashidsJsonConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using AspNetCore.Hashids.Options;
using HashidsNet;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace AspNetCore.Hashids.Json
{
public class LongHashidsJsonConverter : JsonConverter<long>
{
public override long Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.String)
{
var stringValue = reader.GetString();

var hashid = GetHashids(options)
.DecodeLong(stringValue);

if (hashid.Length == 0)
{
throw new JsonException("Invalid hash.");
}

return hashid[0];
}
else if (reader.TokenType == JsonTokenType.Number)
{
if ( GetHashIdOptions(options).AcceptNonHashedIds)
{
return reader.GetInt64();
}

throw new JsonException(@$"Element is decorated with {nameof(HashidsJsonConverter)}
but is reading a non hashed id. To allow deserialize numbers set AcceptNonHashedIds to true.");
}

throw new JsonException();
}


public override void Write(Utf8JsonWriter writer, long value, JsonSerializerOptions options)
{
writer.WriteStringValue(
GetHashids(options).EncodeLong(value));
}

private IHashids GetHashids(JsonSerializerOptions options)
{
return options.GetServiceProvider().GetRequiredService<IHashids>();
}

private HashidsOptions GetHashIdOptions(JsonSerializerOptions options)
{
return options.GetServiceProvider().GetRequiredService<HashidsOptions>();
}
}
}
47 changes: 47 additions & 0 deletions src/AspNetCore.Hashids/Json/NullableLongHashidsJsonConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using HashidsNet;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace AspNetCore.Hashids.Json
{
public class NullableLongHashidsJsonConverter : JsonConverter<long?>
{
public override long? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.String)
{
var stringValue = reader.GetString();
var hashid = GetHashids(options).Decode(stringValue);

if (hashid.Length == 0)
{
throw new JsonException("Invalid hash.");
}

return hashid[0];
}
else if (reader.TokenType == JsonTokenType.Number)
{
return reader.GetInt64();
}

throw new JsonException();
}


public override void Write(Utf8JsonWriter writer, long? value, JsonSerializerOptions options)
{
if (value.HasValue)
{
writer.WriteStringValue(GetHashids(options).EncodeLong(value.Value));
}
}

private IHashids GetHashids(JsonSerializerOptions options)
{
return options.GetServiceProvider().GetRequiredService<IHashids>();
}
}
}
24 changes: 19 additions & 5 deletions src/AspNetCore.Hashids/Mvc/HashidsModelBinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,28 @@ public Task BindModelAsync(ModelBindingContext bindingContext)
return Task.CompletedTask;
}

var ids = hashids.Decode(value);
if (bindingContext.ModelMetadata.ModelType == typeof(long))
{
var ids = hashids.DecodeLong(value);

if (ids.Length == 0)
{
return Task.CompletedTask;
}

if (ids.Length == 0)
bindingContext.Result = ModelBindingResult.Success(ids.First());
} else
{
return Task.CompletedTask;
}
var ids = hashids.Decode(value);

if (ids.Length == 0)
{
return Task.CompletedTask;
}

bindingContext.Result = ModelBindingResult.Success(ids.First());
bindingContext.Result = ModelBindingResult.Success(ids.First());
}


return Task.CompletedTask;
}
Expand Down