ロングタイムリーダー、初めてのポスター。Asp MVC 2既存の電子メールアドレスに対するリモート検証ですが、編集についてどうですか?
私はASP MVC 2とリモート検証を使用しています。 AddPersonVMとEditPersonVMが継承するPersonVMというモデルがあります。これは、両方のサブクラス化されたモデルの間で同じUIのほとんどを処理するために1つのusercontrolを使用できるようにするためです。
/// <summary>
/// This class handles adding and editing people.
/// </summary>
[MustHaveAtLeastOneOf("HomePhoneNumber", "CellPhoneNumber", ErrorMessage="At least one of the phone numbers must be filled in.")]
public abstract class PersonVM : WebViewModel
{
#region Reference (for Binding)
/// <summary>
/// Provides a list of person types, e.g. Teacher, Student, Parent.
/// </summary>
public IEnumerable<PersonType> ListOfPersonTypes {
get {
if (_listOfPersonTypes == null) {
_listOfPersonTypes = Data.PersonTypes
.Where(pt => pt.OrganizationID == ThisOrganization.ID || pt.OrganizationID == null)
.OrderBy(pt => pt.Name).ToArray();
}
return _listOfPersonTypes;
}
}
private IEnumerable<PersonType> _listOfPersonTypes = null;
/// <summary>
/// Provides a list of schools the person can belong to.
/// </summary>
public IEnumerable<School> ListOfSchools {
get {
if (_listOfSchools == null) {
_listOfSchools = Data.Schools
.Where(s =>
(s.OrganizationID == ThisOrganization.ID || s.OrganizationID == null) // TODO
&& s.Deleted == false
)
.OrderBy(s => s.Name);
}
return _listOfSchools;
}
}
private IEnumerable<School> _listOfSchools = null;
/// <summary>
/// Provides a list of contact types, e.g. Home phone, email.
/// </summary>
public IEnumerable<ContactType> ListOfContactTypes {
get {
if (_listOfContactTypes == null) {
_listOfContactTypes = Data.ContactTypes
.OrderBy(ct => ct.Name);
}
return _listOfContactTypes;
}
}
private IEnumerable<ContactType> _listOfContactTypes = null;
/// <summary>
/// Provides a list of genders.
/// </summary>
public IEnumerable<string> Genders {
get {
return new string[] { null, "Male", "Female" };
}
}
/// <summary>
/// Returns a list of US states.
/// </summary>
public List<StaticData.USState> ListOfUSStates {
get {
return StaticData.USStates;
}
}
#endregion
/// <summary>
/// Represents the current person being edited.
/// </summary>
public Person CurrentPerson { get; set; }
#region Abstracted Required Fields
/*
* This is done, since address information, DOB
* are not required on the panel, but are required fields here.
* I tried implementing an interface called IPersonAddressRequired
* with this information in it, but it didn't work. Additionally,
* only one instance of [MetadataType] is allowed on a class,
* so that didn't work either.
*/
[Required]
[StringLength(100)]
public string Address {
get { return CurrentPerson.Address; }
set { CurrentPerson.Address = value; }
}
[StringLength(100)]
public string Address2 {
get { return CurrentPerson.Address2; }
set { CurrentPerson.Address2 = value; }
}
[Required]
[StringLength(50)]
public string City {
get { return CurrentPerson.City; }
set { CurrentPerson.City = value; }
}
[Required]
[StringLength(50)]
public string State {
get { return CurrentPerson.State; }
set { CurrentPerson.State = value; }
}
[Required]
[StringLength(50)]
public string Zip {
get { return CurrentPerson.Zip; }
set { CurrentPerson.Zip = value; }
}
[DataType(DataType.Date)]
[Required]
public DateTime? DOB {
get { return CurrentPerson.DOB; }
set { CurrentPerson.DOB = value; }
}
[Required]
public string Gender {
get { return CurrentPerson.Gender; }
set { CurrentPerson.Gender = value; }
}
#endregion
#region Abstracted Contact Methods
/// <summary>
/// When adding someone, this represents the phone number contact record.
/// </summary>
[Display(Name = "Home Phone Number")]
[DisplayName("Home Phone Number")]
[USPhoneNumber]
//[Required]
public string HomePhoneNumber { get; set; }
/// <summary>
/// When adding someone, this represents the phone number contact record.
/// </summary>
[Display(Name = "Cell Phone Number")]
[DisplayName("Cell Phone Number")]
[USPhoneNumber]
//[Required]
public string CellPhoneNumber { get; set; }
/// <summary>
/// When adding someone, this represents the email address contact record.
/// </summary>
[Display(Name = "Email Address")]
[DisplayName("Email Address")]
[Required]
[UniqueEmailAddress(ErrorMessage="The email address was already found in our system, please sign in or use another email.")]
[Email(ErrorMessage="The email address specified isn't an email address.")]
public string EmailAddress { get; set; }
#endregion
//////////////////////////////
/// <summary>
/// Sets the picture to be uploaded.
/// </summary>
public byte[] PictureData { get; set; }
/// <summary>
/// One of 'keep', 'remove', 'replace'.
/// </summary>
public string PictureAction { get; set; }
}
私はこのモデル(AddPersonVMとEditPersonVM)を継承した2つのモデルを持っています。それぞれは、変更の仕方を少し違って処理する方法を実装しています。
[UniqueEmailAddress]は私のRemoteAttributeで、既存の電子メールアドレスと問題のあるものを確認します。
誰かを追加してもうまくいきますが、既存の人物を編集すると、既に保存されている電子メールアドレスがメンバーシップシステムに存在するため、検証に失敗します。私がしたいのは、プロパティの値の元の値を保存し、それをIsValidのチェックから除外することです。
マイコード:
/// <summary>
/// Checks to be sure that an entered email address is unique.
/// </summary>
public class UniqueEmailAddressAttribute : RemoteAttribute
{
/// <summary>
/// Returns true if the email address specified is currently in use.
/// </summary>
/// <param name="emailAddress"></param>
/// <returns></returns>
public static bool IsEmailAddressInUse(string emailAddress) {
return (Membership.FindUsersByEmail(emailAddress).Count != 0);
}
///////////////////////////
public UniqueEmailAddressAttribute() : base("UniqueEmailAddress", "RemoteValidation", "emailAddress") { }
///////////////////////////
public override bool IsValid(object value) {
// If value is null, return true, since a [Required] attribute handles required values.
if (value == null)
return true;
// Value must be a string.
if (!(value is string))
return false;
// We're not checking the validity of the email address here,
// the [EmailAddress] attribute handles that for us.
// Check the email's uniqueness.
return !IsEmailAddressInUse((string)value);
}
}
私が持っていると思い何を:
/// /// Checks to be sure that an entered email address is unique. /// public class UniqueEmailAddressAttribute : RemoteAttribute {
string OriginalValue = null;
/// <summary>
/// Returns true if the email address specified is currently in use.
/// </summary>
/// <param name="emailAddress"></param>
/// <returns></returns>
public static bool IsEmailAddressInUse(string emailAddress) {
return (Membership.FindUsersByEmail(emailAddress).Count != 0);
}
///////////////////////////
public UniqueEmailAddressAttribute() : base("UniqueEmailAddress", "RemoteValidation", "emailAddress") {
OriginalValue = value Found using reflection or something;
}
///////////////////////////
public override bool IsValid(object value) {
// If value is null, return true, since a [Required] attribute handles required values.
if (value == null)
return true;
// Value must be a string.
if (!(value is string))
return false;
// We're not checking the validity of the email address here,
// the [EmailAddress] attribute handles that for us.
if ((string)value == OriginalValue)
return true;
// Check the email's uniqueness.
return !IsEmailAddressInUse((string)value);
}
}
任意のアイデア?現時点では、EmailAddressプロパティをAddPersonVMとEditPersonVMの両方に個別に追加し、自分のusercontrolビューからフィールドを取り出して両方のビューに追加し、Editで属性を削除することができましたが、彼らが望む電子メールアドレス。元の値を読み取るために反射が必要な場合は気にしません。
ありがとうございます! - Derreck
上記のコードであなたの質問に無関係なノイズが多すぎます。可読性のために関連するコードを修正して投稿することができます – swapneel
同じ問題があります。 – Paul
@swapneel最初に投稿したときに、コードから無関係な情報をたくさん整えました。より多くのコードを整えることができると確信していますが、私はインフラストラクチャの観点から何か間違ったことをしている場合、誰かがそれを指摘することを望んでいます。 –