Encode in webclient unexpected result - c#

I try use webclient to translate word 'Banana' into rus
private void button1_Click(object sender, EventArgs e)
{
Navigate("http://translate.google.ru/translate_a/t?client=x&text=Banana&hl=en&sl=en&tl=ru");
}
private void Navigate(String address)
{
WebClient client = new WebClient();
client.Proxy = WebRequest.DefaultWebProxy;
client.Credentials = new NetworkCredential("user", "password", "domain");
client.Proxy.Credentials = new NetworkCredential("user", "password", "domain");
string _stranslate = client.DownloadString(new Uri(address));
}
And I want to see in "_stranslate "
{"sentences":[{"trans":"Банан","orig":"Banana#","translit":"Banan #","src_translit":""}],"src":"en","server_time":0}
but got this
{"sentences":[{"trans":"вБОБО","orig":"Banana#","translit":"Banan #","src_translit":""}],"src":"en","server_time":0}
Can some one help me?

Try checking the response headers, the content types tells you what encoding you should use.
Content-Type => text/javascript; charset=KOI8-R
So just add this line.
client.Encoding = Encoding.GetEncoding(20866);
or
client.Encoding = Encoding.GetEncoding("KOI8-R");
A complete list for encodings can be found in the documentation for the Encoding Class
Another way would be to just use System.Net.Mime.ContentType to get the charset.
Like this:
byte[] data = client.DownloadData(url);
ContentType contentType = new System.Net.Mime.ContentType(client.ResponseHeaders[HttpResponseHeader.ContentType]);
string _stranslate = Encoding.GetEncoding(contentType.CharSet).GetString(data);

Add this before your client.DownloadString():
client.Encoding = System.Text.Encoding.UTF8;
Your encoding is likely getting messed up when you read the string.
Using this HTTP header viewer and putting in your URL, I see the following in the headers:
Content-Type: text/javascript; charset=UTF-8
Content-Language: ru
Basically, you need to find out what encoding they are sending back and set your encoding to match.
It is very important to set the encoding before you call DownloadString().

IMHO better solution: add URI query parameter
oe=UTF-8
and use UTF-8 everywhere
var nameValueCollection = new NameValueCollection
{
{"client", "x"},
{"text", HttpUtility.UrlEncode(text)},
{"hl", "en"},
{"sl", fromLanguage},
{"tl", toLanguage},
{"ie", "UTF-8"},
{"oe", "UTF-8"}
};
string htmlResult;
using (var wc = new WebClient())
{
wc.Encoding = Encoding.UTF8;
wc.QueryString = nameValueCollection;
htmlResult = wc.DownloadString(GoogleAddress);
}

Related

How to replace obsolete WebClient POST+ZIP with HttpClient in .NET 6

Since WebClient is deprecated in .NET 6, what is the best solution to convert the following code using WebClient with an equivalent code using HttpClient?
byte[] data = Converter(...); // object to zipped json string
var client = new WebClient();
client.Headers.Add("Accept", "application/json");
client.Headers.Add("Content-Type", "application/json; charset=utf-8");
client.Headers.Add("Content-Encoding", "gzip");
client.Encoding = Encoding.UTF8;
byte[] response = webClient.UploadData("...url...", "POST", data);
string body = Encoding.UTF8.GetString(response);
This code works but only accepts simple json strings as input:
var request = new HttpRequestMessage()
{
RequestUri = new Uri("...url..."),
Version = HttpVersion.Version20,
Method = HttpMethod.Post,
Content = new StringContent("...json string...", Encoding.UTF8, "application/json");
};
var client = new HttpClient();
var response = client.SendAsync(request).Result;
I need a solution to post a zipped json string.
Thank you!
No surprise you managed to only send simple strings, because you used StringContent, which is meant for (drum roll!) string content.
So, what to do if you want to send binary data in form of a byte array? Well, the answer is simple: Don't use StringContent. Instead, use (drum roll intensifies) ByteArrayContent.
In order to add content type you could do this:
var content = new StringContent(payload, Encoding.UTF8);
content.Headers.ContentType = new MediaTypeWithQualityHeaderValue("application/json");
If you want to add headers like you did with webclient:
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//OR
var header = new KeyValuePair<string, string>(key: "Accept", value: "application/json");
client.DefaultRequestHeaders.Add(header.Key, header.Value));

How to download using cefsharp in winforms [duplicate]

I am making a call to a page on my site using webclient. I'm trying to get the result of the webpage put into a pdf so I am trying to get a string representation of the rendered page. The problem is that the request is not authenticated so all I get is a login screen. I have sent the UseDefaultCredentials property to true but I still get the same result. Below is a portion of my code:
WebClient webClient = new WebClient();
webClient.Encoding = Encoding.UTF8;
webClient.UseDefaultCredentials = true;
return Encoding.UTF8.GetString(webClient.UploadValues(link, "POST",form));
You need to give the WebClient object the credentials. Something like this...
WebClient client = new WebClient();
client.Credentials = new NetworkCredential("username", "password");
What kind of authentication are you using? If it's Forms authentication, then at best, you'll have to find the .ASPXAUTH cookie and pass it in the WebClient request.
At worst, it won't work.
Public Function getWeb(ByRef sURL As String) As String
Dim myWebClient As New System.Net.WebClient()
Try
Dim myCredentialCache As New System.Net.CredentialCache()
Dim myURI As New Uri(sURL)
myCredentialCache.Add(myURI, "ntlm", System.Net.CredentialCache.DefaultNetworkCredentials)
myWebClient.Encoding = System.Text.Encoding.UTF8
myWebClient.Credentials = myCredentialCache
Return myWebClient.DownloadString(myURI)
Catch ex As Exception
Return "Exception " & ex.ToString()
End Try
End Function
This helped me to call API that was using cookie authentication. I have passed authorization in header like this:
request.Headers.Set("Authorization", Utility.Helper.ReadCookie("AuthCookie"));
complete code:
// utility method to read the cookie value:
public static string ReadCookie(string cookieName)
{
var cookies = HttpContext.Current.Request.Cookies;
var cookie = cookies.Get(cookieName);
if (cookie != null)
return cookie.Value;
return null;
}
// using statements where you are creating your webclient
using System.Web.Script.Serialization;
using System.Net;
using System.IO;
// WebClient:
var requestUrl = "<API_url>";
var postRequest = new ClassRoom { name = "kushal seth" };
using (var webClient = new WebClient()) {
JavaScriptSerializer serializer = new JavaScriptSerializer();
byte[] requestData = Encoding.ASCII.GetBytes(serializer.Serialize(postRequest));
HttpWebRequest request = WebRequest.Create(requestUrl) as HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/json";
request.ContentLength = requestData.Length;
request.ContentType = "application/json";
request.Expect = "application/json";
request.Headers.Set("Authorization", Utility.Helper.ReadCookie("AuthCookie"));
request.GetRequestStream().Write(requestData, 0, requestData.Length);
using (var response = (HttpWebResponse)request.GetResponse()) {
var reader = new StreamReader(response.GetResponseStream());
var objText = reader.ReadToEnd(); // objText will have the value
}
}

Is it required to encode values when using UploadString with C# WebClient?

I have code like the following to do a POST to a server:
string URI = "http://mydomain.com/foo";
string myParameters =
"&token=1234" +
"&text=" + HttpUtility.UrlEncode(someVariable);
using (WebClient wc = new WebClient())
{
wc.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
string HtmlResult = wc.UploadString(URI, myParameters);
}
Is it required to UrlEncode the parameters like I'm doing or does UploadString handle that automatically under the covers? I don't want to risk any type of double encoding.
Yes, it is required to encode them if you use the UploadString method.
But you could use a more intelligent overload for your case (UploadValues):
string URI = "http://mydomain.com/foo";
var values = new NameValueCollection
{
{ "token", "1234" },
{ "text", someVariable },
};
using (var wc = new WebClient())
{
byte[] result = wc.UploadValues(URI, values);
string htmlResult = Encoding.UTF8.GetString(result);
}
Now you no longer need to worry about any encodings. The WebClient will take them into account when sending the request. Also you will notice that I have removed the application/x-www-form-urlencoded you were adding because when you use the UploadValues method this Content-Type header will automatically be added to the request.

Webclient.UploadString() sends an empty string

Here's some code:
var client = new WebClient();
client.BaseAddress = "http://localhost/";
client.Headers["Content-type"] = "application/x-www-form-urlencoded";
client.Proxy = null;
// The server gets the data
var responseStr = client.UploadString(url, data);
...
// The server gets an empty post data
responseStr = client.UploadString(url, data);
Is Webclient supposed to be an disposable thing?
hmm may be u cant try this :
WebClient client = new WebClient();
client.BaseAddress = "http://localhost/something.php";

How do I authenticate a WebClient request?

I am making a call to a page on my site using webclient. I'm trying to get the result of the webpage put into a pdf so I am trying to get a string representation of the rendered page. The problem is that the request is not authenticated so all I get is a login screen. I have sent the UseDefaultCredentials property to true but I still get the same result. Below is a portion of my code:
WebClient webClient = new WebClient();
webClient.Encoding = Encoding.UTF8;
webClient.UseDefaultCredentials = true;
return Encoding.UTF8.GetString(webClient.UploadValues(link, "POST",form));
You need to give the WebClient object the credentials. Something like this...
WebClient client = new WebClient();
client.Credentials = new NetworkCredential("username", "password");
What kind of authentication are you using? If it's Forms authentication, then at best, you'll have to find the .ASPXAUTH cookie and pass it in the WebClient request.
At worst, it won't work.
Public Function getWeb(ByRef sURL As String) As String
Dim myWebClient As New System.Net.WebClient()
Try
Dim myCredentialCache As New System.Net.CredentialCache()
Dim myURI As New Uri(sURL)
myCredentialCache.Add(myURI, "ntlm", System.Net.CredentialCache.DefaultNetworkCredentials)
myWebClient.Encoding = System.Text.Encoding.UTF8
myWebClient.Credentials = myCredentialCache
Return myWebClient.DownloadString(myURI)
Catch ex As Exception
Return "Exception " & ex.ToString()
End Try
End Function
This helped me to call API that was using cookie authentication. I have passed authorization in header like this:
request.Headers.Set("Authorization", Utility.Helper.ReadCookie("AuthCookie"));
complete code:
// utility method to read the cookie value:
public static string ReadCookie(string cookieName)
{
var cookies = HttpContext.Current.Request.Cookies;
var cookie = cookies.Get(cookieName);
if (cookie != null)
return cookie.Value;
return null;
}
// using statements where you are creating your webclient
using System.Web.Script.Serialization;
using System.Net;
using System.IO;
// WebClient:
var requestUrl = "<API_url>";
var postRequest = new ClassRoom { name = "kushal seth" };
using (var webClient = new WebClient()) {
JavaScriptSerializer serializer = new JavaScriptSerializer();
byte[] requestData = Encoding.ASCII.GetBytes(serializer.Serialize(postRequest));
HttpWebRequest request = WebRequest.Create(requestUrl) as HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/json";
request.ContentLength = requestData.Length;
request.ContentType = "application/json";
request.Expect = "application/json";
request.Headers.Set("Authorization", Utility.Helper.ReadCookie("AuthCookie"));
request.GetRequestStream().Write(requestData, 0, requestData.Length);
using (var response = (HttpWebResponse)request.GetResponse()) {
var reader = new StreamReader(response.GetResponseStream());
var objText = reader.ReadToEnd(); // objText will have the value
}
}

Categories