在ASP.NET中转换/访问QueryString值

时间:2009-03-02 23:23:41

标签: c# .net asp.net

我很好奇每个人在处理/抽象ASP.NET中的QueryString时所做的事情。在我们的一些网络应用程序中,我在网站上看到了很多这样的内容:

int val = 0;
if(Request.QueryString["someKey"] != null)
{
val = Convert.ToInt32(Request.QueryString["someKey"]);
}

有什么更好的方法来处理这种严重性?

7 个答案:

答案 0 :(得分:25)

我倾向于将它们抽象为属性的想法。 例如:

        public int age { 
        get
        {
            if (Request.QueryString["Age"] == null)
                return 0;
            else
                return int.Parse(Request.QueryString["Age"]);                                    
        }
    }

如果您愿意,可以添加更多验证。但我倾向于以这种方式包装所有查询字符串变量。

编辑:--- 另外,另一张海报指出,您必须在每个页面上创建这些属性。我的回答是你没有。您可以在一个可以调用“QueryStrings”或类似内容的类中创建这些属性。然后,您可以在要访问查询字符串的每个页面中实例化此类,然后您可以执行类似

的操作
var queryStrings = new QueryStrings();
var age = queryStrings.age;

通过这种方式,您可以封装所有用于在单个可维护位置访问和处理每种类型的查询变量的逻辑。

EDIT2:--- 因为它是类的一个实例,所以您还可以使用依赖注入在您使用它的每个位置注入QueryStrings类。 StructureMap做得很好。这也允许您模拟QueryStrings类并注入,如果您想进行自动单元测试。比ASP.Net的Request对象更容易模拟它。

答案 1 :(得分:8)

有一点是你没有在这里捕捉空白值。您可能有一个类似“http://example.com?someKey=&anotherKey=12345”的网址,在这种情况下,“someKey”参数值为“”(空)。您可以使用string.IsNullOrEmpty()来检查空状态和空状态。

我还要将“someKey”更改为存储在变量中。这样你就不会在多个地方重复文字字符串了。它使维护更容易。

int val = 0;
string myKey = "someKey";
if (!string.IsNullOrEmpty(Request.QueryString[myKey]))
{
    val = int.Parse(Request.QueryString[myKey]);
}

我希望有所帮助!

伊恩

答案 2 :(得分:3)

写一些辅助方法(库)来处理它......

public static void GetInt(this NameValueCollection nvCol, string key, out int keyValue, int defaultValue)
{
    if (string.IsNullOrEmpty(nvCol[key]) || !int.TryParse(nvCol[key], out keyValue))
        keyValue = defaultValue;
}

或者那些东西......

答案 3 :(得分:3)

这就是我想出的。它使用泛型从QueryString返回强类型值,如果参数不在QueryString中,则使用可选的默认值:

/// <summary>
    /// Gets the given querystring parameter as a the specified value <see cref="Type"/>
    /// </summary>
    /// <typeparam name="T">The type to convert the querystring value to</typeparam>
    /// <param name="name">Querystring parameter name</param>
    /// <param name="defaultValue">Default value to return if parameter not found</param>
    /// <returns>The value as the specified <see cref="Type"/>, or the default value if not found</returns>
    public static T GetValueFromQueryString<T>(string name, T defaultValue) where T : struct
    {
        if (String.IsNullOrEmpty(name) || HttpContext.Current == null || HttpContext.Current.Request == null)
            return defaultValue;

        try
        {
            return (T)Convert.ChangeType(HttpContext.Current.Request.QueryString[name], typeof(T));
        }
        catch
        {
            return defaultValue;
        }
    }

    /// <summary>
    /// Gets the given querystring parameter as a the specified value <see cref="Type"/>
    /// </summary>
    /// <typeparam name="T">The type to convert the querystring value to</typeparam>
    /// <param name="name">Querystring parameter name</param>
    /// <returns>The value as the specified <see cref="Type"/>, or the types default value if not found</returns>
    public static T GetValueFromQueryString<T>(string name) where T : struct
    {
        return GetValueFromQueryString(name, default(T));
    }

自写这篇文章以来,我编写了一个非常小的类库来操作查询字符串值 - 请参阅https://github.com/DanDiplo/QueryString-Helper

答案 4 :(得分:1)

我们一直在使用常量将所有这些“松散”键保存在一个中心位置:

public class Constants
{
  public class QueryString
  {
    public const string PostID = "pid";
    public const string PostKey = "key";
  }
  public class Cookie
  {
    public const string UserID = "mydomain.com-userid";
  }
  public class Cache
  {
    public const string PagedPostList = "PagedPostList-{0}-{1}";
  }
  public class Context
  {
    public const string PostID = "PostID";
  }
  public class Security
  {
    public const RoleAdministrator = "Administrator";
  }
}

这样,您可以轻松访问所需的常量:

public void Index()
{
  if (Request[Constants.QueryString.PostKey] == "eduncan911")
  {
    // do something
  }
}

public object GetPostsFromCache(int postID, int userID)
{
  String cacheKey = String.Format(
      Constants.Cache.PagedPostList
      , userID
      , postID);
  return Cache[cacheKey] as IList<Post>;
}

答案 5 :(得分:1)

据我所知,获得查询字符串值的最佳方法如下:
如果未找到查询字符串,则val的值将为0

int val = 0;
int.TryParse(Request.QueryString["someKey"], out val);

答案 6 :(得分:0)

我和海报谁提出了辅助方法(我会评论他,但还不能)。其他人不同意他赞成创建属性,但我的答案是它没有优雅地处理检查空值或无效格式化等问题。如果你有辅助方法,所有的逻辑都可以写一次,集中。

如果你有很多页面,那么为每个页面添加属性可能比它的价值更耗时。但这显然只是一种偏好,所以对每个人都是如此。

另一个海报的辅助方法可以改进的一个很酷的事情是将out参数改为参考参数(更改为ref)。这样,您可以为属性设置默认值,以防它未通过。有时您可能需要可选参数,例如 - 然后您可以使用某些默认值来启动可选参数未显式传递的情况(比单独传递默认值更容易)。您甚至可以在末尾添加一个IsRequired布尔参数,如果bool设置为true且未传递参数,则会抛出异常。在许多情况下,这可能会有所帮助。