【发布时间】:2016-09-24 13:06:02
【问题描述】:
是否可以通过控制器方法将路由参数从其字符串表示形式隐式转换为具有默认 Binder 的对象的实例?
假设我有一个类 BusinessObjectId,它包含两个属性并且可以从字符串转换为字符串
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);
}
}
这些操作链接被翻译成漂亮的网址:
@Html.ActionLink("xxx", "Sample1", "HomeController", new { oSampleId = new BusinessObjectId(123, false) } ... url:"/sample1/c123"
@Html.ActionLink("xxx", "Sample1", "HomeController", new { oSampleId = new BusinessObjectId(123, true) } ... url:"/sample1/d123"
然后我想像这样在控制器方法中使用参数:
public class HomeController1 : Controller
{
[Route("sample1/{oSampleId:regex(^[cd]{1}\\d+$)}")]
public ActionResult Sample1(BusinessObjectId oSampleId)
{
// oSampleId is null
throw new NotImplementedException();
}
[Route("sample2/{sSampleId:regex(^[cd]{1}\\d+$)}")]
public ActionResult Sample2(string sSampleId)
{
BusinessObjectId oSampleId = sSampleId;
// oSampleId is initialized well by implicit conversion
throw new NotImplementedException();
}
}
方法 Sample1 无法识别传入参数并且实例 oSampleId 为空。在方法 Sample2 中,从字符串表示进行隐式转换效果很好,但我不想手动调用它。
【问题讨论】:
标签: c# asp.net-mvc routing