技术开发 频道

ASP.NET:细说Request与Request.Params

  再谈NameValueCollection

  本文一开始的示例中,为什么代码 ParamsValue = Request.Params["name"]; 得到的结果是:【abc,123】?

  根据前面示例代码我们可以得知:abc这个值是由QueryString提供的,123这值是由Form提供的,最后由Request.Params[]合并在一起了就变成这个样子了。有没有人想过:为什么合起来就变成了这个样子了呢?

  要回答这个问题,我们需要回顾一下Params的定义:

public NameValueCollection Params

   注意:它的类型是NameValueCollection 。MSDN对这个集合有个简单的说明:

此集合基于 NameObjectCollectionBase 类。但与 NameObjectCollectionBase 不同,该类在一个键下存储多个字符串值。

   为了便于大家更容易理解这个类的工作方式,我画了一张草图:

  【name】这个key对应差一个ArrayList,而那个ArrayList中,包含了二个字符串:abc 和 123 ,这就是它的工作方式。

  既然它能在一个键值下存储多个字符串,那我们就来看一下它到底是如何实现的,直接转到Add()方法:(注意我在代码中添加的注释)

public virtual void Add(string name, string value)
{
    
if( base.IsReadOnly ) {
        
throw new NotSupportedException(SR.GetString("CollectionReadOnly"));
    }
    this.InvalidateCachedArrays();

    
// 这是一个关键的调用,它调用基类,得到每个name对应的元素,
    
// 而每个name对应的元素是一个ArrayList
    ArrayList list
= (ArrayList)base.BaseGet(name);

    
if( list == null ) {
        
// 如果不存在name对应的元素,则创建ArrayList
        list
= new ArrayList(1);
        
if( value != null ) {
            
// 添加value到ArrayList,它将是第一个值
            list.Add(value);
        }
        base.BaseAdd(name, list);
    }
    
else if( value != null ) {
        
// 在原有的ArrayList中继续添加新的值
        list.Add(value);
    }
}

  我们再来看一下当我们访问Params[]这个索引器时,.net framework又是如何实现的:

public string this[string name]
{
    
get { return this.Get(name); }
    
set { this.Set(name, value); }
}
public virtual string Get(string name)
{
    
// 根据name得到ArrayList
    ArrayList list
= (ArrayList) base.BaseGet(name);
    
// 将ArrayList变成一个字符串行
    
return GetAsOneString(list);
}

private static string GetAsOneString(ArrayList list)
{
    
int num = (list != null) ? list.Count : 0;
    
if( num == 1 ) {
        
return (string)list[0];
    }
    
if( num <= 1 ) {
        
return null;
    }
    StringBuilder builder
= new StringBuilder((string)list[0]);
    
for( int i = 1; i < num; i++ ) {
        builder.Append(
',');    // 逗号就来源于此。
        builder.Append((string)list[i]);
    }
    
return builder.ToString();
}
0
相关文章