3

この状況を想像してください:

設定

デフォルトの MVC3 プロジェクトで、新しい複合型をAccountModels.cs

public class GlobalAccount
{
    public GlobalAccount()
    {
        this.LogOn = new LogOnModel();
        this.Register = new RegisterModel();
    }

    public LogOnModel LogOn { get; set; }
    public RegisterModel Register { get; set; }
}

を次のようにRegisterModel変更UserNameします。

[Required]
[Remote("UserNameExists", "Validation", "", ErrorMessage = "Username is already taken.")]
[RegularExpression(@"(\S)+", ErrorMessage = "White space is not allowed.")]
[Display(Name = "Username (spaces will be stripped, must be at least 6 characters long)")]
public string UserName { get; set; }

コントローラーのUserNameExistsメソッドは次のとおりです。Validation

public class ValidationController : Controller
{
    public JsonResult UserNameExists(string UserName)
    {
        string user = null;
        if (!String.IsNullOrWhiteSpace(UserName) && UserName.Length >= 6)
            user = UserName == "abcdef" ? "ok" : null;

        return user == null ?
            Json(true, JsonRequestBehavior.AllowGet) :
            Json(string.Format("{0} is not available.", UserName), JsonRequestBehavior.AllowGet);
    }
}

登録ビューで、GlobalAccount代わりにモデルを使用しますRegisterModel

ユーザー名入力ボックスは次のようになります。

@model Your.NameSpace.Models.GlobalAccount

 <div class="field fade-label">
    @Html.LabelFor(model => model.Register.UserName, new { @class = "text" })
    @Html.TextBoxFor(model => model.Register.UserName, new { spellcheck = "false", size = "30" })
</div>

これにより、HTMLで次のような結果になります

<div class="field fade-label">
    <label class="text" for="Register_UserName"><span>Username (spaces will be stripped, must be at least 6 characters long)</span></label>
    <input data-val="true" data-val-regex="White space is not allowed." data-val-regex-pattern="(\S)+" data-val-remote="Username is already taken." data-val-remote-additionalfields="*.UserName" data-val-remote-url="/beta/Validation/UserNameExists" data-val-required="The Username (spaces will be stripped, must be at least 6 characters long) field is required." id="Register_UserName" name="Register.UserName" size="30" spellcheck="false" type="text" value="">
</div>

デバッグ

FireBugを使用して何が起こっているかを確認すると...リモート検証は、属性IDの代わりに属性を検証メソッド(1つ)に次のように送信しています。UserNameExists

Register.UserNameそれ以外のRegister_UserName

だから私はこの値を取得することはできません...今まで:(

これは本当にバグなのか、それとも誰かがすでに発見したもので、Google で調べてもわからなかったのでしょうか?

実際の問題の簡単なイメージを次に示します。

ここに画像の説明を入力

4

3 に答える 3

9

どうですか:

public ActionResult UserNameExists(
    [Bind(Include = "UserName")]RegisterModel register
)
{
    string user = null;
    if (!String.IsNullOrWhiteSpace(register.UserName) && register.UserName.Length >= 6)
        user = register.UserName == "abcdef" ? "ok" : null;

    return user == null ?
        Json(true, JsonRequestBehavior.AllowGet) :
        Json(string.Format("{0} is not available.", register.UserName), JsonRequestBehavior.AllowGet);
}

もう 1 つの可能性は、特別なビュー モデルを定義することです。

public class UserNameExistsViewModel
{
    public string UserName { get; set; }
}

その後:

public ActionResult UserNameExists(UserNameExistsViewModel register)
{
    string user = null;
    if (!String.IsNullOrWhiteSpace(register.UserName) && register.UserName.Length >= 6)
        user = register.UserName == "abcdef" ? "ok" : null;

    return user == null ?
        Json(true, JsonRequestBehavior.AllowGet) :
        Json(string.Format("{0} is not available.", register.UserName), JsonRequestBehavior.AllowGet);
}

厄介なのは、次のことが機能しないことです。

public ActionResult UserNameExists(
    [Bind(Prefix = "Register")]string UserName
)

図を見てください:-)私はおそらくカスタムビューモデルを使用します。一番きれいに見えます。

于 2011-04-27T07:47:56.123 に答える
2

私はこれが回答済みとしてマークされていることを知っていますが、私は同じ問題を抱えているので、私のために働いている別のバリ​​エーションを提供すると思いました。

私の場合のクラスは「Food」で、リモート検証しようとしているフィールドは「Name」です。テキストボックスは、EditorForコントロールによって作成されています。

@Html.EditorFor(model => model.Name)

リモート検証は、Foodクラスフィールドに設定されています。

[Remote("FoodNameExists")]
public string Name { get; set; }

そして、これはメソッドを呼び出します:

public ActionResult FoodNameExists(string Name) {

元の質問によると、これは「Name」としてFoodNameExistsメソッドに渡されるのではなく、EditorForヘルパーによって作成されたId値である「Food_Name」でさえも、「Food」であるname属性として渡されます。名前」...もちろん、入力パラメータとして設定できるものではありません。

したがって、私のハックは、入力パラメータを無視してQueryStringを調べることです。

var name = Request.QueryString["Food.Name"];

...これは正しい値を返します。これに対して検証し、レースに出かけます。

于 2011-05-15T23:55:35.773 に答える
0

これは私が見つけた最も簡単な方法で、ビュー内の DropDownListFor の HtmlAttributes に data- val- -属性を追加するだけです。次のメソッドは RemoteValidation でも機能します。リモート検証が必要ない場合は、data-val-remote-* を含む要素を削除するだけです。

        @Html.DropDownListFor(m => m.yourlistID, (IEnumerable<SelectListItem>)ViewBag.YourListID, String.Empty, 
        new Dictionary<string, object>() { { "data-val", "true" }, 
        { "data-val-remote-url", "/Validation/yourremoteval" }, 
        { "data-val-remote-type", "POST" }, { "data-val-remote-additionalfield", "youradditionalfieldtovalidate" } })

それが役立つことを願っています。よろしくお願いします!

于 2012-02-17T10:49:59.567 に答える