Replace CntrlComparison with LeafGasComparison
This commit is contained in:
@@ -8,7 +8,7 @@ namespace LeafWeb.Core.Charter
|
||||
{
|
||||
public static class CurveDataConverter
|
||||
{
|
||||
public static IEnumerable<CurveData> Convert(IEnumerable<CntrlComparison> cntrlComparison)
|
||||
public static IEnumerable<CurveData> Convert(IEnumerable<LeafGasComparison> cntrlComparison)
|
||||
{
|
||||
var comparisonGroups =
|
||||
from comparison in cntrlComparison
|
||||
@@ -17,12 +17,12 @@ namespace LeafWeb.Core.Charter
|
||||
{
|
||||
CurveID = curves.Key,
|
||||
FitType = from curve in curves
|
||||
group curve by new {curve.FitGi, curve.FitGammaStar} into grp
|
||||
group curve by new {curve.FitRwp, curve.FitGammaStar} into grp
|
||||
select new
|
||||
{
|
||||
grp.Key.FitGi,
|
||||
grp.Key.FitRwp,
|
||||
grp.Key.FitGammaStar,
|
||||
Comparison = grp.SingleOrDefault()
|
||||
Comparison = grp.FirstOrDefault() // TODO: this may need to be SingleOrDefault
|
||||
}
|
||||
};
|
||||
|
||||
@@ -44,13 +44,13 @@ namespace LeafWeb.Core.Charter
|
||||
// gammastar = chloroplastic CO2 partial pressure photocompensation point = "Cmp"
|
||||
|
||||
// put each comparison into the correct curve location
|
||||
if (!fitType.FitGi && !fitType.FitGammaStar)
|
||||
if (!fitType.FitRwp && !fitType.FitGammaStar)
|
||||
curveData.FixedCndFixedCmp = paramSet;
|
||||
else if (!fitType.FitGi && fitType.FitGammaStar)
|
||||
else if (!fitType.FitRwp && fitType.FitGammaStar)
|
||||
curveData.FixedCndEstimatedCmp = paramSet;
|
||||
else if (fitType.FitGi && !fitType.FitGammaStar)
|
||||
else if (fitType.FitRwp && !fitType.FitGammaStar)
|
||||
curveData.EstimatedCndFixedCmp = paramSet;
|
||||
else if (fitType.FitGi && fitType.FitGammaStar)
|
||||
else if (fitType.FitRwp && fitType.FitGammaStar)
|
||||
curveData.EstimatedCndEstimatedCmp = paramSet;
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ namespace LeafWeb.Core.Charter
|
||||
}
|
||||
}
|
||||
|
||||
private static CurveParamSet ConvertParamSet(CntrlComparison comparison)
|
||||
private static CurveParamSet ConvertParamSet(LeafGasComparison comparison)
|
||||
{
|
||||
var curveParamSet = new CurveParamSet();
|
||||
foreach (var fittingInfo in comparison.FittingInfo)
|
||||
@@ -85,7 +85,7 @@ namespace LeafWeb.Core.Charter
|
||||
return curveParamSet;
|
||||
}
|
||||
|
||||
private static void Set(CurveParamSet paramSet, CntrlComparisonPhotosyntheticInfo item)
|
||||
private static void Set(CurveParamSet paramSet, LeafGasComparisonPhotosyntheticInfo item)
|
||||
{
|
||||
AddXyIfInRange(item.CO2cc, item.Ac, paramSet.AcChloroData.Add); // Ac(y),CO2cc(x)
|
||||
AddXyIfInRange(item.CO2cj, item.Aj, paramSet.AjChloroData.Add); // Aj(y),CO2cj(x)
|
||||
@@ -103,12 +103,12 @@ namespace LeafWeb.Core.Charter
|
||||
set(xyPoint);
|
||||
}
|
||||
|
||||
private static void Set(CurveParamSet paramSet, CntrlComparisonFittingInfo fittingInfo)
|
||||
private static void Set(CurveParamSet paramSet, LeafGasComparisonFittingInfo fittingInfo)
|
||||
{
|
||||
var xyPoint1 = new XyPoint(fittingInfo.PCO2c, fittingInfo.AnetMeas); // AnetMeas(y), PCO2c(x)
|
||||
var xyPoint2 = new XyPoint(fittingInfo.PCO2i, fittingInfo.AnetMeas);
|
||||
var xyPoint1 = new XyPoint(fittingInfo.CO2c, fittingInfo.Anet_obs); // AnetMeas(y), PCO2c(x)
|
||||
var xyPoint2 = new XyPoint(fittingInfo.CO2i_obs, fittingInfo.Anet_obs);
|
||||
|
||||
switch (fittingInfo.PointLimitType)
|
||||
switch (fittingInfo.LimitState)
|
||||
{
|
||||
case 1:
|
||||
paramSet.AnetMeasChloro1Data.Add(xyPoint1);
|
||||
|
||||
+4
-4
@@ -76,13 +76,14 @@
|
||||
<Compile Include="DAL\DataService.cs" />
|
||||
<Compile Include="DAL\LeafWebContext.cs" />
|
||||
<Compile Include="DAL\LeafWebInitializer.cs" />
|
||||
<Compile Include="Entities\LeafGasComparisonPhotosyntheticInfo.cs" />
|
||||
<Compile Include="Entities\LeafGasComparisonFittingInfo.cs" />
|
||||
<Compile Include="Entities\LeafGasComparison.cs" />
|
||||
<Compile Include="Entities\LeafInputStatusType.cs" />
|
||||
<Compile Include="Entities\LeafOutputFile.cs" />
|
||||
<Compile Include="Entities\PhotosynthesisType.cs" />
|
||||
<Compile Include="Parsers\LeafGasComparisonParser.cs" />
|
||||
<Compile Include="Remote\IPiscalClient.cs" />
|
||||
<Compile Include="Entities\CntrlComparison.cs" />
|
||||
<Compile Include="Entities\CntrlComparisonFittingInfo.cs" />
|
||||
<Compile Include="Entities\CntrlComparisonPhotosyntheticInfo.cs" />
|
||||
<Compile Include="Entities\FluxnetSite.cs" />
|
||||
<Compile Include="Entities\LeafInput.cs" />
|
||||
<Compile Include="Entities\LeafInputData.cs" />
|
||||
@@ -100,7 +101,6 @@
|
||||
<Compile Include="Remote\PiscalStatus.cs" />
|
||||
<Compile Include="Remote\PiscalUtility.cs" />
|
||||
<Compile Include="Utility\BoolTypeConverter.cs" />
|
||||
<Compile Include="Parsers\CntrlComparisonParser.cs" />
|
||||
<Compile Include="Parsers\CsvParserBase.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Utility\FileUtility.cs" />
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace LeafWeb.Core.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Part of LeafOutput
|
||||
/// The file 'cntrlcomparison.csv', which is in comma-separated-value format, contains outputs from PISCAL that
|
||||
/// facilitates examination of how well the fitting is.
|
||||
/// </summary>
|
||||
public class CntrlComparison
|
||||
{
|
||||
public virtual IEnumerable<CntrlComparisonFittingInfo> FittingInfo { get; set; }
|
||||
public virtual IEnumerable<CntrlComparisonPhotosyntheticInfo> PhotosyntheticInfo { get; set; }
|
||||
|
||||
public string CurveID => FittingInfo.First().CurveID;
|
||||
|
||||
public bool FitGi => FittingInfo.First().FitGi;
|
||||
|
||||
public bool FitGammaStar => FittingInfo.First().FitGammaStar;
|
||||
}
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
using LeafWeb.Core.Utility;
|
||||
|
||||
namespace LeafWeb.Core.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// First model prediction is calculated at each sampling point.
|
||||
/// Then model prediction is calculated at many selected levels of intercelluar CO2 partial pressure
|
||||
/// levels under three limitation states to enable plotting curves.The same structure is then repeated for
|
||||
/// each fitting of the same curve with different parameters to be estimated and with different curves. Note
|
||||
/// that some common information about a curve is repeated for each data point to make the structure of the
|
||||
/// file as regular as possible.
|
||||
/// </summary>
|
||||
public class CntrlComparisonFittingInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// the curve identifier, repeated for each point
|
||||
/// </summary>
|
||||
[ParseInfo(1)]
|
||||
public string CurveID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// whether or not chlorophyll fluorescence data are used for identifying the limitation states
|
||||
/// 0 = not used, 1 = used. (Currently this choice is still under evaluation and therefore ChlFlUse? = 0).
|
||||
/// </summary>
|
||||
[ParseInfo(2, alternateTitle: "ChlFlUse?")]
|
||||
public bool ChlFlUse {get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// whether or not the internal conductance (gi) is fitted for.
|
||||
/// 0 = not fitted and gi is either infinite or fixed at the value provided by the user.
|
||||
/// 1 = gi is estiamted, repeated for each point
|
||||
/// </summary>
|
||||
[ParseInfo(3, alternateTitle: "FitGi?")]
|
||||
public bool FitGi {get; set;}
|
||||
|
||||
/// <summary>
|
||||
/// whether or not the chloroplastic CO2 partial pressure photocompensation point is
|
||||
/// fitted for. 0= not fitted, a prescribed value is used, repeated for each point
|
||||
/// </summary>
|
||||
[ParseInfo(4, alternateTitle: "FitGamma*?")]
|
||||
public bool FitGammaStar {get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// whether or not the apparent Michaelis - Menten constant Kco = Kc(1+O/Ko) is fitted for.
|
||||
/// 0= not fitted, a prescribed value is calculated from Kc, Ko and the oxygen partial pressure.
|
||||
/// 1= Fitted for, repeated for each point
|
||||
/// </summary>
|
||||
[ParseInfo(5, alternateTitle: "FitKco?")]
|
||||
public bool FitKco {get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// whether the dark respiration is fitted for. 0= not fitted for, a prescribed value is used.
|
||||
/// 1= fitted for. repeated for each point
|
||||
/// </summary>
|
||||
[ParseInfo(6, alternateTitle: "FitRd?")]
|
||||
public bool FitRd {get; set;}
|
||||
|
||||
/// <summary>
|
||||
/// whether alpha (the non-returned fraction of the glycolate carbon
|
||||
/// recycled in the photorespiratory cycle) is fitted for.
|
||||
/// 0= not fitted for and alpha = 0
|
||||
/// 1= fitted for, repeated for each point
|
||||
/// </summary>
|
||||
[ParseInfo(7, alternateTitle: "FitAlpha?")]
|
||||
public bool FitAlpha {get; set;}
|
||||
|
||||
/// <summary>
|
||||
/// the combination of limitation states present in the A/Ci dataset. Parameters
|
||||
/// are estimated for those limitation states that occur in the measured curve, repeated for each point
|
||||
/// Rubisco: Rubisco limitation(Vcmax, Kco)
|
||||
/// RuBP: RuBP regeneration limitation(J)
|
||||
/// Tpu: export limitation(TPU, alpha)
|
||||
/// </summary>
|
||||
[ParseInfo(8)]
|
||||
public string LimitCombina { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// intercellular CO2 partial pressure
|
||||
/// </summary>
|
||||
[ParseInfo(9, units:"Pa")]
|
||||
public double PCO2i { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// chloroplastic CO2 partial pressure corresponding to the PCO2i of a point.
|
||||
/// PCO2c=PCO2i-AnetCal/internal conductance
|
||||
/// </summary>
|
||||
[ParseInfo(10, units:"Pa")]
|
||||
public double PCO2c { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// measured net assimilation rate
|
||||
/// </summary>
|
||||
[ParseInfo(11, units: "umol/m2/s")]
|
||||
public double AnetMeas { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// calculated net assimilation rate
|
||||
/// </summary>
|
||||
[ParseInfo(12, units: "umol/m2/s")]
|
||||
public double AnetCal { get; set; }
|
||||
|
||||
// TODO: readme has weitedrms, data file has PCOiCal
|
||||
// weitedrms - (umol/m2/s), root mean square error of the fitting (weiting coefficient =1)
|
||||
[ParseInfo(13)]
|
||||
public double PCOiCal { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 1 = point limited by rubisco
|
||||
/// 2 = point limited by RuBP regeneration
|
||||
/// 3 = point limited by TPU
|
||||
/// </summary>
|
||||
[ParseInfo(14, units:"1,2,3")]
|
||||
public int PointLimitType { get; set; }
|
||||
|
||||
public virtual CntrlComparison CntrlComparison { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace LeafWeb.Core.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Part of LeafOutput
|
||||
/// The file 'leafgascomparison.csv', which is in comma-separated-value format, contains outputs from PISCAL that
|
||||
/// facilitates examination of how well the fitting is.
|
||||
/// </summary>
|
||||
public class LeafGasComparison
|
||||
{
|
||||
public virtual IEnumerable<LeafGasComparisonFittingInfo> FittingInfo { get; set; }
|
||||
public virtual IEnumerable<LeafGasComparisonPhotosyntheticInfo> PhotosyntheticInfo { get; set; }
|
||||
|
||||
public string CurveID => FittingInfo.First().CurveID;
|
||||
|
||||
public bool FitRwp => FittingInfo.First().FitRwp;
|
||||
|
||||
public bool FitGammaStar => FittingInfo.First().FitGammaStar;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
using LeafWeb.Core.Utility;
|
||||
|
||||
namespace LeafWeb.Core.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// First model prediction is calculated at each sampling point.
|
||||
/// Then model prediction is calculated at many selected levels of intercelluar CO2 partial pressure
|
||||
/// levels under three limitation states to enable plotting curves.The same structure is then repeated for
|
||||
/// each fitting of the same curve with different parameters to be estimated and with different curves. Note
|
||||
/// that some common information about a curve is repeated for each data point to make the structure of the
|
||||
/// file as regular as possible.
|
||||
/// </summary>
|
||||
public class LeafGasComparisonFittingInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// the curve identifier, repeated for each point
|
||||
/// </summary>
|
||||
[ParseInfo(1)]
|
||||
public string CurveID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// whether or not the internal conductance (gi) is fitted for.
|
||||
/// 0 = not fitted and gi is either infinite or fixed at the value provided by the user.
|
||||
/// 1 = gi is estiamted, repeated for each point
|
||||
/// </summary>
|
||||
[ParseInfo(2, boolEncodedPosition: 1, alternateTitle: "FitRwp|Rch|ha?")] // formerly FitGi
|
||||
public bool FitRwp {get; set;}
|
||||
|
||||
/// <summary>
|
||||
/// whether or not the chloroplastic CO2 partial pressure photocompensation point is
|
||||
/// fitted for. 0= not fitted, a prescribed value is used, repeated for each point
|
||||
/// </summary>
|
||||
[ParseInfo(4, boolEncodedPosition: 1, alternateTitle: "FitGamma*?")]
|
||||
public bool FitGammaStar {get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// intercellular CO2 partial pressure
|
||||
/// </summary>
|
||||
[ParseInfo(10, units:"Pa")]
|
||||
public double CO2i_obs { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// chloroplastic CO2 partial pressure corresponding to the PCO2i of a point.
|
||||
/// PCO2c=PCO2i-AnetCal/internal conductance
|
||||
/// </summary>
|
||||
[ParseInfo(12, units:"Pa")]
|
||||
public double CO2c { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// measured net assimilation rate
|
||||
/// </summary>
|
||||
[ParseInfo(13, units: "umol/m2/s")]
|
||||
public double Anet_obs { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 1 = point limited by rubisco
|
||||
/// 2 = point limited by RuBP regeneration
|
||||
/// 3 = point limited by TPU
|
||||
/// </summary>
|
||||
[ParseInfo(15, units:"1,2,3")]
|
||||
public int LimitState { get; set; }
|
||||
|
||||
public virtual LeafGasComparison LeafGasComparison { get; set; }
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -6,7 +6,7 @@ namespace LeafWeb.Core.Entities
|
||||
/// The second section gives photosynthesis for each of the three limitation states at selected values of intercellular
|
||||
/// partial pressure.Note that the corresponding values of chloraplastic CO2 partial pressure depend on the limitation state.
|
||||
/// </summary>
|
||||
public class CntrlComparisonPhotosyntheticInfo
|
||||
public class LeafGasComparisonPhotosyntheticInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// intercellular CO2 partial pressure
|
||||
@@ -50,6 +50,6 @@ namespace LeafWeb.Core.Entities
|
||||
[ParseInfo(7, units: "umol/m2/s")]
|
||||
public double At { get; set; }
|
||||
|
||||
public virtual CntrlComparison CntrlComparison { get; set; }
|
||||
public virtual LeafGasComparison LeafGasComparison { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ namespace LeafWeb.Core.Entities
|
||||
public byte[] Contents { get; set; }
|
||||
|
||||
// convention for the filename which LeafCharter uses
|
||||
public bool IsLeafChartFile => Filename?.StartsWith("cntrlcomparison") ?? false;
|
||||
public bool IsLeafChartFile => Filename?.Contains("leafgascomparison") ?? false;
|
||||
public bool IsErrorMessage => Filename?.Contains("errormessage") ?? false;
|
||||
public bool IsWarningMessage => Filename?.Contains("warningmessage") ?? false;
|
||||
}
|
||||
|
||||
@@ -6,17 +6,17 @@ using LeafWeb.Core.Utility;
|
||||
|
||||
namespace LeafWeb.Core.Parsers
|
||||
{
|
||||
public class CntrlComparisonParser : CsvParserBase
|
||||
public class LeafGasComparisonParser : CsvParserBase
|
||||
{
|
||||
public CntrlComparisonParser(FileSystemInfo csvFile) : base(csvFile)
|
||||
public LeafGasComparisonParser(FileSystemInfo csvFile) : base(csvFile)
|
||||
{
|
||||
}
|
||||
|
||||
public CntrlComparisonParser(byte[] fileContents) : base(fileContents)
|
||||
public LeafGasComparisonParser(byte[] fileContents) : base(fileContents)
|
||||
{
|
||||
}
|
||||
|
||||
public CntrlComparison[] Parse()
|
||||
public LeafGasComparison[] Parse()
|
||||
{
|
||||
var fittingTitles = GetNextCsvRowValues();
|
||||
if (fittingTitles == null)
|
||||
@@ -25,10 +25,10 @@ namespace LeafWeb.Core.Parsers
|
||||
if (fitUnits == null)
|
||||
throw new ParseException($"Could not read data units row on line number {CsvReader.Row}");
|
||||
|
||||
return ParseCntrlComparisonSet(fittingTitles).ToArray();
|
||||
return ParseLeafGasComparisonSet(fittingTitles).ToArray();
|
||||
}
|
||||
|
||||
private IEnumerable<CntrlComparison> ParseCntrlComparisonSet(string[] fittingTitles)
|
||||
private IEnumerable<LeafGasComparison> ParseLeafGasComparisonSet(string[] fittingTitles)
|
||||
{
|
||||
var endOfFile = false;
|
||||
while (!endOfFile)
|
||||
@@ -43,7 +43,7 @@ namespace LeafWeb.Core.Parsers
|
||||
throw new ParseException($"Encountered empty line while readding fitting info on line {CsvReader.Row}");
|
||||
if (values == null) // end of file
|
||||
yield break;
|
||||
if (ParsedObjectFactory<CntrlComparisonPhotosyntheticInfo>.IsPropertiesTitlesMatch(values))
|
||||
if (ParsedObjectFactory<LeafGasComparisonPhotosyntheticInfo>.IsPropertiesTitlesMatch(values))
|
||||
{
|
||||
photosyntheticTitles = values;
|
||||
break;
|
||||
@@ -66,13 +66,13 @@ namespace LeafWeb.Core.Parsers
|
||||
}
|
||||
|
||||
var fittingInfo =
|
||||
ParsedObjectFactory<CntrlComparisonFittingInfo>
|
||||
ParsedObjectFactory<LeafGasComparisonFittingInfo>
|
||||
.Create(fittingTitles, fittingValues.ToArray());
|
||||
var photosyntheticInfo =
|
||||
ParsedObjectFactory<CntrlComparisonPhotosyntheticInfo>
|
||||
ParsedObjectFactory<LeafGasComparisonPhotosyntheticInfo>
|
||||
.Create(photosyntheticTitles, photosyntheticValues.ToArray());
|
||||
|
||||
yield return new CntrlComparison
|
||||
yield return new LeafGasComparison
|
||||
{
|
||||
FittingInfo = fittingInfo,
|
||||
PhotosyntheticInfo = photosyntheticInfo
|
||||
@@ -24,6 +24,8 @@ namespace LeafWeb.Core.Utility
|
||||
|
||||
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
|
||||
{
|
||||
if (value is bool)
|
||||
return value;
|
||||
if (value is string)
|
||||
{
|
||||
var s = value as string;
|
||||
|
||||
@@ -8,6 +8,7 @@ namespace LeafWeb.Core.Utility
|
||||
public class ParseInfoAttribute : Attribute
|
||||
{
|
||||
public int Position { get; private set; }
|
||||
public int? BoolEncodedPosition { get; private set; }
|
||||
public string Units { get; private set; }
|
||||
public string Title { get; private set; }
|
||||
public string AlterateTitle { get; private set; }
|
||||
@@ -23,13 +24,16 @@ namespace LeafWeb.Core.Utility
|
||||
}
|
||||
}
|
||||
|
||||
public ParseInfoAttribute(int position, [CallerMemberName]string title = null, string units = null, string alternateTitle = null, string exampleValue = null)
|
||||
public ParseInfoAttribute(int position, [CallerMemberName]string title = null,
|
||||
string units = null, string alternateTitle = null, string exampleValue = null,
|
||||
int boolEncodedPosition = -1)
|
||||
{
|
||||
AlterateTitle = alternateTitle;
|
||||
ExampleValue = exampleValue;
|
||||
Title = title;
|
||||
Position = position;
|
||||
Units = units;
|
||||
BoolEncodedPosition = boolEncodedPosition == -1 ? (int?)null : boolEncodedPosition;
|
||||
}
|
||||
|
||||
public bool IsTitleMatch(string title)
|
||||
|
||||
@@ -132,6 +132,7 @@ namespace LeafWeb.Core.Utility
|
||||
return string.IsNullOrEmpty(value) || value == "NA" || value == "-9999";
|
||||
}
|
||||
|
||||
// TODO: this call maybe could be cached
|
||||
private static PropertyInfo MatchProperty(PropertyInfo[] properties, string title, int position)
|
||||
{
|
||||
return
|
||||
@@ -139,6 +140,7 @@ namespace LeafWeb.Core.Utility
|
||||
properties.FirstOrDefault(p => p.Attribute<ParseInfoAttribute>().IsPositionMatch(position));
|
||||
}
|
||||
|
||||
// TODO: this call maybe could be cached
|
||||
private static PropertyInfo MatchPropertyExact(PropertyInfo[] properties, string title, int position)
|
||||
{
|
||||
return
|
||||
@@ -180,6 +182,7 @@ namespace LeafWeb.Core.Utility
|
||||
{
|
||||
// http://stackoverflow.com/questions/3531318/convert-changetype-fails-on-nullable-types
|
||||
var t = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType;
|
||||
value = HandleBoolEncodedProperty(property, value);
|
||||
// convertedValue = Convert.ChangeType(value, t);
|
||||
var converter = TypeDescriptor.GetConverter(t);
|
||||
convertedValue = converter.ConvertTo(value, t);
|
||||
@@ -191,5 +194,26 @@ namespace LeafWeb.Core.Utility
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static object HandleBoolEncodedProperty(PropertyInfo property, object value)
|
||||
{
|
||||
var boolEncodedPosition = property.Attribute<ParseInfoAttribute>().BoolEncodedPosition;
|
||||
if (boolEncodedPosition == null) return value;
|
||||
|
||||
var v = (value as string)?.Substring(boolEncodedPosition.Value -1, 1);
|
||||
switch (v)
|
||||
{
|
||||
// these values are False=1, True=2
|
||||
case "1":
|
||||
value = false;
|
||||
break;
|
||||
case "2":
|
||||
value = true;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException($"{property.Name} {boolEncodedPosition} {value} {v}");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user