Merge pull request #753 from hargata/Hargata/752
Allow for JSON Body in POST/PUT API Methods
This commit is contained in:
@@ -126,7 +126,14 @@ namespace CarCareTracker.Controllers
|
||||
}
|
||||
|
||||
var apiResult = _vehicleLogic.GetVehicleInfo(vehicles);
|
||||
return Json(apiResult);
|
||||
if (_config.GetInvariantApi() || Request.Headers.ContainsKey("culture-invariant"))
|
||||
{
|
||||
return Json(apiResult, StaticHelper.GetInvariantOption());
|
||||
}
|
||||
else
|
||||
{
|
||||
return Json(apiResult);
|
||||
}
|
||||
}
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpGet]
|
||||
@@ -157,11 +164,22 @@ namespace CarCareTracker.Controllers
|
||||
}
|
||||
var vehicleRecords = _serviceRecordDataAccess.GetServiceRecordsByVehicleId(vehicleId);
|
||||
var result = vehicleRecords.Select(x => new GenericRecordExportModel { Id = x.Id.ToString(), Date = x.Date.ToShortDateString(), Description = x.Description, Cost = x.Cost.ToString(), Notes = x.Notes, Odometer = x.Mileage.ToString(), ExtraFields = x.ExtraFields });
|
||||
return Json(result);
|
||||
if (_config.GetInvariantApi() || Request.Headers.ContainsKey("culture-invariant"))
|
||||
{
|
||||
return Json(result, StaticHelper.GetInvariantOption());
|
||||
} else
|
||||
{
|
||||
return Json(result);
|
||||
}
|
||||
}
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpPost]
|
||||
[Route("/api/vehicle/servicerecords/add")]
|
||||
[Consumes("application/json")]
|
||||
public IActionResult AddServiceRecordJson(int vehicleId, [FromBody] GenericRecordExportModel input) => AddServiceRecord(vehicleId, input);
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpPost]
|
||||
[Route("/api/vehicle/servicerecords/add")]
|
||||
public IActionResult AddServiceRecord(int vehicleId, GenericRecordExportModel input)
|
||||
{
|
||||
if (vehicleId == default)
|
||||
@@ -213,6 +231,10 @@ namespace CarCareTracker.Controllers
|
||||
}
|
||||
[HttpPut]
|
||||
[Route("/api/vehicle/servicerecords/update")]
|
||||
[Consumes("application/json")]
|
||||
public IActionResult UpdateServiceRecordJson([FromBody] GenericRecordExportModel input) => UpdateServiceRecord(input);
|
||||
[HttpPut]
|
||||
[Route("/api/vehicle/servicerecords/update")]
|
||||
public IActionResult UpdateServiceRecord(GenericRecordExportModel input)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(input.Id) ||
|
||||
@@ -273,11 +295,23 @@ namespace CarCareTracker.Controllers
|
||||
}
|
||||
var vehicleRecords = _collisionRecordDataAccess.GetCollisionRecordsByVehicleId(vehicleId);
|
||||
var result = vehicleRecords.Select(x => new GenericRecordExportModel { Id = x.Id.ToString(), Date = x.Date.ToShortDateString(), Description = x.Description, Cost = x.Cost.ToString(), Notes = x.Notes, Odometer = x.Mileage.ToString(), ExtraFields = x.ExtraFields });
|
||||
return Json(result);
|
||||
if (_config.GetInvariantApi() || Request.Headers.ContainsKey("culture-invariant"))
|
||||
{
|
||||
return Json(result, StaticHelper.GetInvariantOption());
|
||||
}
|
||||
else
|
||||
{
|
||||
return Json(result);
|
||||
}
|
||||
}
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpPost]
|
||||
[Route("/api/vehicle/repairrecords/add")]
|
||||
[Consumes("application/json")]
|
||||
public IActionResult AddRepairRecordJson(int vehicleId, [FromBody] GenericRecordExportModel input) => AddRepairRecord(vehicleId, input);
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpPost]
|
||||
[Route("/api/vehicle/repairrecords/add")]
|
||||
public IActionResult AddRepairRecord(int vehicleId, GenericRecordExportModel input)
|
||||
{
|
||||
if (vehicleId == default)
|
||||
@@ -329,6 +363,10 @@ namespace CarCareTracker.Controllers
|
||||
}
|
||||
[HttpPut]
|
||||
[Route("/api/vehicle/repairrecords/update")]
|
||||
[Consumes("application/json")]
|
||||
public IActionResult UpdateRepairRecordJson([FromBody] GenericRecordExportModel input) => UpdateRepairRecord(input);
|
||||
[HttpPut]
|
||||
[Route("/api/vehicle/repairrecords/update")]
|
||||
public IActionResult UpdateRepairRecord(GenericRecordExportModel input)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(input.Id) ||
|
||||
@@ -390,11 +428,23 @@ namespace CarCareTracker.Controllers
|
||||
}
|
||||
var vehicleRecords = _upgradeRecordDataAccess.GetUpgradeRecordsByVehicleId(vehicleId);
|
||||
var result = vehicleRecords.Select(x => new GenericRecordExportModel { Id = x.Id.ToString(), Date = x.Date.ToShortDateString(), Description = x.Description, Cost = x.Cost.ToString(), Notes = x.Notes, Odometer = x.Mileage.ToString(), ExtraFields = x.ExtraFields });
|
||||
return Json(result);
|
||||
if (_config.GetInvariantApi() || Request.Headers.ContainsKey("culture-invariant"))
|
||||
{
|
||||
return Json(result, StaticHelper.GetInvariantOption());
|
||||
}
|
||||
else
|
||||
{
|
||||
return Json(result);
|
||||
}
|
||||
}
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpPost]
|
||||
[Route("/api/vehicle/upgraderecords/add")]
|
||||
[Consumes("application/json")]
|
||||
public IActionResult AddUpgradeRecordJson(int vehicleId, [FromBody] GenericRecordExportModel input) => AddUpgradeRecord(vehicleId, input);
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpPost]
|
||||
[Route("/api/vehicle/upgraderecords/add")]
|
||||
public IActionResult AddUpgradeRecord(int vehicleId, GenericRecordExportModel input)
|
||||
{
|
||||
if (vehicleId == default)
|
||||
@@ -446,6 +496,10 @@ namespace CarCareTracker.Controllers
|
||||
}
|
||||
[HttpPut]
|
||||
[Route("/api/vehicle/upgraderecords/update")]
|
||||
[Consumes("application/json")]
|
||||
public IActionResult UpdateUpgradeRecordJson([FromBody] GenericRecordExportModel input) => UpdateUpgradeRecord(input);
|
||||
[HttpPut]
|
||||
[Route("/api/vehicle/upgraderecords/update")]
|
||||
public IActionResult UpdateUpgradeRecord(GenericRecordExportModel input)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(input.Id) ||
|
||||
@@ -506,11 +560,23 @@ namespace CarCareTracker.Controllers
|
||||
return Json(response);
|
||||
}
|
||||
var result = _taxRecordDataAccess.GetTaxRecordsByVehicleId(vehicleId).Select(x => new TaxRecordExportModel { Id = x.Id.ToString(), Date = x.Date.ToShortDateString(), Description = x.Description, Cost = x.Cost.ToString(), Notes = x.Notes, ExtraFields = x.ExtraFields });
|
||||
return Json(result);
|
||||
if (_config.GetInvariantApi() || Request.Headers.ContainsKey("culture-invariant"))
|
||||
{
|
||||
return Json(result, StaticHelper.GetInvariantOption());
|
||||
}
|
||||
else
|
||||
{
|
||||
return Json(result);
|
||||
}
|
||||
}
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpPost]
|
||||
[Route("/api/vehicle/taxrecords/add")]
|
||||
[Consumes("application/json")]
|
||||
public IActionResult AddTaxRecordJson(int vehicleId, [FromBody] TaxRecordExportModel input) => AddTaxRecord(vehicleId, input);
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpPost]
|
||||
[Route("/api/vehicle/taxrecords/add")]
|
||||
public IActionResult AddTaxRecord(int vehicleId, TaxRecordExportModel input)
|
||||
{
|
||||
if (vehicleId == default)
|
||||
@@ -550,6 +616,10 @@ namespace CarCareTracker.Controllers
|
||||
}
|
||||
[HttpPut]
|
||||
[Route("/api/vehicle/taxrecords/update")]
|
||||
[Consumes("application/json")]
|
||||
public IActionResult UpdateTaxRecordJson([FromBody] TaxRecordExportModel input) => UpdateTaxRecord(input);
|
||||
[HttpPut]
|
||||
[Route("/api/vehicle/taxrecords/update")]
|
||||
public IActionResult UpdateTaxRecord(TaxRecordExportModel input)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(input.Id) ||
|
||||
@@ -628,11 +698,23 @@ namespace CarCareTracker.Controllers
|
||||
vehicleRecords = _odometerLogic.AutoConvertOdometerRecord(vehicleRecords);
|
||||
}
|
||||
var result = vehicleRecords.Select(x => new OdometerRecordExportModel { Id = x.Id.ToString(), Date = x.Date.ToShortDateString(), InitialOdometer = x.InitialMileage.ToString(), Odometer = x.Mileage.ToString(), Notes = x.Notes, ExtraFields = x.ExtraFields });
|
||||
return Json(result);
|
||||
if (_config.GetInvariantApi() || Request.Headers.ContainsKey("culture-invariant"))
|
||||
{
|
||||
return Json(result, StaticHelper.GetInvariantOption());
|
||||
}
|
||||
else
|
||||
{
|
||||
return Json(result);
|
||||
}
|
||||
}
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpPost]
|
||||
[Route("/api/vehicle/odometerrecords/add")]
|
||||
[Consumes("application/json")]
|
||||
public IActionResult AddOdometerRecordJson(int vehicleId, [FromBody] OdometerRecordExportModel input) => AddOdometerRecord(vehicleId, input);
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpPost]
|
||||
[Route("/api/vehicle/odometerrecords/add")]
|
||||
public IActionResult AddOdometerRecord(int vehicleId, OdometerRecordExportModel input)
|
||||
{
|
||||
if (vehicleId == default)
|
||||
@@ -669,6 +751,10 @@ namespace CarCareTracker.Controllers
|
||||
}
|
||||
[HttpPut]
|
||||
[Route("/api/vehicle/odometerrecords/update")]
|
||||
[Consumes("application/json")]
|
||||
public IActionResult UpdateOdometerRecordJson([FromBody] OdometerRecordExportModel input) => UpdateOdometerRecord(input);
|
||||
[HttpPut]
|
||||
[Route("/api/vehicle/odometerrecords/update")]
|
||||
public IActionResult UpdateOdometerRecord(OdometerRecordExportModel input)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(input.Id) ||
|
||||
@@ -740,11 +826,23 @@ namespace CarCareTracker.Controllers
|
||||
Notes = x.Notes,
|
||||
ExtraFields = x.ExtraFields
|
||||
});
|
||||
return Json(result);
|
||||
if (_config.GetInvariantApi() || Request.Headers.ContainsKey("culture-invariant"))
|
||||
{
|
||||
return Json(result, StaticHelper.GetInvariantOption());
|
||||
}
|
||||
else
|
||||
{
|
||||
return Json(result);
|
||||
}
|
||||
}
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpPost]
|
||||
[Route("/api/vehicle/gasrecords/add")]
|
||||
[Consumes("application/json")]
|
||||
public IActionResult AddGasRecordJson(int vehicleId, [FromBody] GasRecordExportModel input) => AddGasRecord(vehicleId, input);
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpPost]
|
||||
[Route("/api/vehicle/gasrecords/add")]
|
||||
public IActionResult AddGasRecord(int vehicleId, GasRecordExportModel input)
|
||||
{
|
||||
if (vehicleId == default)
|
||||
@@ -801,6 +899,10 @@ namespace CarCareTracker.Controllers
|
||||
}
|
||||
[HttpPut]
|
||||
[Route("/api/vehicle/gasrecords/update")]
|
||||
[Consumes("application/json")]
|
||||
public IActionResult UpdateGasRecordJson([FromBody] GasRecordExportModel input) => UpdateGasRecord(input);
|
||||
[HttpPut]
|
||||
[Route("/api/vehicle/gasrecords/update")]
|
||||
public IActionResult UpdateGasRecord(GasRecordExportModel input)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(input.Id) ||
|
||||
@@ -865,7 +967,14 @@ namespace CarCareTracker.Controllers
|
||||
var currentMileage = _vehicleLogic.GetMaxMileage(vehicleId);
|
||||
var reminders = _reminderRecordDataAccess.GetReminderRecordsByVehicleId(vehicleId);
|
||||
var results = _reminderHelper.GetReminderRecordViewModels(reminders, currentMileage, DateTime.Now).Select(x=> new ReminderExportModel { Description = x.Description, Urgency = x.Urgency.ToString(), Metric = x.Metric.ToString(), Notes = x.Notes, DueDate = x.Date.ToShortDateString(), DueOdometer = x.Mileage.ToString()});
|
||||
return Json(results);
|
||||
if (_config.GetInvariantApi() || Request.Headers.ContainsKey("culture-invariant"))
|
||||
{
|
||||
return Json(results, StaticHelper.GetInvariantOption());
|
||||
}
|
||||
else
|
||||
{
|
||||
return Json(results);
|
||||
}
|
||||
}
|
||||
[Authorize(Roles = nameof(UserData.IsRootUser))]
|
||||
[HttpGet]
|
||||
|
||||
@@ -24,7 +24,8 @@ namespace CarCareTracker.Helper
|
||||
bool GetServerEnableShopSupplies();
|
||||
string GetServerPostgresConnection();
|
||||
string GetAllowedFileUploadExtensions();
|
||||
public bool DeleteUserConfig(int userId);
|
||||
bool DeleteUserConfig(int userId);
|
||||
bool GetInvariantApi();
|
||||
}
|
||||
public class ConfigHelper : IConfigHelper
|
||||
{
|
||||
@@ -51,6 +52,10 @@ namespace CarCareTracker.Helper
|
||||
{
|
||||
return CheckBool(CheckString("LUBELOGGER_CUSTOM_WIDGETS"));
|
||||
}
|
||||
public bool GetInvariantApi()
|
||||
{
|
||||
return CheckBool(CheckString("LUBELOGGER_INVARIANT_API"));
|
||||
}
|
||||
public string GetMOTD()
|
||||
{
|
||||
var motd = CheckString("LUBELOGGER_MOTD");
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using CarCareTracker.Models;
|
||||
using CsvHelper;
|
||||
using System.Globalization;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace CarCareTracker.Helper
|
||||
{
|
||||
@@ -622,6 +623,12 @@ namespace CarCareTracker.Helper
|
||||
return string.IsNullOrWhiteSpace(decorations) ? input.ToString("C2") : $"{input.ToString("C2")}{decorations}";
|
||||
}
|
||||
}
|
||||
public static JsonSerializerOptions GetInvariantOption()
|
||||
{
|
||||
var serializerOption = new JsonSerializerOptions();
|
||||
serializerOption.Converters.Add(new InvariantConverter());
|
||||
return serializerOption;
|
||||
}
|
||||
public static void WriteGasRecordExportModel(CsvWriter _csv, IEnumerable<GasRecordExportModel> genericRecords)
|
||||
{
|
||||
var extraHeaders = genericRecords.SelectMany(x => x.ExtraFields).Select(y => y.Name).Distinct();
|
||||
|
||||
138
Models/API/TypeConverter.cs
Normal file
138
Models/API/TypeConverter.cs
Normal file
@@ -0,0 +1,138 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace CarCareTracker.Models
|
||||
{
|
||||
public class DummyType
|
||||
{
|
||||
|
||||
}
|
||||
class InvariantConverter : JsonConverter<DummyType>
|
||||
{
|
||||
public override void Write(Utf8JsonWriter writer, DummyType value, JsonSerializerOptions options)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
public override DummyType? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
class FromDateOptional: JsonConverter<string>
|
||||
{
|
||||
public override string? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
var tokenType = reader.TokenType;
|
||||
if (tokenType == JsonTokenType.String)
|
||||
{
|
||||
return reader.GetString();
|
||||
}
|
||||
else if (tokenType == JsonTokenType.Number)
|
||||
{
|
||||
if (reader.TryGetInt64(out long intInput))
|
||||
{
|
||||
return DateTimeOffset.FromUnixTimeSeconds(intInput).Date.ToShortDateString();
|
||||
}
|
||||
}
|
||||
return reader.GetString();
|
||||
}
|
||||
public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
|
||||
{
|
||||
if (options.Converters.Any(x => x.Type == typeof(DummyType)))
|
||||
{
|
||||
writer.WriteStringValue(DateTime.Parse(value).ToString("yyyy-MM-dd"));
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteStringValue(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
class FromDecimalOptional : JsonConverter<string>
|
||||
{
|
||||
public override string? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
var tokenType = reader.TokenType;
|
||||
if (tokenType == JsonTokenType.String)
|
||||
{
|
||||
return reader.GetString();
|
||||
}
|
||||
else if (tokenType == JsonTokenType.Number) {
|
||||
if (reader.TryGetDecimal(out decimal decimalInput))
|
||||
{
|
||||
return decimalInput.ToString();
|
||||
}
|
||||
}
|
||||
return reader.GetString();
|
||||
}
|
||||
public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
|
||||
{
|
||||
if (options.Converters.Any(x=>x.Type == typeof(DummyType)))
|
||||
{
|
||||
writer.WriteNumberValue(decimal.Parse(value));
|
||||
} else
|
||||
{
|
||||
writer.WriteStringValue(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
class FromIntOptional : JsonConverter<string>
|
||||
{
|
||||
public override string? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
var tokenType = reader.TokenType;
|
||||
if (tokenType == JsonTokenType.String)
|
||||
{
|
||||
return reader.GetString();
|
||||
}
|
||||
else if (tokenType == JsonTokenType.Number)
|
||||
{
|
||||
if (reader.TryGetInt32(out int intInput))
|
||||
{
|
||||
return intInput.ToString();
|
||||
}
|
||||
}
|
||||
return reader.GetString();
|
||||
}
|
||||
public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
|
||||
{
|
||||
if (options.Converters.Any(x => x.Type == typeof(DummyType)))
|
||||
{
|
||||
writer.WriteNumberValue(int.Parse(value));
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteStringValue(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
class FromBoolOptional : JsonConverter<string>
|
||||
{
|
||||
public override string? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
var tokenType = reader.TokenType;
|
||||
switch (tokenType)
|
||||
{
|
||||
case JsonTokenType.String:
|
||||
return reader.GetString();
|
||||
case JsonTokenType.True:
|
||||
return "True";
|
||||
case JsonTokenType.False:
|
||||
return "False";
|
||||
default:
|
||||
return reader.GetString();
|
||||
}
|
||||
}
|
||||
public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
|
||||
{
|
||||
if (options.Converters.Any(x => x.Type == typeof(DummyType)))
|
||||
{
|
||||
writer.WriteBooleanValue(bool.Parse(value));
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteStringValue(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
namespace CarCareTracker.Models
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace CarCareTracker.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Import model used for importing records via CSV.
|
||||
@@ -45,20 +47,28 @@
|
||||
}
|
||||
public class GenericRecordExportModel
|
||||
{
|
||||
[JsonConverter(typeof(FromIntOptional))]
|
||||
public string Id { get; set; }
|
||||
[JsonConverter(typeof(FromDateOptional))]
|
||||
public string Date { get; set; }
|
||||
[JsonConverter(typeof(FromIntOptional))]
|
||||
public string Odometer { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string Notes { get; set; }
|
||||
[JsonConverter(typeof(FromDecimalOptional))]
|
||||
public string Cost { get; set; }
|
||||
public string Tags { get; set; }
|
||||
public List<ExtraField> ExtraFields { get; set; }
|
||||
}
|
||||
public class OdometerRecordExportModel
|
||||
{
|
||||
[JsonConverter(typeof(FromIntOptional))]
|
||||
public string Id { get; set; }
|
||||
[JsonConverter(typeof(FromDateOptional))]
|
||||
public string Date { get; set; }
|
||||
[JsonConverter(typeof(FromIntOptional))]
|
||||
public string InitialOdometer { get; set; }
|
||||
[JsonConverter(typeof(FromIntOptional))]
|
||||
public string Odometer { get; set; }
|
||||
public string Notes { get; set; }
|
||||
public string Tags { get; set; }
|
||||
@@ -66,23 +76,33 @@
|
||||
}
|
||||
public class TaxRecordExportModel
|
||||
{
|
||||
[JsonConverter(typeof(FromIntOptional))]
|
||||
public string Id { get; set; }
|
||||
[JsonConverter(typeof(FromDateOptional))]
|
||||
public string Date { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string Notes { get; set; }
|
||||
[JsonConverter(typeof(FromDecimalOptional))]
|
||||
public string Cost { get; set; }
|
||||
public string Tags { get; set; }
|
||||
public List<ExtraField> ExtraFields { get; set; }
|
||||
}
|
||||
public class GasRecordExportModel
|
||||
{
|
||||
[JsonConverter(typeof(FromIntOptional))]
|
||||
public string Id { get; set; }
|
||||
[JsonConverter(typeof(FromDateOptional))]
|
||||
public string Date { get; set; }
|
||||
[JsonConverter(typeof(FromIntOptional))]
|
||||
public string Odometer { get; set; }
|
||||
[JsonConverter(typeof(FromDecimalOptional))]
|
||||
public string FuelConsumed { get; set; }
|
||||
[JsonConverter(typeof(FromDecimalOptional))]
|
||||
public string Cost { get; set; }
|
||||
public string FuelEconomy { get; set; }
|
||||
[JsonConverter(typeof(FromBoolOptional))]
|
||||
public string IsFillToFull { get; set; }
|
||||
[JsonConverter(typeof(FromBoolOptional))]
|
||||
public string MissedFuelUp { get; set; }
|
||||
public string Notes { get; set; }
|
||||
public string Tags { get; set; }
|
||||
@@ -94,7 +114,9 @@
|
||||
public string Urgency { get; set; }
|
||||
public string Metric { get; set; }
|
||||
public string Notes { get; set; }
|
||||
[JsonConverter(typeof(FromDateOptional))]
|
||||
public string DueDate { get; set; }
|
||||
[JsonConverter(typeof(FromIntOptional))]
|
||||
public string DueOdometer { get; set; }
|
||||
}
|
||||
public class PlanRecordExportModel
|
||||
|
||||
Reference in New Issue
Block a user