0

私は従来の WebForms アプリケーションを維持しており、ページの 1 つは GET 要求を処理するだけで、多くのクエリ文字列パラメーターを操作します。この作業はコード ビハインドで行われ、この種のチェックとキャストの多くが行われます。

protected override void OnLoad(EventArgs e)
{
    string error = string.Empty;

    string stringParam = Request.Params["stringParam"];
    if (!String.IsNullOrEmpty(stringParam))
    {
        error = "No parameter";
        goto LoadError;
    }

    Guid? someId = null;
    try
    {
        someId = new Guid(Request.Params["guidParam"]);
    }
    catch (Exception){}
    if (!someId.HasValue)
    {
        error = "No valid id";
        goto LoadError;
    }

    // parameter checks continue on

LoadError:
    log.ErrorFormat("Error loading page: {0}", error);
    // display error page
}

この解析と検証をカプセル化し、コード ビハインドから移動する、テスト可能なクラスを作成したいと思います。これおよび/または例に対するいくつかのアプローチを推奨できる人はいますか?

4

2 に答える 2

2

最初の大きなステップとして、おそらく次のような形式のマッパー/トランスレーター オブジェクトを作成します。

class SpecificPageRequestMapper 
{
    public SpecificPageRequest Map(NameValueCollection parameters)
    {
        var request = new SpecificPageRequest();
        string stringParam = parameters["stringParam"];
        if (String.IsNullOrEmpty(stringParam))
        {
            throw new SpecificPageRequestMappingException("No parameter");
        }

        request.StringParam = stringParam;

        // more parameters

        ...

        return request;
    }
}

class SpecificPageRequest
{
    public string StringParam { get; set; }
    // more parameters...
}

次に、次のOnLoadようになります。

protected override void OnLoad(EventArgs e)
{  
    try
    {
        var requestObject = requestMapper.Map(Request.Params);
        stringParam = requestObject.StringParam;
        // so on, so forth. Unpack them to the class variables first.
        // Eventually, just use the request object everywhere, maybe.
    }
    catch(SpecificPageRequestMappingException ex)
    {
        log.ErrorFormat("Error loading page: {0}", ex.Message);
        // display error page
    }
}

私が作成した特定の例外のコードは省略し、背後のページのどこかでマッパーをインスタンス化すると仮定しました。

この新しいオブジェクトのテストは簡単です。に渡されたコレクションにパラメーターを設定Mapし、要求オブジェクトの正しいパラメーターが期待する値を持っていることをアサートします。適切なケースで例外がスローされることを確認することで、ログ メッセージをテストすることもできます。

于 2012-12-28T06:54:31.113 に答える
1

このようなパラメーター解析を使用するページが多数あると仮定すると、まずNamedValueCollectionに拡張メソッドを持つ単純な静的クラスを作成します。例えば、

static class Parser
{    
    public static int? ParseInt(this NamedValueCollection params, string name)
    {
        var textVal = params[name];
        int result = 0;
        if (string.IsNullOrEmpty(textVal) || !int.TryParse(textVal, out result))
        {
            return null;
        }
        return result;
    }

   public static bool TryParseInt(this NamedValueCollection params, string name, out int result)
    {
        result = 0;
        var textVal = params[name];
        if (string.IsNullOrEmpty(textVal))
            return false;
        return int.TryParse(textVal, out result);
    }

    // ...    
}

次のように使用します

int someId = -1;
if (!Request.Params.TryParseInt("SomeId", out someId))
{
   // error
}

次のステップは、ページ固有のパーサー クラスを作成することです。例えば、

public class MyPageParser
{
    public int? SomeId { get; private set; } 
    /// ...

    public IEnumerable<string> Parse(NamedValueCollection params)
    {
        var errors = new List<string>();
        int someId = -1;
        if (!params.TryParseInt("SomeId", out someId))
        {
            errors.Add("Some id not present");
            this.SomeId = null;
        }
        this.SomeId = someId;

        // ...  
    }
}
于 2012-12-28T07:06:49.573 に答える