基於easyui的webform擴展(續)

回顧html

  《前端基於easyui的mvc擴展》《前端基於easyui的mvc擴展(續)》《基於easyui的webform擴展》這幾篇講解了如何在mvc以及web form內來實現前端使用easyui以及在後端使用基於ValidationAttribute進行驗證(mvc自己就有支持),可是這都是以Framework4.0爲基礎的,那麼當咱們遇到3.5或者是更早之前的版本的時候,如今這套應用就須要從新重構了。前端

  首先來梳理一下整個流程,大體的流程以下:web

  1. 經過調用須要展現的控件方法
  2. 解析屬性上的驗證元數據
  3. 生成符合easyui驗證規則的html
  4. 提交表單到後端
  5. 對錶單轉化後的對象進行驗證
  6. 若是經過驗證則能夠對對象進行操做,不經過則直接返回

  mvc和web form在前端的方式基本上都是用同樣的,那麼也就是說要讓咱們編寫的代碼能支持更多的版本的狀況下,假如咱們本身實現一套驗證特性的話,那麼只要讓前端生成的規則保持一致,後端的話,只有web form是本身去驗證這一步的。express

實現後端

  那麼參考前幾篇的結果以及ValidationAttribute,咱們很快便能整理出一套跟ValidationAttribute類似的驗證特性了,部分代碼以下:mvc

//驗證基類
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = false)]
public abstract class CustomValidationBaseAttribute : Attribute
{
    private object m_Model = null;
    protected object Model { get { return m_Model; } }

    private string m_ErrorMessage = null;
    public string ErrorMessage
    {
        get { return m_ErrorMessage; }
        set { m_ErrorMessage = value; }
    }

    public bool IsValid(object model, object value)
    {
        if (model == null)
            return false;

        m_Model = model;
        return IsValid(value);
    }

    public virtual string FormatErrorMessage(string displayName)
    {
        return string.Format(ErrorMessage, displayName);
    }

    protected abstract bool IsValid(object value);
}

//必填特性
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public class CustomRequiredAttribute : CustomValidationBaseAttribute
{
    protected override bool IsValid(object value)
    {
        return value != null && !string.IsNullOrEmpty(value.ToString());
    }
}

  有了特性,那麼接下來只要根據不一樣的環境,來生成相同的easyui驗證規則就能夠了。ide

  首先分析一下各類控件的規則,主要有如下3種狀況:ui

  1. linkbutton這種不須要進行數據綁定,只要顯示文本或某些屬性的
  2. validatebox、numberbox、combobox等是須要解析表達式,在model存在的狀況下,要顯示出值的
  3. Label只要顯示屬性上配置的DisplayName的,雖然不是easyui的控件,可是2裏面的控件共用表達式樹的解析

  其實以上2-3的區別僅僅是在控件上添加一個屬於easyui的樣式表而已,因而使用以下2中類來區分以上3種狀況,代碼以下:this

internal class BuilderBase
{
    public BuilderBase(string tag, string attributeJson) : this(tag, null, attributeJson) { }

    public BuilderBase(string tag, string control, string attributeJson)
    {
        //省略,文章最後提供詳細源碼
    }

    //擴展Builder,好比Linkbutton要添加文本或其餘編輯控件要增長name及驗證規則
    protected virtual void ExpandFor(TagBuilder builder) { }
}

internal class ParseExpressionBuilder : BuilderBase
{
    public ParseExpressionBuilder(string tag, Expression<Func<TModel, object>> expression, string attributeJson) : this(tag, null, expression, default(TModel), attributeJson) { }

    public ParseExpressionBuilder(string tag, string control, Expression<Func<TModel, object>> expression, TModel model, string attributeJson) : base(tag, control, attributeJson)
    {
        //略
    }

    protected override void ExpandFor(TagBuilder builder)
    {
        //略
    }

    //此方法用來處理不一樣控件的綁定值操做
    protected virtual void AppendValue(ref TagBuilder builder, object value)
    {
        if (value != null)
            builder.AddAttribute("value", value.ToString());
    }
}

   這裏將具體的生成規則都放在了一些列的Builder內,可是爲了保證在mvc和web form內能生成相同easyui的easyui規則,因爲咱們自定義的規則是參考ValidationAttribute的,所以咱們只要根據接口來實現咱們自定義的那一部分就能夠了,其實只要適當的修改第一篇文章內的生成規則即可以完工了,部分代碼以下:spa

//這裏挑選了必填驗證的代碼,跟以前的相比僅僅是驗證特性的對象不一樣而已
var attribute = validationAttrs.FirstOrDefault(attr => attr is CustomRequiredAttribute);
if (attribute != null)
{
    tag.AddAttribute("required", "true");
    tag.AddAttribute("missingMessage", attribute.ErrorMessage);
}

  而上篇提到的EasyUIHelper僅僅是提供給外部生成的公用方法而已,它的代碼大體以下:

public class EasyUIHelper
{
    public static string Label(Expression<Func<TModel, object>> expression, string attributeJson)
    {
        return new LabelBuilder(expression, attributeJson);
    }

    public static string ValidateText(Expression<Func<TModel, object>> expression, TModel model, string attributeJson)
    {
        return new ValidateboxBuilder(expression, model, "text", attributeJson);
    }
    //針對3.5的其餘重構和其餘方法省略,具體請看源碼
}

   完成了前端的生成規則之後,接下來就是對於後端驗證進行重構了,代碼與以前的差異不大,僅僅是把本來基於ValidationAttribute改成基於CustomValidationBaseAttribute來完成,爲了節省篇幅代碼就不寫了,具體的能夠查看源碼。

結尾

  因爲本篇是基於前幾篇的一個總結和對以前版本的兼容,所以內容相對比較少,若是對這幾篇的內容有什麼問題請指出,謝謝你們,另外源碼在此(從代碼庫中抽出來的一部分)。

相關文章
相關標籤/搜索