2011-02-09 31 views
8
int uploadsID; 
int pageNumber; 
int x; 
int y; 
int w; 
int h; 

bool isValidUploadID = int.TryParse(context.Request.QueryString["uploadID"], out uploadsID); 
bool isValidPage = int.TryParse(context.Request.QueryString["page"], out pageNumber); 
bool isValidX = int.TryParse(context.Request.QueryString["x"], out x); 
bool isValidY = int.TryParse(context.Request.QueryString["y"], out y); 
bool isValidW = int.TryParse(context.Request.QueryString["w"], out w); 
bool isValidH = int.TryParse(context.Request.QueryString["h"], out h); 

if (isValidUploadID && isValidPage && isValidX && isValidY & isValidW & isValidH) 
{ 

这是一个ajax处理程序,检查所有传递的参数都可以。这被认为是不好的,有没有更好的方法来写这个,或者它不是那么重要?C#有没有更好的书写方式?

+1

您可以使用包含所有属性和一个需要NameValueCollection(请求。QueryString或只是Request)并准备对象,该对象公开一个方法:“IsValid”并检查当前请求的所有参数是否正确。 – 2011-02-09 10:02:54

+1

你可能想考虑在[codereview](http://codereview.stackexchange.com/)上发布这个 – Benjol 2011-02-09 10:05:41

回答

7

假设你不打算在其他地方使用个人bool变量,你可能写入的内容为:

int uploadsID, pageNumber, x, y, w, h; 
if (int.TryParse(context.Request.QueryString["uploadID"], out uploadsID) && 
    int.TryParse(context.Request.QueryString["page"], out pageNumber) && 
    int.TryParse(context.Request.QueryString["x"], out x) && 
    int.TryParse(context.Request.QueryString["y"], out y) && 
    int.TryParse(context.Request.QueryString["w"], out w) && 
    int.TryParse(context.Request.QueryString["h"], out h)) 
{ 
} 

您可能希望把解压出来int.TryParse(context.Request.QueryString[name], out variable到一个单独的方法,让你的东西,如:

int uploadsID, pageNumber, x, y, w, h; 
if (TryParseContextInt32("uploadID", out uploadsID) && 
    TryParseContextInt32("page", out pageNumber) && 
    TryParseContextInt32("x", out x) && 
    TryParseContextInt32("y", out y) && 
    TryParseContextInt32("w", out w) && 
    TryParseContextInt32("h", out h)) 
{ 
} 

或者,你可以封装所有这些上下文数据储存到一个新的类型用的TryParse方法,所以你必须是这样的:

PageDetails details; 
if (PageDetails.TryParse(context.Request.QueryString)) 
{ 
    // Now access details.Page, details.UploadID etc 
} 

这显然更多的工作,但我认为这会使代码更加清晰。

2

一两件事你可以做的是替换此:

int uploadsID; 
int pageNumber; 
int x; 
int y; 
int w; 
int h; 

有了这个

int uploadsID, pageNumber, x, y, w, h; 
+0

Downvote是好的,但一个理由将不胜感激。您显然认为第一个代码对我更改后的代码具有更好的可读性? – 2011-02-09 11:33:08

6

是,通过分解出你的int.TryParse(etc.)到一个单独的功能开始。

(可能由F#过度影响)

//return a tuple (valid, value) from querystring of context, indexed with key 
private Tuple<bool, int> TryGet(HttpContext context, string key) 
{ 
    int val = 0; 
    bool ok = int.TryParse(context.request.QueryString[key], out val); 
    return Tuple.New(ok, val); 
} 

然后:

var UploadId = TryGet(context, "uploadID"); 
//... 
if(UploadId.Item1 && etc..) 
{ 
    //do something with UploadId.Item2; 

为了使事情变得稍微清晰,你可以

private class ValidValue 
{ 
    public bool Valid { get; private set; } 
    public int Value { get; private set; } 
    public ValidValue(bool valid, int value) 
    { 
     Valid = valid; 
     Value = value; 
    } 
    //etc., but this seems a bit too much like hard work, and you don't get 
    // equality for free as you would with Tuple, (if you need it) 
+0

更像是一个单独的类,它验证了它自己的属性。 – Turrau 2011-02-09 10:05:21

+1

你介意在此扩展吗? – 2011-02-09 10:06:36

3

我可能会去一个格式像这样


int uploadsID, pageNumber, x, y, h; 

if (Int32.TryParse(context.Request.QueryString["uploadID"], out uploadsID) 
    && Int32.TryParse(context.Request.QueryString["page"], out pageNumber) 
    && Int32.TryParse(context.Request.QueryString["x"], out x) 
    && Int32.TryParse(context.Request.QueryString["y"], out y) 
    && Int32.TryParse(context.Request.QueryString["w"], out w) 
    && Int32.TryParse(context.Request.QueryString["h"], out h)) 
{ 
    ... 
} 

,但我看不出什么毛病你的方法。

1
try 
{ 
    // use Parse instead of TryParse 

    // all are valid, proceed 
} 
catch 
{ 
    // at least one is not valid 
} 
0

你可以写摆脱的TryParse丑陋out传球方式的帮手,如:

public delegate bool TryParser<T>(string text, out T result) where T : struct; 

public static T? TryParse<T>(string text, TryParser<T> tryParser) 
          where T : struct 
{ 
    // null checks here. 
    T result; 
    return tryParser(text, out result) ? result : new T?(); 
} 

然后(假设你只在有效期兴趣):

bool isValid = new [] { "uploadID" , "page", "x", "y", "w", "h" } 
       .Select(q => context.Request.QueryString[q]) 
       .All(t => TryParse<int>(t, int.TryParse).HasValue); 

如果您需要单个值:

var numsByKey = new [] { "uploadID" , "page", "x", "y", "w", "h" } 
       .ToDictionary(q => q, 
          q => TryParse<int>(context.Request.QueryString[q], 
               int.TryParse)); 

bool isValid = numsByKey.Values.All(n => n.HasValue); 

除了细粒度的信息需要查找而不是本地变量访问之外,它保留了与以前几乎相同的信息。

相关问题