Adding images to RadioButtonList causes error on postback - c#

I have RadioButtonList, in which I am adding images dynamically:
this.RlCredtiCardTypes.Items.Add(new ListItem(String.Format("<img src='{0}'>", GetImageUrl(item.Code), item.Code)));
This will render fine, but on post back I get the following error:
A potentially dangerous Request.Form value was detected from the client
I understand the error. The question is; how do I dynamical add images to my RadioButtonList without causing this error?
I have also tried to HttpContext.Current.Server.HtmlEncode the img string, but that renders the literal text and not the image.
As a note, I do not want to set EnableEventValidation="false", as this will leave my page open to nefarious activity.
This question seems to related to this question, but its not marked as answered.

message A potentially dangerous Request.Form value was detected from the client comes whenever you try to pass html string via post in asp.net
Your best way to do is encode string into base64 and than decode it while showing into form and while posting form's data back just convert all html related data into base64 string via jquery or javascript.

The reason this occurs is the html code for the image is being sent across in the post back. You can disable validation on the RadioButtonList by adding ValidateRequestMode="Disabled" validaterequestmode(v=vs.110)
<asp:RadioButtonList ID="RlCredtiCardTypes" runat="server" ValidateRequestMode="Disabled"></asp:RadioButtonList>
This will leave the rest of your form securely checking against evil code.

Related

Passing Html string to div innerhtml and its causing errors

I'm running into an error when I try put this is in a textbox like this,
tbGameTitle.Text = "<iframe id = 'ForIframe' src='http://e.gamesalad.com/play/117208' allowTransparency='true' scrolling='no'></iframe>";
when I click on my button
myThing.InnerHtml = tbGameTitle.Text;
it throws this error
A potentially dangerous Request.Form value was detected from the client (tbGameTitle="<iframe id = 'ForIfr...").
If I have this load on the pageload event then its fine. But as soon as I enter this in the textbox and click on my button, it throws that error. I had it working in another project from way back and it never threw this error.
ASP.Net form content is checked for dangerous content when it is submitted (things like HTML and javascript are flagged as being potentially dangerous and are rejected). There are a few ways of allowing this content to be submitted, HTML encoding your text before it is send to the server or disabling request validation using a tag in the top of your page (potentially unsafe!):
<# Page validateRequest="false" %>
More information on request validation can be found at this link
You need to escape characters like "<".
Read a little about: XSS
This post must be helpful.
the main code you want from that page is:
// The event to escape the data and store in our HiddenField
jQuery('.allow_html textarea').blur(function () {
jQuery(jQuery(this).parent()).find('input[type="hidden"]').val(escape(jQuery(this).val()));
});
// The code to unescape the code and set it in our textbox
jQuery('.allow_html textarea').each(function(idx, item) {
var value = jQuery(jQuery(item).parent()).find('input[type="hidden"]').val();
jQuery(item).val(unescape(value));
});
that will escape HTML code in the input.
and, at the server side you need to unescape it:
// encode the data
HtmlCodeHiddenField.Value = Uri.EscapeDataString(EscapedHtml);
// decode the data
string myHtml = Uri.UnescapeDataString(HtmlCodeHiddenField.Value);

Pass data to server side from Javascript code

I'm trying to send data from client-side to server-side (asp.net c#), if you really want to know, I want to send the window.name property.
First I thought about having a asp:HiddenField and on the OnSubmit event have some JS write the value in the hidden field. The only problem is that I can access the hidden field value (according to this) only from PreLoad event to PreRenderComplete event. The project that I'm working on has a lot of code in the OnInit event, and unfortunately I cannot move it and I need to use the window.name value here.
The other ideas that I have is to add a custom HTTP Header windowId or on the OnSubmit event have a JS that appends a parameter to the document.location.href.
I managed to write to the header from JS with the XMLHttpRequest setRequestHeader, but, maybe I did something wrong in my implementation, this generates 2 requests, the first one is the normal, expected one(clicking a button/link ...) and the second is from the XMLHttpRequest. I find this behavior very unnatural. Do you have any sugestions? (see code snippet below). I do not what to use AJAX.
var oReq = new window.XMLHttpRequest;
oReq.open('POST', document.location, false);
oReq.setRequestHeader("windowId", window.name);
oReq.send(null);
For the OnSubmit hook idea, i haven't spent to much time on it, but i think I have to append the # character before i append my windowId parameter with it's value, so that the page doesn't reload. I might be wrong about this. Any way, I have to remove this from the URL after I take the value, so that the user doesn't see the nasty URL. Do you have any sugestions?
Ok so what are your ideas?
Thank you for reading all my blabbering, and thank you, in advance, for you answers.
I would recommend the <asp:HiddenField /> (e.g., <asp:HiddenField ID="hfWindowName" runat="server" />. In OnInit you can still access its value by using Request.Form:
string windowName = Request.Form(hfWindowName.UniqueID);

Make server-side validation without losing data on postback

I would like to know which is the best way to do this: I have a form using ASP that is being validated firstly on client-side with jQuery. In this form I have a FileUpload control to upload an Excel file and the validation of this control is being made on server-side to check the file type, valid data, valid structure, etc... I really need to make the file validation on server-side to be as secure as possible and I don't want to use ActiveX.
The problem is that, when the server-side validation returns an error, the previously inserted data in the form is lost due to the postback.
Is there a way to make client-side validation, then after this is done, make the server-side validation and on the postback don't lose the sent data?
I think the best way to do that is to get old values of field at Page_Load.
All you have to is check if page is postback.
if (Page.IsPostBack)
{
YourTextBox.Attributes.Add("Value", YourTextBox.Text);
}
Hope this help you.
Try adding a CustomValidator to you form that will call the FileUpload.SaveAs() method and that will validate the uploaded file.
For example:
protected void ValidateCstm_ServerValidate(object source, ServerValidateEventArgs args)
{
//Upload the file
fileUpload1.SaveAs(....
.....
.....
//Validate the fileUpload
.....
//If the fileUpload is invalid
args.IsValid = false;
}
I hope that this helps.
Have you considered using AJAX for the file validation, thus avoiding a full post back altogether? There are several AJAX-based file upload widgets 'out there' that might serve your purposes...
just when you encountered any error on server side , set all your form post data in some session variable and redirect to the form and show the form filled up with this session data.
Alternatively you can use jQuery File Upload component. It does not require post backs. It needs server to handle HTTP GET, POST and DELETE and return JSON. You can use ASHX for this. This way your server side validation will not interfere with post backs.

passing value from opener to popup and processing it server side, not client side. Cant use a GET

I have an aspx web page (opener) which opens a popup window
In the popup window I need to retrieve the value of a hidden field which exists in the opener page.
So this is all straight forward using Javascript.
However, here’s the problem, I need the value of the hidden field to be processed SERVER side before the pop up page loads
(Basically, the hidden field contains XML which need to be deserialized server side and the data used to construct the DOM of the popup page)
So how do I pass the data in the hidden field of the opener, to get processed serverside in popup?
The data is Waaay too long to be passed as a GET. i.e. in the querystring of the popup page
What are the other options here?
Retrieve it using Javascript in popup, then do a postback to reload the page (very ugly)
Somehow post the data when opening the popup? Is this possible and can I stil pass other info via the querystring
Any other ideas?
Have a form like this
<form method="POST" action="action.php" onsubmit="open_popup(this);">
<input name="really-big-field" type="hidden">
</form>
also, javascript like this
function open_popup(form)
{
window.open('action.php', 'actionpopup','width=400,height=300');
form.target = 'actionpopup';
}
window.open() will open a popup like you want.
Setting the form's target to the opened popup will make sure that the form will POST to that popup.
Since a POST is made, you can send larger data than you can send using GET.
You can process the data server side in action.php (or in ASP.Net/VB file).
My usual solution to this sort of issue is to use XmlHTTPRequest to post the XML to the server, which simply stores the XML against some unique ID such as a GUID and have the ID returned from the server.
The URL you provide for your popup would then only need to carry this ID rather than the whole XML. Now when the server code on the other end of that URL needs the XML it can use the ID to look up the XML (probably deleting it from its temporary store at the same time) and can process the XML as if had been posted in the request.
Edit: Sorry, I realize this doesn't answer your question. I didn't read it clearly enough and didn't realize you needed to do it server side. I suppose if you wanted to take this path, though, you could then AJAX up your page to build it.
Parent page:
foo = 'bar';
child = open ("popup.html");
// you can now access the new windows functions with child.varname and child.function()
Child page:
alert(window.opener.foo);
Should alert Foo. Therefore you can:
somevar = window.opener.document.getElementById('id').value;
to get the field's value.

user control event handler lost on postback

I have a menu usercontrol called LeftMenu that has a bulletedlist of linkitems. It's on the ascx page as such:
<asp:BulletedList ID="PublisherList" DisplayMode="LinkButton" OnClick="PublisherList_Click" cssClass="Menu" runat="server"></asp:BulletedList>
I databind the list in the page_load under if(!isPostBack)
I'm having an issue on a page that loads the control. When the page first loads, the event handler fires. However, when the page posts back it no longer fires and in IE8, when I'm debugging, I get "Microsoft JScript runtime error: Object expected" in Visual Studio pointing at "__doPostBack('LeftMenu$PublisherList','0')." In FF I don't get the error, but nothing happens. I'm not loading the control dynamically, it's loaded on the aspx page using:
<%# Register TagPrefix="Standards" TagName="LeftMenu" Src="LeftMenu.ascx" %>
<Standards:LeftMenu ID="LeftMenu" runat="server"/>
Any ideas of where I'm losing the event handler?
I just realized this is happening on another user control I have as well. A text box and a button and I'm using the default button to make sure pressing the enter key uses that button. .Net converts that in the html to:
<div id="SearchBarInclude_SearchBar" onkeypress="javascript:return WebForm_FireDefaultButton(event, 'SearchBarInclude_QuickSearchButton')">
so as soon as i enter a key in the box I get a javascript error at the line saying "object expected." It seems like the two issues are related.
Edit Again: I think I need to clarify. It's not that I'm clicking on the menu item and it can't find the selected item on postback. I have this search page with the left navigation on it and then the main content of the page is something that causes a postback. Everything is fine with this postback. Once that page has been posted back, now if I click on the bulleted list in the left navigation I get a javascript error and it fails. The page_init for the LeftMenu control is never called.
It sounds like you might be losing the click because you are not DataBinding the list on PostBack. Therefore, the post back is trying to refer to a control (a specific bulleted list item) that does not exist.
You should try binding the list again on PostBack just to see if that fixes your issue. BUT, what should REALLY happen is that the LeftMenu and the BulletedList should store their information into ViewState so that you can ensure that the data that was shown to the user on their initial page load is the same data that the PostBack is processing and working with.
If you have EnableViewState=true for your UserControl and all controls within it, everything should work fine. With ViewState enabled, ASP will reinflate your controls from ViewState after Init has fired. This means that the postback event arg (which points to an index in your control list) will still find the control in that list position. Otherwise the list is empty on postback.
However, ViewState is the work of the devil and was designed simply to foster the illusion that you are working in a stateful environment. It is okay to use it for small amounts of data but typically not advisable for templated controls like repeaters and lists because you have no idea how much data is going to be created in ViewState.
If you are dealing with static, or relatively static data, store it in the application cache and rebind your lists in Page.Init every time (note that it has to be in Init because post-init is when ASP rebinds from ViewState; if you get in there first, your data will be used instead).
If you are dealing with volatile data, you have a problem because the data you rebind must be exactly the same as the original page request, otherwise the postback events will be firing against the wrong rows. In that case you need to either store your initial data in Session or you simply store the list of rows ids (in a hidden variable or Session) and you recreate the data to bind against from the ids each time.
An even better solution is to not use postback events at all. Try to turn all your events into GETs that have an ID on the query string. You can still create the list using binding the first time through the page (as you are currently doing), and you can even GET the same page with a new ID.
If you need to keep state on the same page but need to respond to the user changing a radio button selection (or something else), think about using Ajax calls to update the screen. You also do that with an ID that you pass to the Ajax call.
In general, the more you move from using stateful ASP, the lighter and more responsive your pages will become. You will also be in a better position to move to stateless MVC if necessary. You will also save lots of time lost to debugging obscure problems because ViewState is not available when you need it to be.
The best analysis of ViewState I've read is in the link below. If you fully understand how it works, you can continue to use it without necessarily incurring the costs.
http://weblogs.asp.net/infinitiesloop/archive/2006/08/03/truly-understanding-viewstate.aspx
It's possible that this might be javascript related, and that a script that is loading earlier in the page is throwing an error and causing the page to not be loaded properly.
Are your usercontrols loading any javascript onto the page? Can you check for javascript errors on the initial load of the page?
I moved the code into an existing project we have and for some strange reason, I stopped getting the javascript errors and instead got:
"Invalid postback or callback argument. Event validation is enabled using <pages enableEventValidation="true"/> in configuration or <%# Page EnableEventValidation="true" %> in a page.
For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them. If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation."
I haven't quite figured out where I'm supposed to put the register event validation with a user control, but in the mean time I just set enableeventvalidation=false and it seems to work now.
It looks like the doPostBack function is missing since its arguments are literals so they couldn't be the cause. Is that one of your own functions or did you mean to call the ASP __doPostBack function?
Have a look at the Firefox error console or allow script debugging in IE and see exactly what object can't be found. Even better, download Firebug and debug it.
I had a similar issue. It turned out that Akamai was modifying the user-agent string because an setting was being applied that was not needed.
This meant that some .NET controls did not render __doPostBack code properly. This issue has been blogged here.

Categories