Query String parameter value truncate after # - c#

Problem - The query string parameter value is getting truncated if I have # in the parameter string value.
I have a table where I am binding the anchor tag <a/> prop href value like below;
<a class="btn btn-primary" href="/FileDetails/DownloadBlob?dirName=#data.FolderName&blobName=#data.FileName">
after binding on browser:
<a class="btn btn-primary" href="/FileDetails/DownloadBlob?dirName=RSHSYNCADE&blobName=J231132 anyfoostringnjectable barfoorBstringch #212422627, string Batch #145876V.pdf">
In the above anchor tag for href prop value I am setting a Controller/Action along with the query string parameters dirName and blobName.
But when the control comes to the specified action method of the controller it truncates the second param value from # means I can only see a value upto J231132 anyfoostringnjectable barfoorBstringch.
While trying to find a fix on internet, I am unable to find a proper solution which fit to my scenario till now.
Can anyone please help me to understand what causing this issue and what would be the fix for these kind of issues?

You need to encode the url that you put in the anchor href. If that values comes from the server, use HttpServerUtility.UrlEncode when you set the href tag. Otherwise you can use encodeURIComponent function in javscript or replace the "#" with "%23"

Query string URL must be encoded, there is some special characters for instance if you put plus(+) in query string. It will be handle as space because handler
will detect it as an encoded string then will replace it with space.
Encoded form of plus(+) is %2B
Encoded form of sharp(#) is %23
if you send the sharp value as %23 will handle as a sharp(#) and you won't have problem.
As helper you may use URi builders. There is many NuGet package exist.

in asp.net core view,you could try with asp-route-yourkeyor asp-all-route-data
I tried as below :
<a asp-action="AnotherAction"asp-route-atm="999#999">somelink</a>
Result:

Related

Why do I have to encode a string when reading and writing form inputs using jquery?

I am programatically reading data from a text input using standard Jquery like this:
var listName = $('#list').val();
and then I am adding a hidden input field into a form before submitting like this:
var myForm = $("#myForm);
myForm.append('<input type="hidden" name="List" value="' + listName + '" />');
In one example, the value in the field is:
Key Date & Times
so on the UI it looks like this
<input type="hidden" name="MyList" value="Key Date & Times" />
when I submit the form using:
var myForm = $("#myForm);
myForm.submit();
and check it on the asp.net-mvc server side i only see:
Key Date
being sent over. After some research, it was suggested to write some javascript to run the value through:
encodeURIComponent()
After doing that and taking a look at the server side, I now see:
Key%20Date%20%26%20Times
How can I convert that back to
Key Date & Times
on the C# asp.net-mvc server side? Or Seperately, if I am doing something wrong on the client side, please let me if you have any suggestions.
My main question is why do i have to worry about encoding the value of a hidden input box in a form. I would have thought this would be taken care of for you.
string decodeString = HttpUtility.UrlDecode(#"Key%20Date%20%26%20Times");
Use UrlDecode method of HttpUtility class.
There's something wrong on client-side. I've tested the following code which is like one you wrote and worked fine!
<input type="hidden" id="ref" value="Key Date & Times" />
<form id="form1" action="~/home/handle" method="post">
<input type="submit" />
</form>
<script>
var myForm = $('#form1');
var listName = $('#ref').val();
myForm.append('<input type="hidden" name="name" value="' + listName + '" />');
</script>
You have no need to use conversion tools!
I think no need to do any thing with your code, it works properly, i have folow below code, please confirm it.
View/Html:
#using (#Html.BeginForm("Save", "Home", FormMethod.Post, new { id = "myForm", name = "myForm" }))
{
<input type="button" class="btn btn-danger" value="Click" id="btnClick">
}
Jquery:
$(document).ready(function () {
var myForm = $("#myForm");
myForm.append('<input type="hidden" name="List" value="Key Date & Times" />');
$('#btnClick').click(function () {
var myForm = $("#myForm");
myForm.submit();
});
});
Controller:
public ActionResult Save()
{
return RedirectToAction("Index");
}
Output:
this happens when you use GET method to submit a form (in GET method '&' acts as a variable separator) you have to use POST method or String manipulation.
if you are using encodeURIComponent() you can convert it back using Server.UrlDecode(""); on server side
you can also read this for extra knowledge Click here
It is very likely you are submitting a GET request to the server, and therefore all values of each input form fields are posted to the server in the query string.
In this way, as already said by Zulqarnain Jalil, every '&' it is interpreted by the server as a separator of the key/value pairs in the query string, and so you miss the last part of your "List" hidden input form field.
Hence, in this case you have to url-encode all your values with "&" char.
Instead, if you submit a POST request to the server, you needn't to do any url-encoding of form field values, because they are passed to the server separately, namely not in the same string.
If you want to avoid url-encoding try to transform your request in a POST request:
var myForm = $("#myForm");
myForm.method = "post";
myForm.submit();
You can also use. There is typo at var myForm = $("#myForm");
string decodeString = Server.UrlDecode("Key%20Date%20%26%20Times");
OR
string decodeString = Uri.UnescapeDataString("Key%20Date%20%26%20Times");
A lot of this has to do with implementing security against Cross Site Scripting attacks (XSS). You need to encode all html input fields that will be used in the post request. Otherwise someone could add domaliciousStuff() to a text field and it would be stored in the database. Then when the data is displayed on the form again, your script (now saved in the database, will run on the web page!).
AntiXSS is a great library that possesses more capabilities than the built-in Html.Encode. You can find it via Nuget Package Manager.
https://www.nuget.org/packages/AntiXSS/
Your main question encoding the value of a hidden input box in a form can be answered like this and this is just not pertaining to hidden inputs it relates to any data being posted to the server.
When data contains spaces and special characters like (&) in your case then it is the responsibility of the application developer to encode it so that the data is safe to be processed by the server. Having spaces and special characters pose security issues like XSS. This is just one of the many steps a responsible developer should take to mitigate such security threats.
Regarding how to get back the values at the server side use the following class found in System.Web namespace
string values = "Key%20Date%20%26%20Times";
string decodeString = HttpUtility.UrlDecode(values);
Hope it answers your question(s)
You can simply add accept-charset="ISO-8859-1" in form tag and don't worry about encoding it automatically converts special characters.
<!DOCTYPE html>
<html>
<body>
<form action="demo_form.asp" accept-charset="ISO-8859-1">
First name: <input type="text" name="fname"><br>
Last name: <input type="text" name="lname"><br>
<input type="submit" value="Submit">
</form>
</body>
</html>
You can test it here
I had the same problem 3 to 4 days back. I was working with Angular and ASP.
Like the answers above state I too had to use URLDecode.
Answering your question:- Why should I encode user input?
Avoid Unexpected Behaviour
Say your application can handle two parameters in a GET request.
This only takes in one argument
localhost:5000/stalls?searchbook=
This takes in two arguments
localhost:5000/stalls?searchbook=&includesecret=
You also have a page that can search for books.
Whatever the user types into the search bar results in a GET request.
localhost:5000/stalls?searchbook=USERSTRINGGOESHERE
If the user were to search for
&includesecret=true
Resultant GET Request localhost:5000/stalls?searchbook=&includesecret=true and might accidentally result in private data being leaked to the user on the results page.
Symbols that are normally encoded (spaces, &, % etc) can many a times mean different things. '&' separates keys in a GET request and can also be a part of a string, so using it without encoding can result in expected behaviour.
P.S:- Private data shouldn't be queried via a GET request. It's just for the sake of this example :)
Consistency
While testing my application I noticed that PhantomJS encoded strings by default. This way I got different search results in different clients. It is therefore safe to assume that some clients might encode the URL even if you don't do it.
Another Example
'#' keys can be a part of a URL. If I visit localhost:5000/homepage.html#footer the element with the ID footer comes into display. This too can cause lead to behaviour that you do not expect. Try entering # in a GET request parameters that isn't encoded nor is cleaned of non alphabetic characters and you'll most likely end up in a situation similar to mine. The search functionality that I wrote a few days back would break if I entered # in it (when it wasn't encoded).
You can replace all the %20 with spaces.
string values = "Key%20Date%20%26%20Times";
string decodeString = values.replace(/%20/g,' ');
you said your main question is:
why do i have to worry about encoding the value of a hidden input box
in a form. I would have thought this would be taken care of for you.
Well, the answer is because otherwise it could lead to injection problems. (Also, hidden fields are not the place for storing sensitive information and I wonder why that input is hidden, also, to be hidden won't change how it behaves...)
In order to fix your issue you could mix htmlEscape and string replace functions, like in the answer to this question (Encode hidden form field value)
function htmlEscape(str) {
return String(str)
.replace(/&/g, '%26')
.replace(/ /g, '%20');
}
I hope it helps.

How to correctly encode MailTo links in ASP.NET MVC?

I have the following mailto link on an ASP.NET MVC 5 application:
<a rel="nofollow" href="#(
String.Format("mailto:?subject={0}&body={1}",
"The title", "The description" + "%0D%0A" + "http://theurl.xyz")">
share by email
</a>
This is not validating on HTML Validator. I get the error:
Bad value mailto:?subject=The subject&body=This is the url:%0D%0Ahttp://localhost:8580/home for attribute href on element a: Whitespace in query component. Use %20 in place of spaces.
I tried encoding using HttpUtility.UrlEncode but when I open the email I get "+" signs and others in the subject and body and I am not able to solve that.
I know this is a little old, but I came across this when I was trying to figure out the best way to encode mailto links. I've found the best way is use Uri.EscapeDataString for each parameter and then encode the entire attribute thing using HttpUtility.HtmlAttributeEncode:
HttpUtility.HtmlAttributeEncode(
String.Format("mailto:?subject={0}&body={1}",
Uri.EscapeDataString(subject),
Uri.EscapeDataString(body)))
HttpUtility.UrlEncode and HttpUtility.UrlEncodeUnicode do not correctly encode spaces -- they become plus signs ("+") which then show up as plus signs in the subject line/body/etc. HttpUtility.UrlPathEncode seems to fix that problem, but doesn't properly encode other characters like ?, #, and /. Uri.EscapedDataString seems to be the only method that properly encodes all of these characters. I imagine Uri.HexEscape would work equally as well, but it seems like that might be overkill.
Caveat: I haven't tested this with even a remotely wide variety of browsers and email clients
You need to use the HttpUtility.UrlPathEncode instead of the HttpUtility.UrlEncode:
<a rel="nofollow" href="#(
(String.Format("mailto:?subject={0}&body={1}",
HttpUtility.UrlPathEncode("The subject line"),
HttpUtility.UrlPathEncode("The body") + "%0D%0A" + "http://theurl.xyz"))))">
share by email
</a>
Note: you need to HttpUtility.UrlPathEncode the parts separately, and you cannot put the HttpUtility.UrlPathEncode around the whole String.Format because the HttpUtility.UrlPathEncode handles the ? specially and only encodes the text before the ?.
From MSDN:
You can encode a URL using with the UrlEncode method or the
UrlPathEncode method. However, the methods return different results.
The UrlEncode method converts each space character to a plus character
(+). The UrlPathEncode method converts each space character into the
string "%20", which represents a space in hexadecimal notation.
That's because razor doesn't know when to start processing c# code. You have to explicitly tell razor when to interpret c#...
<a rel="nofollow" href=" #(string.Format("mailto:?subject={0}&body={1}", ViewBag.Title, ViewBag.Description + "%0D%0A" + ViewBag.Url))>Share by Email </a>
Edit
Answer
I got carried away by sytanx errors you had in your razor. However, even after you edited your question I can still see some issues there. The first issue is that you open two parenthesis but close only one. The second issue is that you specify an empty email address, well, you should at least add a space (not html encoded). And the last issue is that you are not actually separating the subject and body because you are using ? instead of &. If you correct these issues you should be good to go. Here's an example based on your question...
<a rel="nofollow" href="#(String.Format("mailto: ?subject={0}&body={1}"
, "The title"
, "The description" + "%0D%0A" + "http://theurl.xyz"))">
share by email
</a>
That should work as it is. But if you want to do more funky stuff, please read this RFC

How to get # value from query string?

Please help me to get query string value from the URL.
http://test.com/test.aspx#id=test
I tried to access with
Request.QueryString["id"]
Its getting null value.Please suggest how to access id from the url.
Thanks
I agree with everyone that the # should be a ?, but just FYI:
Note it isn't actually possible get the anchor off the URL, for example:
http://test.com/test.aspx#id=test
The problem is that # specified an anchor in the page, so the browser sees:
http://test.com/test.aspx
And then looks in the page for
<a id="test">Your anchor</a>
As this is client side you need to escape the # from the URL - you can't get it on the server because the browser's already stripped it off.
If you want the part after the # you have to copy it using Javascript before the request is sent to the server, and put the value in the querystring.
More info here c# get complete URL with "#"
A query string starts with a question mark ? not a hash #.
Try:
http://test.com/test.aspx?id=test
Using a hash, you're asking to jump to a named anchor within the document, not providing a query string
Your URL is not valid.
http://test.com/test.aspx#id=test
refers to a bookmark named id=test.
You should use
http://test.com/test.aspx?id=test
And then Request.QueryString["id"] will work.
If you would like to use it as hash tag you can use:
string value = Request.Url.ToString().Split('#')[1];
with this code, you will have your hash tag value.
Isnt it supposed to be?
http://test.com/test.aspx?id=test

Remove anchor from URL in C#

I'm trying to pull in an src value from an XML document, and in one that I'm testing it with, the src is:
<content src="content/Orwell - 1984 - 0451524934_split_2.html#calibre_chapter_2"/>
That creates a problem when trying to open the file. I'm not sure what that #(stuff) suffix is called, so I had no luck searching for an answer. I'd just like a simple way to remove it if possible. I suppose I could write a function to search for a # and remove anything after, but that would break if the filename contained a # symbol (or can a file even have that symbol?)
Thanks!
If you had the src in a string you could use
srcstring.Substring(0,srcstring.LastIndexOf("#"));
Which would return the src without the #. If the values you are retreiving are all web urls then this should work, the # is a bookmark in a url that takes you to a specific part of the page.
You should be OK assuming that URLs won't contain a "#"
The character "#" is unsafe and should
always be encoded because it is used in World Wide Web and in other
systems to delimit a URL from a fragment/anchor identifier that might
follow it.
Source (search for "#" or "unsafe").
Therefore just use String.Split() with the "#" as the split character. This should give you 2 parts. In the highly unlikely event it gives more, just discard the last one and rejoin the remainder.
From Wikipedia:
# is used in a URL of a webpage or other resource to introduce a "fragment identifier" – an id which defines a position within that resource. For example, in the URL http://en.wikipedia.org/wiki/Number_sign#Other_uses the portion after the # (Other_uses) is the fragment identifier, in this case indicating that the display should be moved to show the tag marked by ... in the HTML
It's not safe to remove de anchor of the url. What I mean is that ajax like sites make use of the anchor to keep track of the context. For example gmail. If you go to http://www.gmail.com/#inbox, you go directly to your inbox, but if you go to http://www.gmail.com/#all, you'll go to all your mail.
The server can give a different response based on the anchor, even if the response is a file.

How do I encode an URL?

When I run my project I get the url http://localhost:5973/PageToPageValuePass/Default.aspx I want to Encode the URL since sometimes I need to transfer data from page to page. When the urls are encoded then it increases the reliability.
Server.UrlEncode("http://www.google.com/c#");
I get this, but how do I use it to help me encode the url?
If your encoding parts of the path:
System.Uri.EscapeUriString("c#")
If your encoding 'arguments':
String.Format( "http://something/?test={0}", System.Uri.EscapeDataString("c#") );
try this
in ASP.NET
Server.UrlEncode("http://www.google.com/c#");
in WinForms using System.Web.dll
HttpUtility.UrlEncode("http://www.google.com/c#");
Url encoding is used to ensure that special symbols included in a url (most likely in a querystring) are not mistakenly interpreted as those used in the parsing and processing of a url. For example, the + symbol is used to indicate a space in a url. However, if you were intending for a + symbol to be a part of your querystring then you would want to encode that querystring before sending it to a browser.
For example. Imagine you have written a page that receives a math equation on the querystring and displays that equation on the page.
The url might be: http://yoursite.com/displayMath.aspx?equation=3+5
The + symbol in this case is intended to be a meaningful part of the equation. However, without a UrlEncode it would be interpreted as representing a space. Reading this value from the querystring on the receiving page would yield "3 5", which is not what was intended.
Instead of redirecting to that url directly, you would want to URL encode the request first. You might write the following code:
string equation = "3+5";
string url = String.Format(#"http://yoursite.com/displayMath.aspx?equation={0}", equation);
string encodedUrl = Server.UrlEncode(url);
Response.Redirect(encodedUrl);
This would ensure that a subsequent Request.Querystring["equation"] would receive the equation intact because any special symbols would first be encoded.
I'm not sure I understand your use case for encoding urls. If you could perhaps provide more information on what you are trying to achieve I will attempt to answer more fully. For now I hope that this information is useful.
say you want to create a link with some parameters you can use it as follows:
aspx:
Click Here
code behind:
myLink.Href = Page.ResolveClientUrl("~/MyPage.aspx") + "?id=" +
Server.UrlEncode("put here what ever you want to url encode");
Or as in your question:
myLink.Href = "http://www.google.com/")+Server.UrlEncode("C#");
this will put in html:
<a id="myLink" runat="server" target="_self" href="http://www.google.com/c+c%23">

Categories