I mostly favour immutable DTOs with read-only fields if I can get away with it:
public class CustomerDTO
{
public CustomerDTO(int id, string name)
{
Id = id;
Name = name;
}
public readonly int Id;
public readonly string Name;
// Override Equals and GetHashCode as well...
}
There's lots of advantages to be had from immutable records, such as structural equality, which makes automated test assertions much simpler to write. It also dispenses with the need to write and maintain separate Test Data Builders.
It depends on the serializer, though. JSON.NET can handle immutable records, but many other serializers can't.
For those that handle public fields, I prefer fields over properties, simply because it's more honest; automatically implemented read/write properties provide no encapsulation.
Some serializers insist on public properties, and don't serialize fields. If that's the scenario, you have to go with that.
Honestly, considering how much thought I've put into this, it's not really something that keeps me awake at night, because ultimately, at the boundaries, applications aren't object-oriented. Thus, the rules of OOD don't really apply to DTOs anyway.