C# 验证和分析ASP.NET中的url参数
我正在维护一个遗留的WebForms应用程序,其中一个页面只提供GET请求,并使用许多查询字符串参数。这项工作是在代码隐藏中完成的,并进行了大量此类检查和转换C# 验证和分析ASP.NET中的url参数,c#,asp.net,oop,validation,refactoring,C#,Asp.net,Oop,Validation,Refactoring,我正在维护一个遗留的WebForms应用程序,其中一个页面只提供GET请求,并使用许多查询字符串参数。这项工作是在代码隐藏中完成的,并进行了大量此类检查和转换 protected override void OnLoad(EventArgs e) { string error = string.Empty; string stringParam = Request.Params["stringParam"]; if (!String.IsNullOrEmpty(stri
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
}
我想创建一个可测试类来封装这个解析和验证,并将其从代码中移出。有人能推荐一些方法和/或示例吗?作为第一大步,我可能会创建某种形式的映射器/转换器对象,如下所示:
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...
}
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
}
}
然后您的OnLoad
可以如下所示:
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...
}
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
的集合上设置参数,然后断言请求对象上的正确参数具有您期望的值。您甚至可以通过检查日志消息是否在正确的情况下抛出异常来测试日志消息。作为第一大步,我可能会创建某种形式的映射器/转换器对象,如下所示:
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...
}
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
}
}
然后您的OnLoad
可以如下所示:
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...
}
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
的集合上设置参数,然后断言请求对象上的正确参数具有您期望的值。您甚至可以通过检查日志消息是否在正确的情况下抛出异常来测试日志消息。假设您可能有许多这样的页面使用这样的参数解析,首先创建一个简单的静态类,该类上有扩展方法。比如说,
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);
}
// ...
}
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;
// ...
}
}
使用它如下
int someId = -1;
if (!Request.Params.TryParseInt("SomeId", out someId))
{
// error
}
下一步是编写特定于页面的解析器类。比如说,
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);
}
// ...
}
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;
// ...
}
}
公共类MyPageParser
{
公共int?SomeId{get;private set;}
/// ...
公共IEnumerable解析(NamedValueCollection参数)
{
var errors=新列表();
int-someId=-1;
如果(!params.TryParseInt(“SomeId”,out SomeId))
{
错误。添加(“某些id不存在”);
this.SomeId=null;
}
this.SomeId=SomeId;
// ...
}
}
假设您可能有许多这样的页面使用这样的参数解析,首先创建一个简单的静态类,该类上有扩展方法。比如说,
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);
}
// ...
}
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;
// ...
}
}
使用它如下
int someId = -1;
if (!Request.Params.TryParseInt("SomeId", out someId))
{
// error
}
下一步是编写特定于页面的解析器类。比如说,
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);
}
// ...
}
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;
// ...
}
}
公共类MyPageParser
{
公共int?SomeId{get;private set;}
/// ...
公共IEnumerable解析(NamedValueCollection参数)
{
var errors=新列表();
int-someId=-1;
如果(!params.TryParseInt(“SomeId”,out SomeId))
{
错误。添加(“某些id不存在”);
this.SomeId=null;
}
this.SomeId=SomeId;
// ...
}
}
转到
?不是每天都能看到。是的,没错,这也是重构的目标之一。goto
?不是每天都能看到。是的,没错,这也是重构的目标之一。