How to replace "%2B" with "+" when calling RedirectToAction() - asp.net-core

I'm using the RedirectToAction() method in an ASP.NET Core 2.1 controller called CatalogController:
return RedirectToAction("search", new { search_string = "example+string" });
This redirects to a URL:
catalog/search/?search_string=example%2Bstring
How do I replace the %2B encoding with a + instead?
The URL should instead look like:
catalog/search/?search_string=example+string

The RedirectToAction() method assumes that any values passed via the RouteValues parameter are not encoded; the RedirectToAction() method will take care of the URL encoding on your behalf. As such, when you enter a +, it's treating it as a literal + symbol, not an encoded space.
%2B is the correct encoding for a literal + symbol. If you want a space to be encoded in the URL, then you should enter a space in your RouteValues dictionary (e.g., search_string = "example string"). This will encode the space as a %20.
Note: A %20 is the equivalent of a + in an encoded URL, so I'm assuming that will satisfy your requirements.
If your search_string value is coming from a URL encoded source, you will need to first decode it using e.g. WebUtility.UrlDecode(). That said, if you're retrieving your search_string value from an action parameter or binding model, this decoding should already be done for you.
If, for some reason, you want to treat literal + symbols as spaces, you'll need to explicitly perform that replace on your source value (e.g., search_string.Replace("+", " ")).

Related

Is it possible to use apache's URIBuilder to set a parameter with percentage sign?

I want to build this complete URL:
locahost/some/path?param1=%06
using org.apache.http.client.utils.URIBuilder method setParameter(final String param, final String value). At its javadoc, there's line:
The parameter name and value are expected to be unescaped and may contain non ASCII characters
But when I use setParameter("param1","%06") I always get ...param1=%2506 instead of ...param1=%06. Looking here I noticed percent sign is 25 in hex.
Should I parse this manually or there's a way to keep using URIBuilder and keep the parameters as is?

Add special characters to Uri, Kotlin

So, I have my base URL, which is this:
val GITHUB_BASE_URL: String = "https://api.github.com/search/repositories"
And then I have this code that appends the param q (REPO_NAME_PARAM == query) to the Uri and builds it:
val builtUri: Uri = Uri.parse(GITHUB_BASE_URL).buildUpon()
.appendQueryParameter(REPO_NAME_PARAM, repoName)
.build()
Until here, everything works fine. But, when I try to filter the search of the repositories by the language they are written in (which the URL, for example, should be https://api.github.com/search/repositories?q=hello+language:Kotlin), the + and the : characters get replaced by %2B and %3A. This causes the app to not retrieve the expected results, as the characters got changed in the final url.
This is the code that I currently have
val WRITTEN_IN_PARAM: String = "+language:"
val builtUri: Uri = Uri.parse(GITHUB_BASE_URL).buildUpon()
.appendQueryParameter(REPO_NAME_PARAM, repoName+ WRITTEN_IN_PARAM+"Kotlin")
.build()
2B or not 2B, that is the question. :)
The problem is that the URL parameter is being URL Encoded twice. When we send certain characters in HTTP queries, they need to be encoded. One encoding (considered a shortcut) is to turn a space into a + symbol. The proper way to encode a space is with %20.
However, when the code above gets that already encoded String it doesn't know that the + is already encoded from a space and tries to encode it again (using %2B, the encoding for +).
If you hit the URL you've provided with %20 in place of +, and %3A in place of :, it should work fine. Therefore, the fix is to not send + unless you really want a +, in which case it will be properly encoded to a %2B.
The Fix: The library being used appears to correctly encode strings, just leave the + as a space and it should give you what you need.
Here is a good list of characters and their encoding, if you are interested.

Model binding fails in webapi 2.0

I am using Webapi 2.0. I am passing one parameter having value as vb/c4t+UuRLnQ2W/g8SQ== After model binding i am getting the value of authId in my code as vb/c4t UuRLnQ2W/g8SQ== The (+) sign gets replaced with a space. Could you please help me out how can i get that.
Url: api/employee/1234?authId=vb/c4t+UuRLnQ2W/g8SQ==
[HttpGet]
public IHttpActionResult Get(string eid, string authId)
{
}
+ sign has a different meaning in the query string. It is used to represent a space. Another character that has semantic importance in the query string is & which is used to separate the various var=value pairs in the query string.
Most server side scripts would decode the query parameters before using them, so that a + gets properly converted to a space. Now, if you want a literal + to be present in the query string, you need to specify %2B instead.
Example yourString.replace("+","%2b")
Alternative method : You should URLEncode your query string values to make sure you are not loosing the content.
Another alternate way is like create your own code for + sign. for example 12sfdhjsj8722nsn2232dfsdd will represent a + sign. so you can replace the + sign with the code and in your server side you can get it back using the same code.

WKWebView load webpage with special characters

I've got a wkwebview that works as a browser. I can't manage to load addresses with special characters such as "http://www.håbo.se" (swedish character).
I'm using:
parsedUrl = [parsedUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
which is promising as it creates an address that looks like follows:
http://www.h%c3%a5bo.se/
If I enter that in Chrome it works. But when I try to load it in the wkwebview i get the following (I can load all other pages):
Here's the full NSError printed
Error Domain=NSURLErrorDomain Code=-1003 "A server with the specified hostname could not be found." UserInfo={_WKRecoveryAttempterErrorKey=<WKReloadFrameErrorRecoveryAttempter: 0x7f82ca502290>, NSErrorFailingURLStringKey=http://www.h%c3%a5bo.se/, NSErrorFailingURLKey=http://www.h%c3%a5bo.se/, NSUnderlyingError=0x7f82ca692200 {Error Domain=kCFErrorDomainCFNetwork Code=-1003 "A server with the specified hostname could not be found." UserInfo={NSErrorFailingURLStringKey=http://www.h%c3%a5bo.se/, NSErrorFailingURLKey=http://www.h%c3%a5bo.se/, _kCFStreamErrorCodeKey=8, _kCFStreamErrorDomainKey=12, NSLocalizedDescription=A server with the specified hostname could not be found.}},
This one is complicated. From this article:
Resolving a domain name
If the string that represents the domain name is not in Unicode, the
user agent converts the string to Unicode. It then performs some
normalization functions on the string to eliminate ambiguities that
may exist in Unicode encoded text.
Normalization involves such things as converting uppercase characters
to lowercase, reducing alternative representations (eg. converting
half-width kana to full), eliminating prohibited characters (eg.
spaces), etc.
Next, the user agent converts each of the labels (ie. pieces of text
between dots) in the Unicode string to a punycode representation. A
special marker ('xn--') is added to the beginning of each label
containing non-ASCII characters to show that the label was not
originally ASCII. The end result is not very user friendly, but
accurately represents the original string of characters while using
only the characters that were previously allowed for domain names.
For example, following domain name:
JP納豆.例.jp
converts to next representation:
xn--jp-cd2fp15c.xn--fsq.jp
You can use following code to perform this conversion.
Resolving a path
If the string is input by the user or stored in a non-Unicode
encoding, it is converted to Unicode, normalized using Unicode
Normalization Form C, and encoded using the UTF-8 encoding.
The user agent then converts the non-ASCII bytes to percent-escapes.
For example, following path:
/dir1/引き割り.html
converts to next representation:
/dir1/%E5%BC%95%E3%81%8D%E5%89%B2%E3%82%8A.html
For this purpose, you may use following code:
path = [URL.path stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLPathAllowedCharacterSet]];
Note that stringByAddingPercentEscapesUsingEncoding: is deprecated, because each URL component or subcomponent has different rules for what characters are valid.
Putting it all together
Resulting code:
#implementation NSURL (Normalization)
- (NSURL*)normalizedURL {
NSURLComponents *components = [NSURLComponents componentsWithURL:self resolvingAgainstBaseURL:YES];
components.host = [components.host IDNAEncodedString]; // from https://github.com/OnionBrowser/iOS-OnionBrowser/blob/master/OnionBrowser/NSStringPunycodeAdditions.h
components.path = [components.path stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLPathAllowedCharacterSet]];
return components.URL;
}
#end
Unfortunately, actual URL "normalization" is more complicated - you need to handle all remaining URL components too. But I hope I've answered your question.

Usage of url_encode

I tried using Ruby's url_encode (doc here.)
It encodes http://www.google.com as http%3A%2F%2Fwww.google.com. But it turns out that I cannot open the latter via a browser. If so, what's the use of this function? What is it useful for, when the URL that it encodes can't even be opened?
A typical use is the HTTP GET method, in where you need a query String.
Query String 1:
valudA=john&valueB=john2
Actual value server get:
valueA : "john"
valueB : "john2"
url_encode is used to make the key-value pair enable to store the string which includes some non-ASCII encoded character such as space and special character.
Suppose the valueB will store my name, code 4 j, you need to encode it because there are some spaces.
url_encode("code 4 j")
code%204%20j
Query string 2:
valueA=john&valueB=code%204%20j
Actual value server get:
valueA: "john"
valueB: "code 4 j"
You can use url_encode to encode for example the keys/values of a GET request.
Here is an example of what a SO search query URL looks after encoding:
https://stackoverflow.com/questions/tagged/c%23+or+.net+or+asp.net
As you can see, url encoding appears to be applied only on the last part of the URL, after the last slash.
In general you cannot use url_encode on your entire URL or you will also encode the special characters in a normal URL like the :// in your example.
You can check a tutorial that explains how it works here: http://www.permadi.com/tutorial/urlEncoding/