HtmlHelper.Button(..., string onClickMethod, ...) HTML-encodes single-quotes! - c#

I'm upgrading an old project from MVC 1.0 to MVC 3.0 (yes, it's that old), and I've run into an issue where calling HtmlHelper.Button(..., onClickMethod, ...) HTML-encodes single quotes into '
I can see how this would not be an issue if onClickMethod was just the name of a method to be called in javascript, however this is how we are using it:
return helper.Button(name, buttonText, HtmlButtonType.Button,
string.Format("window.location='{0}'", url));
which obviously is now broken.
Is there any way to bypass this encoding? I can see hacking it by changing the return type of the method to string, and doing:
return string.Format(helper.Button(name, buttonText, HtmlButtonType.Button,
"window.location={0}").ToString(), "'" + url + "'");
but this is more or less a hack, and not elegant.

Having the ' should work. Even though the document stream contains the encoded value the browser unencodes it when it builds the DOM. You can use a DOM inspection tool to see yourself.
If I put the following on a page I see the alert box just fine upon click:
<input type="button" onclick="alert('Hello');" />

You can use the URI class to convert html codes into regular text
Uri.UnescapeDataString(string);

Related

How to fix Veracode error for InnerHtml

When running Veracode, it generated a bunch of errors pointing to the lines with InnerHtml.
For example, one of those lines is:
objUL.InnerHtml += "<tr><td></td><td class=\"libraryEdit\">" + HttpUtility.HtmlEncode(dtitems.Rows[currentitem]["content"].ToString()) + "</td>";
What do alternatives exist to fix it without using html server controls?
What exactly are you trying to do, and what exactly does Veracode say?
Most likely, it is complaining that you could end up with an arbitrary code injection vulnerability if the data passed into your InnerHtml is untrusted and could contain malicious JavaScript.
The tool may not complain if you manually construct the DOM elements using the JavaScript createElement function to build each DOM element manually.
I have faced this issue in my ASP.NET Webforms application. The fix to this is relatively simple.
Install HtmlSanitizationLibrary from NuGet Package Manager and refer this in your application.
At the code behind, please use the sanitizer class in the following way.
For example if the current code looks something like this,
YourHtmlElement.InnerHtml = "Your HTML content" ;
Then, replace this with the following:
string unsafeHtml = "Your HTML content";
YourHtmlElement.InnerHtml = Sanitizer.GetSafeHtml(unsafeHtml);
This fix will remove the Veracode vulnerability and make sure that the string gets rendered as HTML. Encoding the string at code behind will render it as 'un-encoded string' rather than RAW HTML as it is encoded before the render begins.

FlexPaper Localization Not Working

Sorry if this question is out of context, but I don't know where else to look and StackOverflow tends to provide the best support. I'm having a problem with FlexPaper not loading the locale for HTML rendering option. It appears to be working for Flash version with no problem, but not for the HTML viewer specifically.
Here is the config which loads the control onto a page:
var searchServiceUrl = escape(ashxDir + "containstext.ashx?doc=" + guid + "&page=[page]&searchterm=[searchterm]"),
docUrl = escape("{" + ashxDir + "view.ashx?guid=" + guid + "&numPages=" + numPages +"&format={format}&page=[*,0]," + numPages + "}"),
configObj = {
DOC: docUrl,
...
DocSizeQueryService: ashxDir + "swfsize.ashx?doc=" + guid,
jsDirectory: "/FlexPaper/js/",
JSONDataType: "jsonp",
localeDirectory: "/FlexPaper/locale/",
localeChain: "en_US"
};
This is exactly how I've found it while looking through documentation and everything else, but it simply does not work for me. I've scoured the internet and nobody else seems to have this problem. Unfortunately when I click on the print button all of my labels and buttons show 'null'. Here is a screenshot of what I get when I try to load the page in the HTML viewer:
If you notice in my configuration above, the localeDirectory is set as a sibling directory of the js directory. The locale directory has all of the valid directories under it which hold the localized strings for various languages (ie. en_US, zh_CN, etc..). I've even tried moving the locale directory around the system to see if it is expecting a different "root", but again to no avail...
Any information would be greatly appreciated.
i had that "null" problem in my PHP set up of flex paper in that i put locale & js folder in my location so it is not fetching correct path so i put correct path in default page from where $('#documentViewer').FlexPaperViewer({ defines i just put below paths :
jsDirectory:"http://{xxx}/subdirectory/assets/js/",
localeDirectory:"http://{xxx}/subdirectory/assets/locale/",
may be this will help others
We found the problem and I realize that I never updated the case with the 'Answer'. The fix was directly related to a wrong url which fed the localized strings to the dialog. We were only able to track it down by interrogating the HTTP Request using Chrome Web Tools. It wasn't a complex fix, but it proved to be a complex issue to track down and diagnose properly.
Hope this helps someone someday.

javascript not execute at live

I am using Visual Studio. My javascript is functioning if I debug it at local host, the function is very simple, photo change at mouseOver.
But after I upload my file to my server, this function is not working. I have tried it on Chrome, Firefox, IE and Safari:
function mouseOver1()
{
var category1 = document
.getElementById('ctl00_ContentPlaceHolder1_lblItemID')
.innerHTML + '_1.jpg';
document
.getElementById('<%= iPhotoMain.ClientID.Replace("$","_") %>')
.src = 'photos/product/' + category1;
}
<img id ="photo1"
src ="photos/product/noImage.gif"
onmouseover="mouseOver1();"
class="thumbpic"
runat ="server" />
In light of comments made by the OP, my original answer is partially incorrect (although I still don't think you should be using static ID for the lblItemID - so will leave the answer below).
My new guess would be that you have a second mouseOver1(); function defined somewhere on your page, or more likely an external JavaScript file that you are linking to. So I would recommend that you check all external JavaScript files on your server that you link to and make sure they're as you would expect.
I can recommend firebug for firefox or the developers tools under IE and Chrome (F12 on both). With firebug you can breakpoint on the next Javascript to fire, so you can easily find out where the call is going to
Original Answer
My guess is that you have mixed up your object ID's. You are also using a static string to find one of your objects.
If I am correct, please try this - if I am incorrect in my guess, I will happily delete my answer.
(Note, I have changed iPhotoMain into photo1)
function mouseOver1(){
var category1 = document
.getElementById('<%=lblItemID.ClientID%>')
.innerHTML + '_1.jpg';
  document
.getElementById('<%=photo1.ClientID%>')
.src = 'photos/product/' + category1;
}
Maybe on server your pages(data) coming slower than your local. So try callback functions with javascript. Like this..
var category1 = "";
function mouseOver1(callback)
{
category1 = document
.getElementById('ctl00_ContentPlaceHolder1_lblItemID')
.innerHTML + '_1.jpg';
callback();
}
function mouseOver2()
{
document
.getElementById('<%= iPhotoMain.ClientID.Replace("$","_") %>')
.src = 'photos/product/' + category1;
}
<img id ="photo1" src ="photos/product/noImage.gif" onmouseover="mouseOver1(mouseOver2);" class="thumbpic" runat ="server" />

Generating JavaScript in C# and subsequent testing

We are currently developing an ASP.NET MVC application which makes heavy use of attribute-based metadata to drive the generation of JavaScript.
Below is a sample of the type of methods we are writing:
function string GetJavascript<T>(string javascriptPresentationFunctionName,
string inputId,
T model)
{
return #"function updateFormInputs(value){
$('#" + inputId + #"_SelectedItemState').val(value);
$('#" + inputId + #"_Presentation').val(value);
}
function clearInputs(){
" + helper.ClearHiddenInputs<T>(model) + #"
updateFormInputs('');
}
function handleJson(json){
clearInputs();
" + helper.UpdateHiddenInputsWithJson<T>("json", model) + #"
updateFormInputs(" + javascriptPresentationFunctionName + #"());
" + model.GetCallBackFunctionForJavascript("json") + #"
}";
}
This method generates some boilerplace and hands off to various other methods which return strings. The whole lot is then returned as a string and written to the output.
The question(s) I have are:
1) Is there a nicer way to do this other than using large string blocks?
We've considered using a StringBuilder or the Response Stream but it seems quite 'noisy'. Using string.format starts to become difficult to comprehend.
2) How would you go about unit testing this code? It seems a little amateur just doing a string comparison looking for particular output in the string.
3) What about actually testing the eventual JavaScript output?
Thanks for your input!
We created a library specifically for the purpose of embedding JavaScript in a fluent-like syntax into our C# code, and then made it open source.
Have a look at Adam.JSGenerator.
I typically try to create a separate .js file for most/all of my javascript code. Usually I will need to have common bahvior applied to many elements that are dynamically created by ASP controls or server-side code, so I may not be able to code everything into a .js file.
I've found that the main reason that you want to generate javascript on the server is because you won't know the IDs of elements until the page renders. Therefore, I try to condense that dependency down as much as possibly so that I'm generating as little javascript as possible. For example, in traditional ASP.Net (not MVC) if I were rendering a set of forms such as in the example, each with multiple fields, then I would probably have something in the code behind such as this:
protected void FormRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
Control form = e.Item.FindControl("MyForm");
ClientScript.RegisterStartupScript(this.GetType(), "prepareForm_" + form.ClientID, #"prepareForm('" + form.ClientID + "');", true);
}
A separate .js file would include the definition of the prepareForm function, which would be something like this:
// define a formPresenter "class" that encapsulates the behavior for a given form
function formPresenter(formId) {
this.setFirstName = function(value) {
$("#" + formId + "_FirstName").val(value);
}
this.setLastName = function(value) {
$("#" + formId + "_LastName").val(value);
}
// create other functions to handle more complicated logic
// clear fields
this.clearInputs = function() {
this.setFirstName("");
this.setLastName("");
//...
}
// receive Json object
this.handleJson = function(json) {
this.clearInputs();
// populate fields with json object
this.setFirstName(json.FirstName);
this.setLastName(json.LastName);
//...
}
// "constructor" logic
}
function prepareForm(formId) {
// create a new formPresenter object and shove it onto the specified element as the "presenter"
document.getElementById(formId).presenter = new formPresenter(formId);
}
Now almost all of your actual logic is in its own .js file, which should be much easier to maintain. If you need to access the formPresenter object for a given form, then you just need to get a reference to whatever element is referenced by the formId parameter and access the presenter variable:
"document.getElementById(" + form.ClientID + ").presenter.handleJson(json);"
Note: Since I've been using JQuery, I've found less of a need to even include any javascript generated by the server. Typically I can find the elements that I need by looking for a specific CSS class name (or something to that effect) and perform whatever setup/initialization I need.
We're doing a lot of JS generation in our project as well, and we're using StringBuilder to do it.
StringBuilder sb = new StringBuilder();
sb.Append("some javascript stuff")
.Append("some more")
.AppendFormat("formatted stuff {0}", "here");
return sb.ToString();
It's not pretty, but no solution is going to be.
And concerning testing, we don't actually do any unit tests on the generated code. Before release people go and test all the features to make sure they work as expected.
If you don't care about super duper performance you could use a templating language to generate the javascript.
Then for unit testing you would just fill the templates with their appropriate bindings/variables and then run it through a Javascript evaluator like Rhino or whatever the .NET equivalent is to at least test the syntax if not the actual JS code.
Other than that I would seriously question the design of software that is generating Javascript like this. It also looks like you are using JQuery but are referencing the $ directly which may lead to some problems down the line.
If compilers generating Javascript is one thing (ala GWT) but I would separate your client side JS code as much as possible from your .NET code (not to mention your .NET code looks like server side JS talk about confusing).
This in vogue kind of design of separating the client crap from the server is known as SOFEA. I let you google that.

Does C# have an equivalent to JavaScript's encodeURIComponent()?

In JavaScript:
encodeURIComponent("©√") == "%C2%A9%E2%88%9A"
Is there an equivalent for C# applications? For escaping HTML characters I used:
txtOut.Text = Regex.Replace(txtIn.Text, #"[\u0080-\uFFFF]",
m => #"&#" + ((int)m.Value[0]).ToString() + ";");
But I'm not sure how to convert the match to the correct hexadecimal format that JS uses. For example this code:
txtOut.Text = Regex.Replace(txtIn.Text, #"[\u0080-\uFFFF]",
m => #"%" + String.Format("{0:x}", ((int)m.Value[0])));
Returns "%a9%221a" for "©√" instead of "%C2%A9%E2%88%9A". It looks like I need to split the string up into bytes or something.
Edit: This is for a windows app, the only items available in System.Web are: AspNetHostingPermission, AspNetHostingPermissionAttribute, and AspNetHostingPermissionLevel.
Uri.EscapeDataString or HttpUtility.UrlEncode is the correct way to escape a string meant to be part of a URL.
Take for example the string "Stack Overflow":
HttpUtility.UrlEncode("Stack Overflow") --> "Stack+Overflow"
Uri.EscapeUriString("Stack Overflow") --> "Stack%20Overflow"
Uri.EscapeDataString("Stack + Overflow") --> Also encodes "+" to "%2b" ---->Stack%20%2B%20%20Overflow
Only the last is correct when used as an actual part of the URL (as opposed to the value of one of the query string parameters)
HttpUtility.HtmlEncode / Decode
HttpUtility.UrlEncode / Decode
You can add a reference to the System.Web assembly if it's not available in your project
I tried to do full compatible analog of javascript's encodeURIComponent for c# and after my 4 hour experiments I found this
c# CODE:
string a = "!##$%^&*()_+ some text here али мамедов баку";
a = System.Web.HttpUtility.UrlEncode(a);
a = a.Replace("+", "%20");
the result is:
!%40%23%24%25%5e%26*()_%2b%20some%20text%20here%20%d0%b0%d0%bb%d0%b8%20%d0%bc%d0%b0%d0%bc%d0%b5%d0%b4%d0%be%d0%b2%20%d0%b1%d0%b0%d0%ba%d1%83
After you decode It with Javascript's decodeURLComponent();
you will get this:
!##$%^&*()_+ some text here али мамедов баку
Thank You for attention
System.Uri.EscapeUriString() didn't seem to do anything, but System.Uri.EscapeDataString() worked for me.
Try Server.UrlEncode(), or System.Web.HttpUtility.UrlEncode() for instances when you don't have access to the Server object. You can also use System.Uri.EscapeUriString() to avoid adding a reference to the System.Web assembly.
For a Windows Store App, you won't have HttpUtility. Instead, you have:
For an URI, before the '?':
System.Uri.EscapeUriString("example.com/Stack Overflow++?")
-> "example.com/Stack%20Overflow++?"
For an URI query name or value, after the '?':
System.Uri.EscapeDataString("Stack Overflow++")
-> "Stack%20Overflow%2B%2B"
For a x-www-form-urlencoded query name or value, in a POST content:
System.Net.WebUtility.UrlEncode("Stack Overflow++")
-> "Stack+Overflow%2B%2B"
You can use the Server object in the System.Web namespace
Server.UrlEncode, Server.UrlDecode, Server.HtmlEncode, and Server.HtmlDecode.
Edit: poster added that this was a windows application and not a web one as one would believe. The items listed above would be available from the HttpUtility class inside System.Web which must be added as a reference to the project.

Categories

Resources