Mapster icon indicating copy to clipboard operation
Mapster copied to clipboard

When the destination type is a record any properties which are all uppercase are not mapped

Open chunty opened this issue 7 months ago • 3 comments

Unless you specify a naming strategy mapping to a record with properties all in upper case the destination value is not set. Works fine if the destination type is a class.

Example here:

using System;
using Mapster;
					
public class Program
{
	public static void Main()
	{
		//TypeAdapterConfig.GlobalSettings.Default.NameMatchingStrategy(NameMatchingStrategy.IgnoreCase); // Needed to allow all upper case when mapping to a record
		
		var testClass = new SrcClass();
		var testRecord = new SrcRecord();
		
		LogAdaptResult<DestinationClass>(testClass);
		LogAdaptResult<DestinationClass>(testRecord);
		
		LogAdaptResult<DestinationRecord>(testClass);
		LogAdaptResult<DestinationRecord>(testRecord);		
	}
	
	public static void LogAdaptResult<TOut>(ITestObject obj) where TOut : class, IResult
	{
		var result = obj.Adapt<TOut>();
		Console.WriteLine("-------");
		Console.WriteLine("Mapping {0} to {1}", obj.GetType().Name, result.GetType().Name);
		Console.WriteLine(" - Name: {0}", result.Name);
		Console.WriteLine(" - SPN: {0}", result.SPN);	
		Console.WriteLine(" - UPC: {0}", result.UPC);	
	}
	
	public interface ITestObject
	{
		public string Name {get;}
		public string SPN {get;}
        public string UPC {get;}
	};
	
	public interface IResult
	{
		public string Name {get;}
		public string SPN {get;}
        public string UPC {get;}
	};	
		
	public class SrcClass : ITestObject
	{
		public string Name {get; set;} = "This is class name";
		public string SPN {get; set;} = "This is class SPN";
        public string UPC {get; set;} = "This is class UPC";		
	}
	
	public record SrcRecord(
		string Name = "This is a record name", 
		string SPN = "This is a record SPN",
		string UPC = "This is a record UPC"
	) : ITestObject ;
	
	public class DestinationClass : IResult
	{
		public string Name {get; set;} = string.Empty;
		public string SPN {get; set;} = string.Empty;
		public string UPC {get; set;} = string.Empty;
	}
		
	public record DestinationRecord(
		string Name = "", 
		string SPN = "",
		string UPC = "") : IResult;
}

chunty avatar Jun 09 '25 12:06 chunty

@chunty It's actually related to the constructor parameters. I described it in #771.

Try the pre-release version. It's not completely fixed there, but you should get the result you want.

DocSvartz avatar Jun 09 '25 13:06 DocSvartz

Addition

In 7.4.0 and earlier mapster not support for record types. There is only support for record in the following specification, where properties are not mapped separately.

class Person {
    public string Name { get; }
    public int Age { get; }

    public Person(string name, int age) {
        this.Name = name;
        this.Age = age;
    }
}

All properties must be specified in the constructor (The problem with the constructor is indicated in the comment above)

DocSvartz avatar Jun 11 '25 04:06 DocSvartz

@chunty It's actually related to the constructor parameters. I described it in #771.

Try the pre-release version. It's not completely fixed there, but you should get the result you want.

Thanks I'll give that a go

chunty avatar Jun 11 '25 09:06 chunty