1

誰かが私を助けてくれることを願っています。Web サイトの UI と同じオブジェクトを使用する Web サービスの両方に個別のメソッドを記述する必要はなく、オブジェクトにカスタム検証コードを直接記述したいと考えています。これは私が現在持っているコードです。これは機能しますが、特に標準の文字列/整数などを本当に使用したいオブジェクトを使用する必要があることを意味するため、これが最善の解決策だとは思いません。オブジェクトのプロパティで属性を使用できますが、属性の値を設定できないため、そのアイデアは窓の外に出ました。どんな助けでもありがたく受け取られます。

敬具、アレックス

<%@ Register src="TextBoxControl.ascx" tagname="TextBoxControl" tagprefix="uc1" %>

<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">

<asp:ValidationSummary ID = "VS" runat="server" />
Name: <uc1:TextBoxControl ID="NameTextBox" runat="server" ErrorMessage="Name is required" />
<br />Postcode:  <uc1:TextBoxControl ID="PostcodeTextBox" runat="server" ErrorMessage="Postcode is required" />
 <asp:Button ID="SubmitButton" runat="server" Text="Submit" OnClick="SubmitButton_OnClick" />
</asp:Content>


public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }
    protected void SubmitButton_OnClick(object sender, EventArgs e)
    {
        MyObject obj = new MyObject();
        obj.Name = new ValidatedString(NameTextBox.Text);
        obj.Postcode = new ValidatedString(PostcodeTextBox.Text);

        NameTextBox.IsValid = obj.Name.Valid;
        NameTextBox.CustomError = obj.Name.GetErrors();
        PostcodeTextBox.IsValid = obj.Postcode.Valid;
        PostcodeTextBox.CustomError = obj.Postcode.GetErrors();
    }
}

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="TextBoxControl.ascx.cs"     Inherits="WebApplication1.TextBoxControl" %>
 <asp:TextBox ID="ValueTextBox" runat="server"></asp:TextBox>
   <asp:CustomValidator ID="CV" runat="server" ControlToValidate="ValueTextBox">*    </asp:CustomValidator>
   <asp:RequiredFieldValidator ID="RFV" runat="server" ControlToValidate="ValueTextBox">*</asp:RequiredFieldValidator>

 public partial class TextBoxControl : System.Web.UI.UserControl
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    public string Text
    {
        get
        {
            return ValueTextBox.Text;
        }
    }

    public string ErrorMessage
    {
        set
        {
            RFV.ErrorMessage = value;
        }
    }

    public bool IsValid
    {
        set
        {
            CV.IsValid = value;
        }
    }

    public string CustomError
    {
        set
        {
            CV.ErrorMessage = value;
        }
    }
}


 public class MyObject
{
    private ValidatedString _name = new ValidatedString();
    public ValidatedString Name
    {
        get{
            return _name;
        }
        set
        {
            if (value.Value.Length > 5)
            {
                value.Errors.Add("Name exceeded maximum length of 5");
                value.Valid = false;
            }
            if (value.Value.Contains("a"))
            {
                value.Errors.Add("Name cannot contain the letter a");
                value.Valid = false;
            }


                _name = value;
        }
    }

    private ValidatedString _postcode = new ValidatedString();
    public ValidatedString Postcode
    {
        get
        {
            return _postcode;
        }
        set
        {
            if (value.Value.Length > 3)
            {
                value.Errors.Add("Postcode exceeded maximum length of 5");
                value.Valid = false;

            }
            if (value.Value.Contains("a"))
            {
                value.Errors.Add("Postcode cannot contain the letter a");
                value.Valid = false;

            }


                _postcode = value;

        }
    }


}

public class ValidatedString
{
    private string _value = string.Empty;
    private bool _valid = true;
    private List<string> _errors = new List<string>();
    public ValidatedString()
    { }

    public ValidatedString(string value)
    {
        _value = value;
    }

    public string Value
    {
        get
        {
            return _value;
        }
        set
        {
            _value = value;
        }
    }

    public bool Valid
    {
        get
        {
            return _valid;
        }
        set
        {
            _valid = value;
        }
    }

    public List<string> Errors
    {
        get
        {
            return _errors;
        }
        set
        {
            _errors = value;
        }
    }


    public string GetErrors()
    {
        string returnValue = string.Empty;
        foreach (string error in Errors)
        {
            returnValue += error + System.Environment.NewLine;
        }
        return returnValue;
    }
}
4

1 に答える 1

1

まず、バリデーターとデータを分離します。それらは2つの異なるものです。それらを 1 つのクラスにまとめてはなりません。バリデーターには、データを検証するためのロジックがあります。検証は彼の責任であり、検証中のデータを保持することではありません。別のクラス、たとえばエンティティがデータを保持する必要があります。

なんで?

  • 将来的には、データを別の場所に転送する必要があります。たとえば、データベース、XML ファイル、WCF 経由などです。エラーメッセージなどを含むすべてのリストを転送したくないと想像できます。
  • さらに、検証は国などの特定の条件に応じて行うことができます。国がデフォルトの国と異なる場合、別の郵便番号バリデータが必要ですが、エンティティは同じままです。
  • この動作は .NET で確認できます。データ コントロールは、検証コントロールから分離されています。このロジックに従います。

2 番目: カスタム検証コントロールを作成できます。クライアント (javascript) またはサーバー側で検証ロジックを実行することを選択できます。サーバー側で実行することを選択した場合、コードとカスタムバリデーターによって使用されるライブラリーのどこかに単純な関数を 1 つ持つことができます。

郵便番号の検証コードは次のようになります。

// Validates a postcode and returning a list of errors. If the list is empty, the postcode is valid.
public List<string> ValidatePostcode(string postcode)
{
    List<string> errors = new List<string>();
    // Assuming postcode is not null. Otherwise, create another check.
    if (postcode.Length > 3)
        errors.Add("Postcode exceeded maximum length of 5");
    if (postcode.Contains("a"))
        errors.Add("Postcode cannot contain the letter a");
    return errors;
}
于 2013-04-27T13:16:10.593 に答える