คุณ UrlEncode โดยไม่ต้องใช้ System.Web อย่างไร


310

ฉันกำลังพยายามเขียนแอปพลิเคชันไคลเอนต์ windows ที่เรียกใช้เว็บไซต์เพื่อหาข้อมูล เพื่อให้การติดตั้งให้น้อยที่สุดฉันพยายามใช้DLLs ใน. NET Framework Client Profileเท่านั้น ปัญหาคือฉันต้อง UrlEncode พารามิเตอร์บางอย่างมีวิธีง่าย ๆ โดยไม่ต้องนำเข้า System.Web.dll ซึ่งไม่ได้เป็นส่วนหนึ่งของไคลเอนต์ Pofile หรือไม่


คุณช่วยแสดงให้เห็นว่าคุณทำการโทรไปยังเว็บไซต์ได้อย่างไร? อาจมีบางสิ่งที่สามารถทำได้ที่นั่น
ดารินทินดิมิทรอฟ

จากความอยากรู้คุณจะเรียกเว็บไซต์สำหรับข้อมูลโดยไม่ต้องใช้ System.Web ได้อย่างไร
Patrick McDonald

@ แพทริกเขาอาจจะใช้หรือWebRequest WebClientนั่นคือเหตุผลที่ฉันถามเกี่ยวกับรหัสนี้เพราะมีหลายสิ่งที่สามารถทำได้เกี่ยวกับการเข้ารหัส URL ของคุณอย่างถูกต้อง
ดารินทินดิมิทรอฟ

1
ฉันใช้วัตถุ System.Net.WebRequest จากนั้นฉันก็โทร GetRequestStream และเขียนพารามิเตอร์ Post ของฉันออกไปที่สตรีม ฉันยังตั้งค่า ContentType เป็น "application / x-www-form-urlencoded"
Martin Brown

1
แน่นอนว่าสิ่งนี้จะถูกนำไปใช้อย่างเท่าเทียมกันหากฉันทำการร้องขอ GET และต่อท้ายพารามิเตอร์เข้ากับ URL
Martin Brown

คำตอบ:


317

System.Uri.EscapeUriString() อาจมีปัญหากับตัวละครบางตัวสำหรับฉันมันเป็นสัญญาณ / ปอนด์ '#' ในสตริง

หากนั่นเป็นปัญหาสำหรับคุณลอง:

System.Uri.EscapeDataString() //Works excellent with individual values

นี่คือคำตอบสำหรับคำถาม SO ที่อธิบายความแตกต่าง:

EscapeUriString กับ EscapeDataString ต่างกันอย่างไร

และแนะนำให้ใช้Uri.EscapeDataString()ในทุกด้าน


1
เท็จ: blogs.msdn.com/b/yangxind/archive/2006/11/09/…คุณจะมีปัญหากับเครื่องหมายบวกเนื่องจากจะไม่มีการเข้ารหัส
Chris Weber

7
โพสต์บล็อกนั้นค่อนข้างเก่าและฉันเพิ่งได้ "Uri Escaped" URL เต็มและช่องว่างทั้งหมดกลายเป็น% 20 ดังนั้นฉันคิดว่าพวกเขาแก้ไข ฉันใช้. Net 4.5
Rodi

EscapeDataString ยังไม่สนับสนุนสตริงที่ยาวมากหากคุณกำลังเตรียมข้อมูลสำหรับการดำเนินการ POST stackoverflow.com/questions/6695208/…
Bron Davies

Uri.EscapeUriStringเป็นปัญหาอย่างมากและไม่ควรใช้เนื่องจากมันพยายามทำบางสิ่ง (หนี URIs แบบเต็ม) ซึ่งเป็นไปไม่ได้ที่จะทำอย่างสม่ำเสมอดูคำตอบนี้สำหรับคำอธิบายโดยละเอียด
Livven

นอกจากนี้ยังมีอักขระ '' Space
Waqas Shabbir

252

ใน. Net 4.5+ ใช้ WebUtility

สำหรับการจัดรูปแบบฉันส่งคำตอบนี้เป็นคำตอบ

ไม่พบตัวอย่างที่ดีเปรียบเทียบกับ:

string testString = "http://test# space 123/text?var=val&another=two";
Console.WriteLine("UrlEncode:         " + System.Web.HttpUtility.UrlEncode(testString));
Console.WriteLine("EscapeUriString:   " + Uri.EscapeUriString(testString));
Console.WriteLine("EscapeDataString:  " + Uri.EscapeDataString(testString));
Console.WriteLine("EscapeDataReplace: " + Uri.EscapeDataString(testString).Replace("%20", "+"));

Console.WriteLine("HtmlEncode:        " + System.Web.HttpUtility.HtmlEncode(testString));
Console.WriteLine("UrlPathEncode:     " + System.Web.HttpUtility.UrlPathEncode(testString));

//.Net 4.0+
Console.WriteLine("WebUtility.HtmlEncode: " + WebUtility.HtmlEncode(testString));
//.Net 4.5+
Console.WriteLine("WebUtility.UrlEncode:  " + WebUtility.UrlEncode(testString));

ขาออก:

UrlEncode:             http%3a%2f%2ftest%23+space+123%2ftext%3fvar%3dval%26another%3dtwo
EscapeUriString:       http://test#%20space%20123/text?var=val&another=two
EscapeDataString:      http%3A%2F%2Ftest%23%20space%20123%2Ftext%3Fvar%3Dval%26another%3Dtwo
EscapeDataReplace:     http%3A%2F%2Ftest%23+space+123%2Ftext%3Fvar%3Dval%26another%3Dtwo

HtmlEncode:            http://test# space 123/text?var=val&another=two
UrlPathEncode:         http://test#%20space%20123/text?var=val&another=two

//.Net 4.0+
WebUtility.HtmlEncode: http://test# space 123/text?var=val&another=two
//.Net 4.5+
WebUtility.UrlEncode:  http%3A%2F%2Ftest%23+space+123%2Ftext%3Fvar%3Dval%26another%3Dtwo

ใน. Net 4.5+ ใช้ WebUtility.UrlEncode

สิ่งนี้ดูเหมือนจะทำซ้ำHttpUtility.UrlEncode(pre-v4.0) สำหรับอักขระทั่วไป:
Uri.EscapeDataString(testString).Replace("%20", "+").Replace("'", "%27").Replace("~", "%7E")
หมายเหตุ: EscapeUriStringจะเก็บสตริง uri ที่ถูกต้องซึ่งทำให้ใช้อักขระ plaintext มากที่สุดเท่าที่จะทำได้

ดูคำตอบนี้สำหรับตารางเปรียบเทียบการเข้ารหัสต่างๆ:
https://stackoverflow.com/a/11236038/555798

ตัวแบ่งบรรทัด ทั้งหมดของพวกเขาที่นี่ (นอกเหนือจากHttpUtility.HtmlEncode) จะถูกแปลง"\n\r"เป็น%0a%0dหรือ%0A%0D

โปรดแก้ไขและเพิ่มตัวละครใหม่ลงในชุดทดสอบของฉันหรือทิ้งไว้ในความคิดเห็นและฉันจะแก้ไข


ในกรณีของฉันฉันจะต้องใช้EscapeDataStringมากกว่าEscapeUriStringขณะที่เรากำลังเข้ารหัสผลตอบแทนการขนส่งและฟีดสายและสิ่งเหล่านี้จำเป็นต้องก้าวร้าวมากขึ้น Escape ที่ดำเนินการโดยEscapeDataString
เดวิด O'Meara

1
ตัวอย่างเพิ่มเติมคุณสามารถให้กรณีทดสอบของคุณเองหากคุณต้องการ นี่คือตัวอย่างของการใช้งานและวิธีการเข้ารหัสอื่น ๆ ที่แสดงความแตกต่างdotnetfiddle.net/12IFw1
Maslow

3
WebUtility.UrlEncode () และ WebUtility.UrlDecode () คือ 4.5+ ไม่มีใน 4.0
Derek Kalweit

msdn พูดว่า: "แพลตฟอร์ม Windows สากล: มีให้ตั้งแต่ 4.5, .NET Framework: มีให้ตั้งแต่ 4.0" ...
Thymine

54

คุณสามารถใช้ได้

Uri.EscapeUriString (ดูhttp://msdn.microsoft.com/en-us/library/system.uri.escapeuristring.aspx )


มีความแตกต่างระหว่างสิ่งนี้กับ EscapeDataString หรือไม่?
Martin Brown

3
คุณต้องการใช้ EscapeUriString EscapeUriString จะพยายามเข้ารหัส URL ทั้งหมด (รวมถึง http: // part) ในขณะที่ EscapeUriString เข้าใจว่าส่วนใดที่ควรเข้ารหัสจริงๆ
Matthew Manela

1
ฉันเห็นดังนั้นในกรณีนี้ฉันอาจต้องการ EscapeDataString เนื่องจากฉันอาจต้องการส่ง URL เป็นพารามิเตอร์รับ ฉันกำลังต่อท้าย URL ในกรณีนี้
Martin Brown

5
@MatthewManela ผมค่อนข้างมั่นใจว่าความคิดเห็น Oct1 คุณควรอ่านEscapeDataString จะพยายามที่จะเข้ารหัส ...
Maslow

Uri.EscapeUriStringอย่าใช้ มันไม่ "เข้าใจ" ว่าควรจะเข้ารหัสส่วนไหน แต่เป็นเพียงความพยายามที่ผิด ๆ ในการทำบางสิ่งบางอย่าง (หนี URIs แบบเต็ม) ซึ่งเป็นไปไม่ได้ที่จะทำอย่างสม่ำเสมอ ดูคำตอบนี้สำหรับคำอธิบายโดยละเอียด
Livven

20

คำตอบที่นี่ดีมาก แต่ก็ยังไม่เพียงพอสำหรับฉัน

ฉันเขียนลูปขนาดเล็กที่เปรียบเทียบUri.EscapeUriStringกับUri.EscapeDataStringอักขระทั้งหมดตั้งแต่ 0 ถึง 255

หมายเหตุ: ฟังก์ชั่นทั้งสองนั้นมีความฉลาดในตัวที่ตัวอักษรด้านบน 0x80 นั้นถูกเข้ารหัส UTF-8 ก่อนแล้วจึงเข้ารหัสเป็นเปอร์เซ็นต์

นี่คือผลลัพธ์:

******* Different *******

'#' -> Uri "#" Data "%23"
'$' -> Uri "$" Data "%24"
'&' -> Uri "&" Data "%26"
'+' -> Uri "+" Data "%2B"
',' -> Uri "," Data "%2C"
'/' -> Uri "/" Data "%2F"
':' -> Uri ":" Data "%3A"
';' -> Uri ";" Data "%3B"
'=' -> Uri "=" Data "%3D"
'?' -> Uri "?" Data "%3F"
'@' -> Uri "@" Data "%40"


******* Not escaped *******

'!' -> Uri "!" Data "!"
''' -> Uri "'" Data "'"
'(' -> Uri "(" Data "("
')' -> Uri ")" Data ")"
'*' -> Uri "*" Data "*"
'-' -> Uri "-" Data "-"
'.' -> Uri "." Data "."
'_' -> Uri "_" Data "_"
'~' -> Uri "~" Data "~"

'0' -> Uri "0" Data "0"
.....
'9' -> Uri "9" Data "9"

'A' -> Uri "A" Data "A"
......
'Z' -> Uri "Z" Data "Z"

'a' -> Uri "a" Data "a"
.....
'z' -> Uri "z" Data "z"

******* UTF 8 *******

.....
'Ò' -> Uri "%C3%92" Data "%C3%92"
'Ó' -> Uri "%C3%93" Data "%C3%93"
'Ô' -> Uri "%C3%94" Data "%C3%94"
'Õ' -> Uri "%C3%95" Data "%C3%95"
'Ö' -> Uri "%C3%96" Data "%C3%96"
.....

EscapeUriStringจะถูกนำมาใช้เพื่อ URL ที่เข้ารหัสในขณะEscapeDataStringที่จะถูกใช้ในการเข้ารหัสเช่นเนื้อหาของคุกกี้เนื่องจากข้อมูลคุกกี้ไม่ต้องมีตัวละครที่สงวนและ'='';'


การวิเคราะห์ที่ดีและการสลายที่นี่มีประโยชน์มาก ถ้าใครมีหรือรู้ถึงประสิทธิภาพการเปรียบเทียบ (เปรียบเทียบทั้งสามวิธี) ที่จะดูดี
Shaun Wilson

นี่เป็นการวิเคราะห์ที่ดีและการซื้อกลับบ้านก็เป็นสิ่งที่คุณไม่ควรใช้Uri.EscapeUriStringเพราะการหลีกหนี URI แบบสมบูรณ์นั้นเป็นไปไม่ได้ที่จะทำอย่างสม่ำเสมอ ดูคำตอบนี้สำหรับคำอธิบายโดยละเอียด
Livven

16

มีเวอร์ชันที่ใช้งานได้ของโปรไฟล์ลูกค้า, คลาส System.Net.WebUtility มีอยู่ในโปรไฟล์ไคลเอ็นต์ System.dll นี่คือลิงค์ MSDN:

WebUtility


ฉันทราบว่าหน้าความช่วยเหลือสำหรับชั้นเรียนนั้นระบุว่า "ให้วิธีการเข้ารหัสและถอดรหัส URL เมื่อประมวลผลคำขอของเว็บ" ดังนั้นอาจเป็นไปได้ว่าพวกเขาไม่ได้ตั้งชื่อวิธีการที่ดี
James White

จุดดีพูดทำไมคุณไม่ลงคะแนนให้พี่ชาย;) การลงคะแนนนี้ทำให้ฉันรู้สึกแย่เป็นเวลา 2 ปี! JK ... แต่โดยสุจริตนั่นอาจเป็นเหตุผลว่าทำไมฉันโพสต์ลิงค์โชคไม่ดีที่ฉันได้รับความนิยมจากข้อผิดพลาดในเอกสารของ Microsoft ...
Sprague

11
ดูเหมือนว่า UrlEncode และ UrlDecode จะถูกเพิ่มลงใน WebUtility ใน. NET เวอร์ชัน 4.5 เท่านั้น
Martin Brown

8

นี่คือตัวอย่างของการส่งคำขอ POST ที่เข้ารหัสพารามิเตอร์โดยใช้ application/x-www-form-urlencodedประเภทเนื้อหา:

using (var client = new WebClient())
{
    var values = new NameValueCollection
    {
        { "param1", "value1" },
        { "param2", "value2" },
    };
    var result = client.UploadValues("http://foo.com", values);
}


-3
System.Net.WebUtility.HtmlDecode

คลาส WebUtility มีวิธีการเข้ารหัสและถอดรหัส URL เมื่อประมวลผลคำขอของเว็บ มันทำสิ่งเดียวกันกับ HttpUtility แต่มันออกจาก System.Web namespace
Alexandru Aliu

3
มันผิดเพราะ HtmlDecodes และไม่ UrlEncode เหมือนคำถามที่ถาม แม้ HtmlEncode จะผิดเพราะการเข้ารหัส HTML นั้นแตกต่างจากการเข้ารหัส URL
Martin Brown
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.