Почему возвращаемое значение Request.Form.ToString() отличается от результата NameValueCollection.ToString()

Кажется, что ToString() в HttpContext.Request.Form оформлен так, что результат отличается из возвращаемого из ToString() при вызове непосредственно на NameValueCollection:

NameValueCollection nameValue = Request.Form;
string requestFormString = nameValue.ToString();

NameValueCollection mycollection = new NameValueCollection{{"say","hallo"},{"from", "me"}};
string nameValueString = mycollection.ToString();

return "RequestForm: " + requestFormString + "<br /><br />NameValue: " + nameValueString;

В результате получится следующее:

RequestForm: say = hallo & from = me

NameValue: System.Collections.Specialized.NameValueCollection

Как я могу получить "string NameValueString = mycollection.ToString();" вернуть "say = hallo & from = me"?

Ответ 1

Причина, по которой вы не видите хорошо отформатированный вывод, состоит в том, что Request.Form имеет тип System.Web.HttpValueCollection. Этот класс переопределяет ToString() так, чтобы он возвращал нужный текст. Стандарт NameValueCollection не отменяет ToString(), поэтому вы получаете вывод версии object.

Без доступа к специализированной версии класса вам потребуется выполнить итерацию коллекции самостоятельно и создать строку:

StringBuilder sb = new StringBuilder();

for (int i = 0; i < mycollection.Count; i++)
{
   string curItemStr = string.Format("{0}={1}", mycollection.Keys[i],
                                                 mycollection[mycollection.Keys[i]]);
   if (i != 0)
       sb.Append("&");
   sb.Append(curItemStr);
}

string prettyOutput = sb.ToString();

Ответ 2

Вам нужно выполнить итерацию по mycollection и построить строку самостоятельно, отформатированную так, как вы хотите. Вот один из способов сделать это:

StringBuilder sb = new StringBuilder();

foreach (string key in mycollection.Keys)
{
   sb.Append(string.Format("{0}{1}={2}",
      sb.Length == 0 ? string.Empty : "&",
      key,
      mycollection[key]));
}

string nameValueString = sb.ToString();

Причина, по которой просто вызов ToString() на вашем NameValueCollection не работает, заключается в том, что метод Object.ToString() - это то, что на самом деле называется, который (если не переопределяется) возвращает объект с полным именем типа. В этом случае полное имя типа - "System.Collections.Specialized.NameValueCollection".

Ответ 3

Другой метод, который хорошо работает:

var poststring = new System.IO.StreamReader(Request.InputStream).ReadToEnd();