Remote -Validierung scheint fehlerhaft zu sein
-
22-10-2019 - |
Frage
Stellen Sie sich diese Situation vor:
Konfiguration
Erstellen Sie im Standard -MVC3 -Projekt einen neuen komplexen Typ in der 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; }
}
In dem RegisterModel
ändere das UserName
zu:
[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; }
Das UserNameExists
Methode in a Validation
Controller ist wie folgt:
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);
}
}
Verwenden Sie jetzt in der Registeransicht das GlobalAccount
Modell anstelle der RegisterModel
Das Benutzername -Eingangsfeld ist wie:
@model Your.NameSpace.Models.GlobalAccount
und
<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>
Dies wird in der HTML zu so etwas führen
<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>
Debuggen
Wenn Sie Firebug verwenden, um zu überprüfen, was los ist ... die Fernvalidierung Sendet das Attribut Name anstelle des Attributs Ich würde zur Validierungsmethode (die UserNameExists
eins) als:
Register.UserName
Anstatt von Register_UserName
Ich kann diesen Wert also nicht holen ... je :(
Ist das wirklich ein Fehler oder ist etwas, das jemand bereits gefunden hat und ich konnte nicht vom Googeln bekommen?
Hier ist ein einfaches Bild des tatsächlichen Problems:
Lösung
Wie wäre es mit:
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);
}
Eine andere Möglichkeit besteht darin, ein spezielles Ansichtsmodell zu definieren:
public class UserNameExistsViewModel
{
public string UserName { get; set; }
}
und dann:
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);
}
Was ärgerlich ist, ist, dass das Folgende nicht funktioniert:
public ActionResult UserNameExists(
[Bind(Prefix = "Register")]string UserName
)
Gehen Sie Abbildung :-) Ich würde wahrscheinlich mit einem benutzerdefinierten Ansichtsmodell gehen. Es sieht sauberste aus.
Andere Tipps
Ich weiß, dass dies als beantwortet markiert ist, aber da ich das gleiche Problem habe, dachte ich, ich würde eine weitere Variation beibringen, die für mich funktioniert.
Die Klasse in meinem Fall ist "Food" und das Feld, das ich versuche, um zu validieren, ist "Name". Das Textfeld wird von einem Editor für Steuerung erstellt:
@Html.EditorFor(model => model.Name)
Remote -Validierung wird auf dem Feld der Lebensmittelklasse festgelegt:
[Remote("FoodNameExists")]
public string Name { get; set; }
Und dies nennt eine Methode:
public ActionResult FoodNameExists(string Name) {
Nach der ursprünglichen Frage, anstatt dass diese an die FoodNamexists -Methode als "Name" oder sogar "food_name" übergeben wird, ist es der vom Editor for Helfer erstellte ID -Wert, das als Namensattribut "Food" übergeben wird. Name "... was natürlich nicht etwas ist, das ich als Eingabeparameter festlegen kann.
Mein Hack ist es also einfach, die Eingabeparameter zu ignorieren und im QueryString zu schauen:
var name = Request.QueryString["Food.Name"];
... Dies gibt den richtigen Wert zurück, gegen den ich validiere, und ich mache mich auf den Weg zu den Rennen.
Dies ist der einfachste Weg, den ich dafür fand, nur Daten-Val hinzuzufügen.- Attribute in htmlattributes von DropdownListfor in der Ansicht. Die folgende Methode funktioniert auch mit RemoteValidation. Wenn Sie keine Remote-Validierung benötigen, entfernen Sie einfach die Elemente, die Daten-Val-Remote enthalten-*:
@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" } })
Ich hoffe, es kann helfen. Mit freundlichen Grüßen!