2016-05-26 9 views
1

コントローラメソッドによるルート引数を、文字列表現からデフォルトのバインダを使用したオブジェクトのインスタンスに暗黙的に変換できますか?インスタンスへのMVCルート引数の解析

のは、私は2つのプロパティが含まれており、これらのactionlinksは素敵なURLに変換されます/文字列へ

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); 
    } 
} 

から変換することができますクラスBusinessObjectIdあるとしましょう:Html.ActionLink @

( "XXX" を、 "サンプル画像"、 "にHomeController"、新しい{(偽123)oSampleId =新しいBusinessObjectId} ... URL: "/ SAMPLE1/C123"

Html.ActionLink( "XXX"、 "サンプル1" @ "HomeController"、新しい{oSampleId =新しいB usinessObjectId(123、真)} ... 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(); 
    } 
} 

方法サンプル1はしていません入ってくる引数を認識し、インスタンスoSampleIdがnullです。メソッドSample2では、文字列represetationからの暗黙的な変換は正常に機能しますが、手動で呼び出すことは望ましくありません。

答えて

1

さて、私の答えは...あなたは、コントローラのメソッドのパラメータとして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を書くべきことがわかりましたそして、別のオプションは、独自の[値プロバイダ]を作成することであることに注意してください

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 
    } 
} 
+0

:-)魅力のように初期化されます(http://stackoverflow.com/questions/37302525/changing-url-parameters- with-routing-in-mvc-4/37329603#37329603)。あなたのソリューションは、この特定のケースではより良いと思います。 – NightOwl888