C# 将MVC路由参数解析为实例
是否可以通过控制器方法将路由参数从其字符串表示隐式转换为具有默认绑定器的对象实例 假设我有一个类BusinessObjectId,它包含两个属性,可以从/转换为字符串C# 将MVC路由参数解析为实例,c#,asp.net-mvc,routing,C#,Asp.net Mvc,Routing,是否可以通过控制器方法将路由参数从其字符串表示隐式转换为具有默认绑定器的对象实例 假设我有一个类BusinessObjectId,它包含两个属性,可以从/转换为字符串 public class BusinessObjectId { private static readonly IDictionary<bool, char> IdTypeMap = new Dictionary<bool, char> { [false] = 'c', [true] = 'd' }
public class BusinessObjectId
{
private static readonly IDictionary<bool, char> IdTypeMap = new Dictionary<bool, char> { [false] = 'c', [true] = 'd' };
private static readonly Regex StrIdPattern = new Regex("^(?<type>[cd]{1})(?<number>\\d+)$", RegexOptions.Compiled);
public long Id { get; set; }
public bool IsDraft { get; set; }
public BusinessObjectId() { }
public BusinessObjectId(long id, bool isDraft)
{
Id = id;
IsDraft = isDraft;
}
public BusinessObjectId(string strId)
{
if (string.IsNullOrEmpty(strId)) return;
var match = StrIdPattern.Match(strId);
if (!match.Success) throw new ArgumentException("Argument is not in correct format", nameof(strId));
Id = long.Parse(match.Groups["number"].Value);
IsDraft = match.Groups["type"].Value == "d";
}
public override string ToString()
{
return $"{IdTypeMap[IsDraft]}{Id}";
}
public static implicit operator string(BusinessObjectId busId)
{
return busId.ToString();
}
public static implicit operator BusinessObjectId(string strBussId)
{
return new BusinessObjectId(strBussId);
}
}
方法Sample1无法识别传入参数,且实例oSampleId为null。在方法Sample2中,字符串表示的隐式转换工作得很好,但我不想手动调用它。我找到了答案。。。您应该编写自定义TypeConverter,它可以从字符串转换BusinessObjectId类,并用属性修饰它
[TypeConverter(typeof(BusinessObjectIdConverter))]
public class BusinessObjectId
{ ... }
public class BusinessObjectIdConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
return new BusinessObjectId((string)value);
}
}
从现在起,您可以在控制器方法中使用BusinessObjectId作为参数,它将像一个符咒一样初始化:-)
请注意,另一个选择是创建自己的。尽管如此,我认为您的解决方案更适合这种特殊情况。
[TypeConverter(typeof(BusinessObjectIdConverter))]
public class BusinessObjectId
{ ... }
public class BusinessObjectIdConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
return new BusinessObjectId((string)value);
}
}
public class HomeController1 : Controller
{
[Route("sample1/{oSampleId:regex(^[cd]{1}\\d+$)}")]
public ActionResult Sample1(BusinessObjectId oSampleId)
{
// TODO: oSampleId is successfully parsed from it's string representations
}
}