Как я могу получить точку с сервера SQL с C#? - PullRequest
0 голосов
/ 14 июля 2020

Я использую пространственный тип данных на моем sql сервере, и я хочу получить эти данные с моего sql сервера в свой класс сущностей, он возвращает ошибку ". NET числовые значения, такие как положительная и отрицательная бесконечности не могут быть записаны как действительные JSON. ", когда я пытаюсь получить значение из моей базы данных.

Координаты - это значение, которое я хочу вернуть из своей базы данных. Я использую тип данных Geography из NetTopologySuite и вставляю точку из моего класса сущности.

enter image description here

The class code that i'm using:

public class Address : EntityBase
{
    public Address () {}

    public Address(string district, string street, int number, string complement, string zipCode, 
    string cityDescription, string stateDescription, Point coordinates, int countryId, byte stateId, int cityId)
    {
        District = district;
        Street = street;
        Number = number;
        Complement = complement;
        ZipCode = zipCode;
        CityDescription = cityDescription;
        StateDescription = stateDescription;
        Coordinates = coordinates;
        CountryId = countryId;
        StateId = stateId;
        CityId = cityId;
    }

    public string District { get; set; }
    public string Street { get; set; }
    public int Number { get; set; }
    public string Complement { get; set; }
    public string ZipCode { get; set; }
    public string CityDescription { get; set; }
    public string StateDescription { get; set; }
    public virtual Point Coordinates { get; set; }
    public int CountryId { get; set; }
    public byte StateId { get; set; }
    public int CityId { get; set; }
    public int? CustomerId { get; set; }
    public int? StoreId { get; set; }
    public int? ProfessionalId { get; set; }
}

And the sql server code for the table:

CREATE TABLE Address(
    Id INT PRIMARY KEY IDENTITY(1, 1),
    District VARCHAR(50) NOT NULL, -- Bairro
    Street VARCHAR(100) NOT NULL, -- Rua
    --Description VARCHAR(100) NOT NULL,
    Number INT,
    Complement VARCHAR(100),
    ZipCode VARCHAR(20) NOT NULL,
    CityDescription VARCHAR(100),
    StateDescription VARCHAR(100),
    Coordinates GEOGRAPHY,
    
    CountryId INT FOREIGN KEY REFERENCES Country(Id) NOT NULL,
    StateId TINYINT FOREIGN KEY REFERENCES State(Id),
    CityId INT FOREIGN KEY REFERENCES City(Id),
    CustomerId INT FOREIGN KEY REFERENCES Customer(Id),
    StoreId INT FOREIGN KEY REFERENCES Store(Id),
    ProfessionalId INT FOREIGN KEY REFERENCES Professional(Id),

    INDEX IndexAddressCountryId NONCLUSTERED (CountryId),
    INDEX IndexAddressStateId NONCLUSTERED (StateId),
    INDEX IndexAddressCityId NONCLUSTERED (CityId),
    INDEX IndexAddressCustomerId NONCLUSTERED (CustomerId),
    INDEX IndexAddressStoreId NONCLUSTERED (StoreId),
    INDEX IndexAddressProfessionalId NONCLUSTERED (ProfessionalId)
)

Is there any method to retrieve the Point value from this? Like a configuration on function OnModelCreating or something else? Can I only retrieve the longitude and latitude from it?

I'm new to Spacial Data so I don't know much about it. Thanks in advance for helping me :)


Edit 1:

Here's the exception error that i get:

введите описание изображения здесь

EntityBase:

namespace CodenApp.Framework.Core.Entities
{
    public abstract class EntityBase<T>
    {
        public T Id { get; set; }
    }
}

И две функции, которые я использую для обработки исключений:

public async Task InvokeAsync(HttpContext httpContext)
{
    try
    {
        await _next(httpContext);
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, ex.ToString());                
        await HandleExceptionAsync(httpContext, ex);
    }
}


protected override Task HandleExceptionAsync(HttpContext context, Exception exception)
{
    if(context == null)
        throw new ArgumentNullException(nameof(context));
    if(exception == null)
        throw new ArgumentNullException(nameof(exception));

    context.Response.ContentType = "application/json";
    context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
    return context.Response.WriteAsync(ApiCatch.Log(exception).ToString());
}

Код, который я использовал для преобразования в Point:

public static Point ConvertToGeometry(string coordinatesAux)
{
    if(coordinatesAux == null)
        throw new NullReferenceException();

    NumberFormatInfo formatProvider = new NumberFormatInfo();
    formatProvider.NumberGroupSeparator = ".";
            
    var currentLocation = new Point(new Coordinate(
                                        Convert.ToDouble(coordinatesAux.Substring(0, coordinatesAux.IndexOf(",")), formatProvider), 
                                        Convert.ToDouble(coordinatesAux.Substring(coordinatesAux.IndexOf(",") + 1), formatProvider))) { SRID = 4326 };
            
    return currentLocation;                                                            
}

1 Ответ

0 голосов
/ 14 июля 2020

Как Панайотис Канавос сказал в комментариях, для решения этой ситуации мне нужно было добавить пакет NuGet NetTopologySuite.IO.GeoJSON4STJ и изменить файл Startup.cs, чтобы получить изменения задано пакетом.

Изменения в Startup.cs внутри функции ConfigureServices:

services.AddControllers(options =>
{
    options.ModelMetadataDetailsProviders.Add(new SuppressChildValidationMetadataProvider(typeof(Point))); 
    options.ModelMetadataDetailsProviders.Add(new SuppressChildValidationMetadataProvider(typeof(Coordinate))); 
    options.ModelMetadataDetailsProviders.Add(new SuppressChildValidationMetadataProvider(typeof(LineString))); 
    options.ModelMetadataDetailsProviders.Add(new SuppressChildValidationMetadataProvider(typeof(MultiLineString))); 
});

services.AddControllers().AddJsonOptions(options =>
{
    var geoJsonConverterFactory = new GeoJsonConverterFactory();
    options.JsonSerializerOptions.Converters.Add(geoJsonConverterFactory);
});

services.AddSingleton(NtsGeometryServices.Instance);

И добавлены IOptions в мой контроллер:

private readonly IOptions<JsonOptions> _jsonOptions;
public StoreController(IAsyncRepository<Store, int> repository, StoreHandler handler, IOptions<JsonOptions> jsonOptions) : base(repository)
{
    _handler = handler;
    _orders = new Expression<Func<Store, object>>[] { x => x.Id };
    _jsonOptions = jsonOptions;
}

Так учат в этом вики .

...