之前寫過一篇ASP.NET MVC使用 DataAnnotations 屬性顯示欄位的中文名稱,當然也可以用Required屬性來驗證該欄位在前端網頁是否必填。
但是我想指定其中兩個欄位是至少要一個必填就好了的話,是否也可以透過屬性來驗證呢?
當然可以,不過這得要借助自訂屬性來處理。
假設我有一個資料表:Customer,這個資料表放的資料如(圖一)所示
(圖一)
建完Controller&View,同時也將Csutomer.partial.cs也建立好,我期望是每個欄位都要輸入,所以將Required屬性都加上去。
[MetadataType(typeof(CustomerMD))]
public partial class Customer
{
public class CustomerMD
{
[Required]
[Display(Name ="姓名")]
public string name { get; set; }
[Required]
[Display(Name = "市話")]
public string phone { get; set; }
[Required]
[Display(Name = "行動電話")]
public string mobile { get; set; }
[Required]
[Display(Name = "地址")]
public string address { get; set; }
}
}
所以跑出來的結果就會是像(圖二)這樣
(圖二)
實際考量後,其實『市話』跟『行動電話』兩者不一定都會有,所以要調整成『市話』跟『行動電話』至少填一個。
但是Required屬性沒辦法達到我想要的需求,所以自己來定義一個屬性
首先,先新增一個class,我自定義名稱為CustomRequired,繼承ValidationAttribute,詳細做法如下
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
namespace WebApplication1.Models
{
//因為我屬性要只能套用至Class,所以我在下方要加上這段
[AttributeUsage(AttributeTargets.Class)]
public class CustomRequired : ValidationAttribute
{
/// <summary> 傳入要綁一起的欄位名稱
/// </summary>
public string[] arg { get; private set; }
/// <summary> 建構子
/// </summary>
/// <param name="_arg"></param>
public CustomRequired(params string[] _arg)
{
this.arg = _arg;
}
//覆寫IsValid
public override bool IsValid(object value)
{
var result = ValidationResult.Success;
var typeInfo = value.GetType();
var propertyInfo = typeInfo.GetProperties();
//如果有傳入欄位名稱,則驗證這些欄位名稱是否有值,只要有一個有值,就回傳true
if (this.arg != null)
{
foreach (string item in this.arg)
{
if (propertyInfo.Where(p => p.Name == item).FirstOrDefault() != null)
{
if (propertyInfo.Where(p => p.Name == item).First().GetValue(value, null) != null)
{
return true;
}
}
}
}
///若走到這一步,表示沒有一個欄位有值,這就不符合我們預期的至少一個欄位必填的原則,於是回傳false
///其中ErrorMessage可以在設定屬性的時候給予。
result = new ValidationResult(ErrorMessage);
return false;
}
}
}
設定完後,就可以在Customer.partial.cs上動手腳了,在上方加入剛剛自訂好的屬性,然後將phone與mobile的Required屬性拿掉。
public partial class Customer
{
[CustomRequired("phone", "mobile", ErrorMessage = "『市話』跟『行動電話』至少填一個")]
public class CustomerMD
{
[Required]
[Display(Name = "姓名")]
public string name { get; set; }
[Display(Name = "市話")]
public string phone { get; set; }
[Display(Name = "行動電話")]
public string mobile { get; set; }
[Required]
[Display(Name = "地址")]
public string address { get; set; }
}
}
然後去新增畫面輸入姓名與地址,接著直接按下Create,登登~~
(圖三)
如(圖三)所示,出現了紅框部分,而顯示的訊息就如在程式指定的訊息。
總結:
這個是不是相當有趣呢,當然不只是Class可以設定,也可以針對欄位做這樣的自定屬性功能,這樣做對我來說好處挺大的,不需要再撰寫一堆JavaScript去判斷。
另外也可以撰寫判斷兩個時間欄位起迄或是限制區間多少...等等,這樣做成共用的模組也是挺方便的。
參考資料
本著作由Chenting Weng製作,以創用CC 姓名標示 4.0 國際 授權條款釋出。
This work by Chenting Weng is licensed under a Creative Commons Attribution 4.0 International License.
Based on a work at https://dotblogs.com.tw/chentingw.
部分文章內容會引用到其他網站的簡介或圖片,若有侵犯到您的著作權,請留言告知,本人會儘快移除。
免責聲明:文章屬個人記事使用,僅供參考,若引用文章造成一切損失,本人不承擔任何責任。如有錯誤,歡迎留言告知。
Part of the content of the article will refer to the profile or picture of other websites.
If there is any infringement of your copyright, please leave a message and let me remove it as soon as possible.
Disclaimer:The article is for personal use and is for reference only. I will not bear any responsibility for any loss caused by quoting the article. If there is an error, please leave a message to inform.