13

MVC 2、3、または 4 の ASP.NET コントローラーの既定のモデル バインディング動作に、フォーム要素からのダッシュを収容する方法を見つけようとして、インターネットを精査してきました。

フロントエンド開発者として、CSS ではキャメルケースやアンダースコアよりもダッシュを好みます。私のマークアップでは、私ができるようにしたいのは次のようなものです:

<input type="text" name="first-name" class="required" />
<input type="text" name="last-name" class="required" />

コントローラーでは、次のような C# オブジェクトを渡します。

public class Person
{
      public string FirstName { get; set; }
      public string LastName { get; set; }
      //etc...
}

Controllerいくつかの正規表現またはその他の動作を通じてこれに対応するためにクラスを拡張する方法はありますか? 私はこのようなことをしなければならないという事実が嫌いです:

<input type="text" name="person.firstname" class="required" />

またはこれさえ:

<input type="text" name="isPersonAttending" class="required" />

考え?

4

3 に答える 3

7

いつでも独自のモデル バインダーを作成できます。

モデル プロパティへのエイリアスの追加をサポートするバインダーを実装する例を次に示します。

http://ole.michelsen.dk/blog/bind-a-model-property-to-a-different-named-query-string-field/

そしてそれで次のようなことをします:

[ModelBinder(typeof(AliasModelBinder))]
public class Person
{
      [BindAlias("first-name")]
      public string FirstName { get; set; }
      [BindAlias("last-name")]
      public string LastName { get; set; }
      //etc...
}

編集: ブロガーが言うように、この実装は、次の SO の質問に対する Andras の回答に基づいています: Asp.Net MVC 2 - モデルのプロパティを別の名前付きの値にバインドする

于 2012-06-23T22:36:32.287 に答える
3

カスタム フォーム値プロバイダーを作成することで、この問題を簡単に解決できます。もう 1 つの利点は、カスタム属性を装飾することで、すべてのモデル プロパティの汚染を回避できることです。

カスタム フォーム値プロバイダー

public class DashFormValueProvider : NameValueCollectionValueProvider
{
    public DashFormValueProvider(ControllerContext controllerContext)
    : base(controllerContext.HttpContext.Request.Form, 
    controllerContext.HttpContext.Request.Unvalidated().Form, 
    CultureInfo.CurrentCulture)
    {
    }

    public override bool ContainsPrefix(string prefix)
    {
        return base.ContainsPrefix(GetModifiedPrefix(prefix));
    }

    public override ValueProviderResult GetValue(string key)
    {
        return base.GetValue(GetModifiedPrefix(key));
    }

    public override ValueProviderResult GetValue(string key, bool skipValidation)
    {
        return base.GetValue(GetModifiedPrefix(key), skipValidation);
    }

    // this will convert the key "FirstName" to "first-name".
    private string GetModifiedPrefix(string prefix)
    {
        return Regex.Replace(prefix, "([a-z](?=[A-Z])|[A-Z](?=[A-Z][a-z]))", "$1-").ToLower();
    }
}

バリュー プロバイダー ファクトリー

public class DashFormValueProviderFactory : ValueProviderFactory
{
    public override IValueProvider GetValueProvider(ControllerContext controllerContext)
    {
        if (controllerContext == null)
        {
            throw new ArgumentNullException("controllerContext");
        }

        return new DashFormValueProvider(controllerContext);
    }
}

Global.asax.cs

ValueProviderFactories.Factories.Add(new DashFormValueProviderFactory());
于 2012-06-24T06:30:19.523 に答える
2

ASP.NET Core ソリューションを探している読者は、いずれかの[From...]属性を試してください。例えば:

public class Person
{
    [FromForm(Name = "first-name")]
    public string FirstName { get; set; }
    [FromForm(Name = "last-name")]
    public string LastName { get; set; }
    //etc...
}

[From...]属性については、https://docs.microsoft.com/en-us/aspnet/core/mvc/models/model-binding?view=aspnetcore-3.1#sourcesで簡単に説明されています。

于 2020-04-16T16:24:47.890 に答える