JsonProperty on C# Records in Constructor [duplicate] - c#

This question already has answers here:
How do I target attributes for a record class?
(2 answers)
Closed 1 year ago.
With the new C# record types in C# 9 i'd like to know wheter it is possible (for serialization) to set the JsonPropertyAttribute from Newtonsoft.Json on the constructor parameter.
It doesn't seem to work out of the box.
MWE:
using System;
using Newtonsoft.Json;
Console.WriteLine(JsonConvert.SerializeObject(new Something("something")));
record Something([JsonProperty("hello")] string world) {}
Output:
{"world":"something"}
Expected output:
{"hello":"something"}
is there an easy way to make it work like this? or do we have to revert back to the property style with a real constructor?
internal record Something
{
public Something(string world) { World = world; }
[JsonProperty("hello")] public string World { get; }
}

Per the docs:
Attributes can be applied to the synthesized auto-property and its backing field by using property: or field: targets for attributes syntactically applied to the corresponding record parameter.
So you want
record Something([property:JsonProperty("hello")] string world) {}
Without the property: qualifier, the attribute ends up on the parameter of the generated constructor (which is useful in other scenarios, like nullability).

Related

How to make a property visible (scope, access modifier) only by XmlSerializer in C#? [duplicate]

This question already has answers here:
How can I serialize internal classes using XmlSerializer?
(5 answers)
c#: how to hide a field which is used only for XML serialization retrocompatibility?
(3 answers)
Closed 2 years ago.
I would like to make some property of a class visisble (scope, access modifier) only by the XML serializer.
I'm not sure about the best way to hide some properties from the consumers of a class without over engineering.
Let's see an exemple:
public class MyClass
{
[XmlIgnore]
public Version Version { get; set; }
/// <summary>
/// Do not used. This is a dummy property for XML serialization.
/// </summary>
[XmlAttribute(AttributeName = nameof(Version))]
public string XmlVersion
{
get => Version.ToString();
set => Version = new Version(value);
}
}
This kind of code allows me to use a class which is not designed to be serialized (System.Version isn't because its properties are readonly).
I would like that the consumers of my class see only Version but not the XmlVersion property.
Edit : If it's possible, I'd like those properties to be hidden even in the project where the class is so my co-worker won't use those dummy properties too.
I know I can use ObsoleteAttribute to give information why they should be avoided but those properties will still be usable which isn't the behavior I'm looking for.

Can I map a JSON element "#somename"? [duplicate]

This question already has answers here:
.NET NewtonSoft JSON deserialize map to a different property name
(6 answers)
Closed 3 years ago.
I’m targeting .net framework 4.7 with a winforms application.
I started by following this article https://learn.microsoft.com/en-us/dotnet/csharp/tutorials/console-webapiclient so I am using DataContractJsonSerializer.
I’m trying to learn about a REST interface that returns JSON -
{"Resource":
{"#attributes":
{"name":"Asset",
"resourceId":"Asset",
"type":"Resource"
}
}
}
I used netwonsoft.json 12.0.2 to paste the JSON as classes. It ignores the ‘#’ character and creates a member “attributes” in class “Resource” with type “Attributes” .
When DataContractJsonSerializer attempts to deserialise the JSON it skips the #attribute element, I presume because it does not match the class name.
Is there a way to map the element #attributes to my attributes member / class?
I have tried adding [DataMember(Name = "#attributes")] on the attributes member of the Resource class and a [DataContract(Name = "#attributes")] on the Attributes class but still the element appears to be skipped (attributes member of Resource is null).
Yes, use JsonProperty
public class MyClass
{
[JsonProperty("#attributes")]
public string attributes { get; set; }
}

Add an event listener to C# class property reflectively [duplicate]

This question already has answers here:
Is it possible to implement Property Changed as Attribute?
(2 answers)
Override Getter/Setter with Custom Attribute
(2 answers)
Override property setter and getter
(2 answers)
C# WPF How to set Property setter method dynamically?
(3 answers)
Closed 5 years ago.
I'm trying to create an OleTableAttribute that I will apply to a class MyTable alongside a System.Data.Linq.Mapping.TableAttribute so that it would look something like this:
[Table(Name="MyTable")]
[OleTable]
public class MyTable
{
[Column(IsPrimaryKey = true)]
public int pk_id { get; set; }
/*...*/
}
What I'd like the OleTableAttribute to do is look for any [Column] attributed properties in the class that it is marked on, and reflectively add some type of listener to the setter method if it has one. The focus of this question is really how to do the reflective monitoring-setup of setter calls; just a simple "hey-its-been-called" signal is all I need. Is this possible?
PostSharp works. Using the [NotifyPropertyChanged] aspect will decorate all your properties behind the scenes with just the type of signalling I'm looking for here. Then the [OleTable] can treat it's attributed class as INotifyPropertyChanged and add its own PropertyChanged event.

Why use properties that don't do any validation or other processes? [duplicate]

This question already has answers here:
What is the difference between a field and a property?
(33 answers)
Closed 8 years ago.
Suppose I have a property in a class as in the following:
class testclass
{
public string Name {get; set;}
public void dosomething(){//...}
}
There is no functional difference between this format and the following:
class testclass
{
public string name;
public void dosomething(){//...}
}
Both name fields can be set to anything including an empty string and both can retrieve just without any restrictions. So what is the use of the property semantics detailed above where there is no validation or other process in the get and set methods? One use I see is that you can remove either the get or set method to make it write only or read only, respectively. I don't know what other use this would serve.
The main reason is so that you can change the implementation later without breaking client code. You might not do any validation or raise an event now but what if you decide to in the future? Also, properties can be bound while fields can't.

Get custom attributes of enum value [duplicate]

This question already has answers here:
Anyone know a quick way to get to custom attributes on an enum value?
(2 answers)
Closed 9 years ago.
In a WinRT .NET application (C#) I want to get the custom attributes, that are defined on an enum value. Take the following enum for example:
public enum MyEnum
{
[Display(Name="Foo")]
EnumValue1,
[Display(Name="Bar")]
EnumValue2
}
Now in "normal" .NET I know that I'm able to obtain the custom attributes of an enum value with enumValue.GetType().GetMember(enumValue.ToString()).
Unfortunately, in WinRT .NET the GetMember() method isn't available on the Type class.
Any suggestions how to go with this?
=====================================================
Thanks to Marc below, I found the answer!
The following code works to get a specific custom attribute from an enum value in .NET 4.5 WinRT:
public static class EnumHelper
{
public static T GetAttribute<T>(this Enum enumValue)
where T : Attribute
{
return enumValue
.GetType()
.GetTypeInfo()
.GetDeclaredField(enumValue.ToString())
.GetCustomAttribute<T>();
}
}
Rather than looking for members, you should perhaps look specifically for fields. If that isn't available on the Type in WinRT, add using System.Reflection; and use type.GetTypeInfo() and look on there too, as various reflection facets are moved to the type-info.

Categories

Resources