Удаленная проверка кажется глючной - PullRequest
3 голосов
/ 27 апреля 2011

представьте себе такую ​​ситуацию:

SetUp

в проекте 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 для метода проверки (UserNameExists один) как:

Register.UserName вместо Register_UserName

Так что я не могу получитьэто значение ... когда-либо : (

Это действительно ошибка или это то, что кто-то уже нашел, и я не смог получить его из Google?

Вотпростое изображение фактическогопроблема:

enter image description here

Ответы [ 3 ]

9 голосов
/ 27 апреля 2011

Как насчет:

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

Другая возможность заключается в определении модели специального вида:

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
)

Пойди сюда :-) Я бы, наверное, выбрал модель с пользовательским представлением.Это выглядит самым чистым.

2 голосов
/ 16 мая 2011

Я знаю, что это помечено как отвеченное, но, поскольку у меня возникла та же проблема, я подумал, что внесу еще один вариант, который работает для меня.

Класс в моем случае - "Еда"поле, которое я пытаюсь удаленно проверить, является "Имя".Текстовое поле создается элементом управления EditorFor:

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

Удаленная проверка устанавливается в поле класса Food:

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

И это вызывает метод:

public ActionResult FoodNameExists(string Name) {

В соответствии с исходным вопросом, вместо того, чтобы передавать его методу FoodNameExists как «Name» или даже «Food_Name», которое является значением Id, созданным помощником EditorFor, он передается как атрибут name, который«Food.Name» ... что, конечно, я не могу установить в качестве входного параметра.

Итак, мой хак - просто игнорировать входные параметры и смотреть в QueryString:

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

... это возвращает правильное значение, с которым я проверяю, и я отправляюсь в гонки.

0 голосов
/ 17 февраля 2012

Это самый простой способ сделать это, просто добавив атрибуты data-val- - в HtmlAttributes DropDownListFor внутри представления. Следующий метод также работает с 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" } })

Надеюсь, это может помочь. С наилучшими пожеланиями!

...