I have a program in .Net 5 C# that make a HTTP Request and the content (JSON) is deserialized (JsonNewtonsoft) in specific type:
// Class definition
public class FooSerializerModel {
[JsonProperty("latitude")]
public string Latitude { get; set; }
[JsonProperty("longitude")]
public string Longitude { get; set; }
}
// Deserialization
var fooJson = JsonConvert.DeserializeObject<FooSerializerModel>(response);
It works fine, now, I need cast the fooJson
variable type to other type for pass it to Data Layer Method:
public class DataModel {
public string Latitude { get; set; }
public string Longitude { get; set; }
}
I need something like this:
var data = fromJson as DataModel;
But I get this error: Cannot convert type FooSerializerModel
to DataModel
Why?
I know is possible solve this problem using:
var data = new DataModel() {
Latitude = fromJson.Latitude,
Longitude = fromJson.Longitude
}
But if my class has 50 attributes I would have to assign one by one, it would be more lines of code and I could forget some of them when doing it explicitly.
Is it possible to do an implicit assignment on a single line? I have tried this:
var data = fromJson as DataModel; // Error
var data = (DataModel) fromJson; // Error
var data = (DataModel) (object) fromJson; // Exception 'Unable to cast object of type' when use 'dotnet run'
I remember that it is possible to do this in TypeScript if you work with types with interfaces and is easy!
CodePudding user response:
All the code was tested in Visual Studio and working properly.
var fooJson = JsonConvert.DeserializeObject<DataModel>(response);
everything will be fine, since you don't really need [JsonProperty] attribute. You just need to fix your startup or there are another options to conver low case to upper.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews()
.AddNewtonsoftJson(options =>
options.SerializerSettings.ContractResolver =
new CamelCasePropertyNamesContractResolver());
.... other code
}
but I even don't think that json attributes will affect your classes even if you use them for MongoDB. Classes are classes, but attributes are attributes, they live a completely separate life.
But if you like it hard way I can offer this
public class DataModel
{
public virtual string Latitude { get; set; }
public virtual string Longitude { get; set; }
}
public class FooSerializerModel:DataModel
{
[JsonProperty("latitude")]
public override string Latitude { get; set; }
[JsonProperty("longitude")]
public override string Longitude { get; set; }
}
Now you can write the code you wanted
var fooJson = JsonConvert.DeserializeObject<FooSerializerModel>(response);
DataModel data=fooJson;
CodePudding user response:
Assuming both your API contract and your data-layer contract expose the same properties with the same types and names, you can use an interface
:
public interface ICoordinates
{
public string Latitude { get; set; }
public string Longitude { get; set; }
}
public class FooSerializerModel : ICoordinates
{
[JsonProperty("latitude")]
public string Latitude { get; set; }
[JsonProperty("longitude")]
public string Longitude { get; set; }
}
public class DataModel : ICoordinates
{
[SampleDbAttribute(ColumnName: "col_latitude")]
public string Latitude { get; set; }
[SampleDbAttribute(ColumnName: "col_longitude")]
public string Longitude { get; set; }
}
Then you can cast between the inherited types because they both implement the same interface:
// Deserialization
var fooJson = JsonConvert.DeserializeObject<FooSerializerModel>(response);
var data = fromJson as DataModel;