5

2 つの異なるビューのモデルとして使用している 2 つのクラスがあります。2 番目のクラスには最初のクラスのインスタンスが含まれていることがわかります。1 つ目は、リモート検証属性を含みます。

[MetadataType( typeof( ExceptionLogModel.EmailRecipientMetadata ) )]
public class EmailRecipientViewModel
{
    public int EmailRecipientID { get; set; }

    [Remote( "ValidateEmailRecipientNameUniqueness", "EmailRecipient", ErrorMessage = "Name is not unique." )]
    public string Name { get; set; }

    [Remote( "ValidateEmailRecipientEmailUniqueness", "EmailRecipient", ErrorMessage = "Email is not unique." )]
    public string Email { get; set; }
}

public class EmailRecipientChoices
{
    public List<EmailRecipient> UnselectedEmailRecipients { get; set; }
    public List<EmailRecipient> SelectedEmailRecipients { get; set; }
    public EmailRecipientViewModel EmailRecipient { get; set; }
}

これらの検証がブラウザーでトリガーされると、ビューが使用したクラスに応じて 2 つの異なる要求が行われます。クエリ文字列パラメーター名が異なることがわかります。

http://localhost:55327/EmailRecipient/ValidateEmailRecipientNameUniqueness?Name=sdhsdgh

http://localhost:55327/EmailRecipient/ValidateEmailRecipientNameUniqueness?EmailRecipient.Name=sdhsdgh

2 番目の URL では機能しないアクション メソッドの現在のバージョンを次に示します。

public JsonResult ValidateEmailRecipientNameUniqueness( string name )
{
    var isValid = !_emailRecipientRepo.NameExists( name );

    return Json( isValid, JsonRequestBehavior.AllowGet );
}

2 番目の URL を使用すると、name パラメータは null になります。そのパラメーターに Bind 属性を追加してプレフィックスを追加できるはずだと読みましたが、これも機能していません。EmailRecipient.ドットが必要な場合に備えて、プレフィックスを に設定してみました。念のため、Name に大文字の N を付けてみました。立ち入り禁止。これを追加すると、他の URL でも壊れます。

public JsonResult ValidateEmailRecipientNameUniqueness( [Bind( Prefix = "EmailRecipient")] string name )

可能な解決策

メソッドで EmailRecipientViewModel のインスタンスを取得し、そのインスタンスの IModelBinder を作成して、いずれかの命名規則を探してインスタンスに割り当てることができます。これは、必要以上の作業のようです。

のオーバーロードを使用して@Html.EditorFor()、htmlFieldName に「Name」を使用するように指示し@Html.ValidationMessage( "Name" )ValidationMessageFor. これの唯一の欠点は潜在的な名前の競合ですが、それは大した問題ではありません。使用されているこのクラスのすべてのインスタンスに一意の名前を使用する必要があります。更新:実際、これを行うと、名前を変更したため、フォームを投稿すると問題が発生します。それは良くないね。

...

メソッドにパラメーターを持たせず、クエリ文字列に手動でアクセスできることがわかりました。これは非常に単純な解決策ですが、nice パラメーターが得られません。

string name = Request.QueryString[ "Name" ] ?? Request.QueryString[ "EmailRecipient.Name" ];

これは簡単なので、おそらくこれを使用するだけです。しかし、私はすでにこの質問を入力しているので、もっと洗練された解決策はありますか?

4

2 に答える 2

3

まあ、これが遅いことはわかっていますが、もっとエレガントな解決策があります:

public JsonResult ValidateEmailRecipientNameUniqueness (EmailRecipient recipient)
{
    string name = recipient.Name;
    var isValid = !_emailRecipientRepo.NameExists(name);
    return Json(isValid, JsonRequestBehavior.AllowGet);
}

つまり、モデル自体を使用します。プロパティが正しくバインドされ、nameこの値のみが必要になります。

于 2015-03-05T12:43:01.110 に答える
1

独自の検証またはモデル バインダーをロールバックせずにこれを行うには、実際にはクリーンな方法はありません。モデル バインディングのように考えてください。モデル バインダーは、リモート検証と同じように、入ってくるものの名​​前を知る必要があります。実行できる 1 つの方法は、実際にすべての検証作業を行う 1 つのメソッドを最終的に呼び出す 2 つの別個のリモート検証メソッドをコントローラーに作成することです。

于 2011-04-14T04:45:27.320 に答える