IE8 post file targeting iframe, arrives on server as null - iframe

I have a form with just an input:file in it and the form targets a named iframe. when the user selects a file it automatically posts the form to the server. This works in IE10/firefox/chrome, but in IE8 the File parameter on my controller method is null when IE8 posts the form. Has anyone else encountered this and know of any solutions, why isn't IE8 actually posting the file data?
ClientSide:
function createFileUploadForm()
{
var frameName = 'fileUploadFormFrame';
var fileValue;
var fileUploadCallback = function()
{
//do stuff when the server responds after receiving the file
};
var fileInputChangedCallback = function(event)
{
if(fileInput.value != fileValue)
{
fileValue = fileInput.value;
form.submit();
}
};
var iFrame = document.createElement('iframe');
iFrame.name = frameName
document.body.appendChild(iFrame);
var form = document.createElement('form');
form.action = 'a/valid/url';
form.method = 'post';
form.enctype = 'multipart/form-data';
form.target = frameName;
var fileInput = document.createElement('input');
fileInput.type = 'file';
fileInput.name = 'File';
fileInput.accept = '.spc';
fileValue = fileInput.value;
//all browsers except IE8
//add event listener to fileInput onChange event -> fileInputChangedCallback
//IE8 fix
//add event listener to fileInput onFocus event -> fileInputChangedCallback
form.appendChild(fileInput);
document.body.appendChild(form);
}
ServerSide:
[HttpPost]
public ActionResult UploadFile(HttpPostedFileBase File)
{
//do stuff with File, but in IE8 File parameter is null
}

the problem was that IE8 requires an additional encoding property on the form to be set:
var form = document.createElement('form');
form.action = 'a/valid/url';
form.method = 'post';
form.enctype = 'multipart/form-data';
form.encoding = 'multipart/form-data'; //this additional line fixes the IE8 problem I was having
form.target = frameName;

Related

View not update after POST although View Model updated

I am writing ASP.NET Custom Component, I want to update my view with following code below:
#if (Model.TableDatasource != null){
//Write some thing to html page example: tables or span
}
At the first, Model.TableDatasource is null, user choose information and Controller Review View(Model) like this:
var model = new PrintDeliveryTicketModel()
{
PlantList = CommonHelper.GetPlantList(),
};
if (request == null)
{
return View(model);
}
else
{
var currentPlant = JsonConvert.DeserializeObject<PlantList>(request);
var FullModel = new PrintDeliveryTicketModel()
{
PlantList = CommonHelper.GetPlantList(),
CurrentPlant = JsonConvert.DeserializeObject<PlantList>(request),
DriverList = JsonConvert.DeserializeObject<List<Drivers>>(CommonHelper.GetDriver(currentPlant.CodePlant, currentPlant.PlantNo.Value).Content.ReadAsStringAsync().Result),
CustomerList = JsonConvert.DeserializeObject<List<Customer>>(CommonHelper.GetCustomer().Content.ReadAsStringAsync().Result),
RecipeList = JsonConvert.DeserializeObject<List<Recipe>>(CommonHelper.GetRecipe(currentPlant.CodePlant, currentPlant.PlantNo.Value).Content.ReadAsStringAsync().Result),
SitesList = JsonConvert.DeserializeObject<List<Site>>(CommonHelper.GetSite().Content.ReadAsStringAsync().Result),
// TruckList = JsonConvert.DeserializeObject<List<Truck>>(CommonHelper.GetTruck().Content.ReadAsStringAsync().Result)
};
return View(FullModel);
}
At the Debug time, I notice that break-point stop at return View(FullMode) and Break-point at ViewFile(cshtml) has value. but nothing printed at view.
Hope some help.

Autofill feature with Listbox in asp.net

i have a Listbox with items being 'first name' loaded from a table of a database,
now i want an autofill feature where if a user types like 'a' all the names starting with 'a' first name should be show in the listbox
and after some button click the original data should be repopulated in the listbox
for 2nd one i.e.. repopulating hope i can do with below code
protected void btnRePopulate_Click(object sender, EventArgs e)
{
DataSet oDs = ReadDataSet();
Listbox1.DataTextField = "Name";
Listbox1.DataValueField = "ID";
Listbox1.DataSource = oDs;
Listbox1.DataBind();
}
but for the 1st i have some things on which iam working (i am using textbox keyup event to fire when the user types 'a' or whatever)
clear the listbox and add the names which starts with 'a', but not sure is it possible from client side
or set another listbox visible with names filtered from the original and hide the original listbox, for which i am not able to set visible property either from js or codebehind
no i dont want to use ajax autofill
is there a better option apart from the above two...
This filtering and resetting is best done on the client side itself. That way you don't make unnecessary server calls. Here is a extension method in jQuery.
$(function() {
$('#select').filterByText($('#textbox'), true);
});
Extension method:
jQuery.fn.filterByText = function(textbox, selectSingleMatch) {
return this.each(function() {
var select = this;
var options = [];
$(select).find('option').each(function() {
options.push({value: $(this).val(), text: $(this).text()});
});
$(select).data('options', options);
$(textbox).bind('change keyup', function() {
var options = $(select).empty().scrollTop(0).data('options');
var search = $.trim($(this).val());
var regex = new RegExp(search,'gi');
$.each(options, function(i) {
var option = options[i];
if(option.text.match(regex) !== null) {
$(select).append(
$('<option>').text(option.text).val(option.value)
);
}
});
if (selectSingleMatch === true &&
$(select).children().length === 1) {
$(select).children().get(0).selected = true;
}
});
});
};
I found this on Lessan Vaezi's blog with a live demo on how to do it.

Why my yui datatable within an updatepanel disappears after postback?

I got my YUI datatable rendered with my json datasource inside an updatepanel... If i click a button within that updatepanel causes postback and my yui datatable disappears
Why yui datatable within an updatepanel disappears after postback?
EDIT:
I am rendering YUI Datatable once again after each post back which is not a form submit... I know it is a bad practice...
What can be done for this.... Any suggestion.....
if (!IsPostBack)
{
GetEmployeeView();
}
public void GetEmployeeView()
{
DataTable dt = _employeeController.GetEmployeeView().Tables[0];
HfJsonString.Value = GetJSONString(dt);
Page.ClientScript.RegisterStartupScript(Page.GetType(), "json",
"EmployeeDatatable('" + HfJsonString.Value + "');", true);
}
When i click any button in that page it causes postback and i have to
regenerate YUI Datatable once again with the hiddenfield value containing
json string..
protected void LbCancel_Click(object sender, EventArgs e)
{
HfId.Value = "";
HfDesigId.Value = "";
ScriptManager.RegisterClientScriptBlock(LbCancel, typeof(LinkButton),
"cancel", "EmployeeDatatable('" + HfJsonString.Value + "');, true);
}
My javascript:
function EmployeeDatatable(HfJsonValue){
var myColumnDefs = [
{key:"Identity_No", label:"Id", width:50, sortable:true, sortOptions:{defaultDir:YAHOO.widget.DataTable.CLASS_DESC}},
{key:"Emp_Name", label:"EmployeeName", width:150, sortable:true, sortOptions:{defaultDir:YAHOO.widget.DataTable.CLASS_DESC}},
{key:"Address", label:"Address", width:200, sortable:true, sortOptions:{defaultDir:YAHOO.widget.DataTable.CLASS_DESC}},
{key:"Desig_Name", label:"Category", width:200, sortable:true, sortOptions:{defaultDir:YAHOO.widget.DataTable.CLASS_DESC}},
{key:"", formatter:"checkbox"}
];
var jsonObj=eval('(' + HfJsonValue + ')');
var target = "datatable";
var hfId = "ctl00_ContentPlaceHolder1_HfId";
generateDatatable(target,jsonObj,myColumnDefs,hfId)
}
function generateDatatable(target,jsonObj,myColumnDefs,hfId){
var root;
for(key in jsonObj){
root = key; break;
}
var rootId = "id";
if(jsonObj[root].length>0){
for(key in jsonObj[root][0]){
rootId = key; break;
}
}
YAHOO.example.DynamicData = function() {
var myPaginator = new YAHOO.widget.Paginator({
rowsPerPage: 10,
template: YAHOO.widget.Paginator.TEMPLATE_ROWS_PER_PAGE,
rowsPerPageOptions: [10,25,50,100],
pageLinks: 10 });
// DataSource instance
var myDataSource = new YAHOO.util.DataSource(jsonObj);
myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
myDataSource.responseSchema = {resultsList: root,fields:new Array()};
myDataSource.responseSchema.fields[0]=rootId;
for(var i=0;i<myColumnDefs.length;i++){
myDataSource.responseSchema.fields[i+1] = myColumnDefs[i].key;
}
// DataTable configuration
var myConfigs = {
sortedBy : {key:myDataSource.responseSchema.fields[1], dir:YAHOO.widget.DataTable.CLASS_ASC}, // Sets UI initial sort arrow
paginator : myPaginator
};
// DataTable instance
var myDataTable = new YAHOO.widget.DataTable(target, myColumnDefs, myDataSource, myConfigs);
myDataTable.subscribe("rowMouseoverEvent", myDataTable.onEventHighlightRow);
myDataTable.subscribe("rowMouseoutEvent", myDataTable.onEventUnhighlightRow);
myDataTable.subscribe("rowClickEvent", myDataTable.onEventSelectRow);
myDataTable.subscribe("checkboxClickEvent", function(oArgs){
var hidObj = document.getElementById(hfId);
var elCheckbox = oArgs.target;
var oRecord = this.getRecord(elCheckbox);
var id=oRecord.getData(rootId);
if(elCheckbox.checked){
if(hidObj.value == ""){
hidObj.value = id;
}
else{
hidObj.value += "," + id;
}
}
else{
hidObj.value = removeIdFromArray(""+hfId,id);
}
});
myPaginator.subscribe("changeRequest", function (){
if(document.getElementById(hfId).value != "")
{
if(document.getElementById("ConfirmationPanel").style.display=='block')
{
document.getElementById("ConfirmationPanel").style.display='none';
}
document.getElementById(hfId).value="";
}
return true;
});
myDataTable.handleDataReturnPayload = function(oRequest, oResponse, oPayload) {
oPayload.totalRecords = oResponse.meta.totalRecords;
return oPayload;
}
return {
ds: myDataSource,
dt: myDataTable
};
}();
}
Hai guys,
I got an answer for my qusetion.... Its my postback that caused the problem and i solved it by making an ajax call using ajax enabled WCF Service in my web application... Everything works fine now....
Anything you are generating client side will have to be regenerated after every page refresh (and after every partial page refresh, if that part contains client-side generated html).
Because the YUI datatable gets its data on the client, you will have to render it again each time you replace that section of html.

Close/kill the session when the browser or tab is closed

Can somebody tell me how can I close/kill the session when the user closes the browser? I am using stateserver mode for my asp.net web app. The onbeforeunload method is not proper as it fires when user refreshes the page.
You can't. HTTP is a stateless protocol, so you can't tell when a user has closed their browser or they are simply sitting there with an open browser window doing nothing.
That's why sessions have a timeout - you can try and reduce the timeout in order to close inactive sessions faster, but this may cause legitimate users to have their session timeout early.
As said, the browser doesn't let the server know when it closes.
Still, there are some ways to achieve close to this behavior. You can put a small AJAX script in place that updates the server regularly that the browser is open. You should pair this with something that fires on actions made by the user, so you can time out an idle session as well as one that has closed out.
As you said the event window.onbeforeunload fires when the users clicks on a link or refreshes the page, so it would not a good even to end a session.
http://msdn.microsoft.com/en-us/library/ms536907(VS.85).aspx describes all situations where window.onbeforeonload is triggered. (IE)
However, you can place a JavaScript global variable on your pages to identify actions that should not trigger a logoff (by using an AJAX call from onbeforeonload, for example).
The script below relies on JQuery
/*
* autoLogoff.js
*
* Every valid navigation (form submit, click on links) should
* set this variable to true.
*
* If it is left to false the page will try to invalidate the
* session via an AJAX call
*/
var validNavigation = false;
/*
* Invokes the servlet /endSession to invalidate the session.
* No HTML output is returned
*/
function endSession() {
$.get("<whatever url will end your session>");
}
function wireUpEvents() {
/*
* For a list of events that triggers onbeforeunload on IE
* check http://msdn.microsoft.com/en-us/library/ms536907(VS.85).aspx
*/
window.onbeforeunload = function() {
if (!validNavigation) {
endSession();
}
}
// Attach the event click for all links in the page
$("a").bind("click", function() {
validNavigation = true;
});
// Attach the event submit for all forms in the page
$("form").bind("submit", function() {
validNavigation = true;
});
}
// Wire up the events as soon as the DOM tree is ready
$(document).ready(function() {
wireUpEvents();
});
This script may be included in all pages
<script type="text/javascript" src="js/autoLogoff.js"></script>
Let's go through this code:
var validNavigation = false;
window.onbeforeunload = function() {
if (!validNavigation) {
endSession();
}
}
// Attach the event click for all links in the page
$("a").bind("click", function() {
validNavigation = true;
});
// Attach the event submit for all forms in the page
$("form").bind("submit", function() {
validNavigation = true;
});
A global variable is defined at page level. If this variable is not set to true then the event windows.onbeforeonload will terminate the session.
An event handler is attached to every link and form in the page to set this variable to true, thus preventing the session from being terminated if the user is just submitting a form or clicking on a link.
function endSession() {
$.get("<whatever url will end your session>");
}
The session is terminated if the user closed the browser/tab or navigated away. In this case the global variable was not set to true and the script will do an AJAX call to whichever URL you want to end the session
This solution is server-side technology agnostic. It was not exaustively tested but it seems to work fine in my tests
Please refer the below steps:
First create a page SessionClear.aspx and write the code to clear session
Then add following JavaScript code in your page or Master Page:
<script language="javascript" type="text/javascript">
var isClose = false;
//this code will handle the F5 or Ctrl+F5 key
//need to handle more cases like ctrl+R whose codes are not listed here
document.onkeydown = checkKeycode
function checkKeycode(e) {
var keycode;
if (window.event)
keycode = window.event.keyCode;
else if (e)
keycode = e.which;
if(keycode == 116)
{
isClose = true;
}
}
function somefunction()
{
isClose = true;
}
//<![CDATA[
function bodyUnload() {
if(!isClose)
{
var request = GetRequest();
request.open("GET", "SessionClear.aspx", true);
request.send();
}
}
function GetRequest() {
var request = null;
if (window.XMLHttpRequest) {
//incase of IE7,FF, Opera and Safari browser
request = new XMLHttpRequest();
}
else {
//for old browser like IE 6.x and IE 5.x
request = new ActiveXObject('MSXML2.XMLHTTP.3.0');
}
return request;
}
//]]>
</script>
Add the following code in the body tag of master page.
<body onbeforeunload="bodyUnload();" onmousedown="somefunction()">
I do it like this:
$(window).bind('unload', function () {
if(event.clientY < 0) {
alert('Thank you for using this app.');
endSession(); // here you can do what you want ...
}
});
window.onbeforeunload = function () {
$(window).unbind('unload');
//If a string is returned, you automatically ask the
//user if he wants to logout or not...
//return ''; //'beforeunload event';
if (event.clientY < 0) {
alert('Thank you for using this service.');
endSession();
}
}
Not perfect but best solution for now :
var spcKey = false;
var hover = true;
var contextMenu = false;
function spc(e) {
return ((e.altKey || e.ctrlKey || e.keyCode == 91 || e.keyCode==87) && e.keyCode!=82 && e.keyCode!=116);
}
$(document).hover(function () {
hover = true;
contextMenu = false;
spcKey = false;
}, function () {
hover = false;
}).keydown(function (e) {
if (spc(e) == false) {
hover = true;
spcKey = false;
}
else {
spcKey = true;
}
}).keyup(function (e) {
if (spc(e)) {
spcKey = false;
}
}).contextmenu(function (e) {
contextMenu = true;
}).click(function () {
hover = true;
contextMenu = false;
});
window.addEventListener('focus', function () {
spcKey = false;
});
window.addEventListener('blur', function () {
hover = false;
});
window.onbeforeunload = function (e) {
if ((hover == false || spcKey == true) && contextMenu==false) {
window.setTimeout(goToLoginPage, 100);
$.ajax({
url: "/Account/Logoff",
type: 'post',
data: $("#logoutForm").serialize(),
});
return "Oturumunuz kapatıldı.";
}
return;
};
function goToLoginPage() {
hover = true;
spcKey = false;
contextMenu = false;
location.href = "/Account/Login";
}
It is not possible to kill the session variable, when the machine unexpectly shutdown due to power failure. It is only possible when the user is idle for a long time or it is properly logout.
For browser close you can put below code into your web.config :
<system.web>
<sessionState mode="InProc"></sessionState>
</system.web>
It will destroy your session when browser is closed, but it will not work for tab close.
Use this:
window.onbeforeunload = function () {
if (!validNavigation) {
endSession();
}
}
jsfiddle
Prevent F5, form submit, input click and Close/kill the session when the browser or tab is closed, tested in ie8+ and modern browsers, Enjoy!

Are there caveats to dynamicly creating a form with javascript?

I have to do a cross site POST (with a redirection, so not using a XMLHTTPRequest), and the base platform is ASP.NET. I don't want to POST all of the controls in the ASP.NET FORM to this other site, so I was considering dynamicly creating a new form element using javascript and just posting that.
Has anyone tried this trick? Is there any caveats?
I do this all the time. Works really well. You will have to look through the Request's parameters manually, though, unless you get creative with what you pass as the parameters won't map onto controls on that page. You could also do this in a REST way by passing the parameters in the query string, but I prefer the forms approach to keep my URLs clean. Note that ASP.NET ignores all forms but it's own on postback so I don't bother removing them.
Example from a GridView template field for below code:
<asp:TemplateField HeaderText="Station" SortExpression="Name">
<ItemTemplate>
<a href="javascript:void(0);" onclick='Redirector.redirect_with_id("StationDetail.aspx", <%# Eval("StationID") != null ? Eval("StationID") : "-1" %>);return false;'>
<asp:Label ID="nameLabel" runat="server" Text='<%# Bind("Name") %>' /></a>
</ItemTemplate>
</asp:TemplateField>
Code below -- requires Prototype:
// JScript File
var Redirector = Class.create();
Redirector.prototype = {
initialize: function(url,target) {
this.url = url;
this.parameters = new Hash();
this.target = target;
},
addParameter: function(id,value) {
this.parameters.set(id, value);
},
redirect: function() {
var form = document.createElement('form');
document.body.appendChild(form);
form.action = this.url;
form.method = "post";
if (this.target) {
form.target = this.target;
}
this.parameters.each( function(pair) {
var input = document.createElement('input');
input.id = pair.key;
input.name = pair.key;
input.value = pair.value;
input.style.display = 'none';
form.appendChild(input);
});
form.submit();
}
};
Redirector.redirect_with_id = function(url,id,target) {
var redirector = new Redirector( url, target );
redirector.addParameter( 'ID', id );
redirector.redirect();
};
Redirector.redirect_with_tag = function(url,tag_name,tag,target) {
var redirector = new Redirector( url, target );
redirector.addParameter( tag_name, tag );
redirector.redirect();
};
Redirector.redirect_with_tags = function(url,tag_names_comma_separated,tag_values_comma_separated,target) {
var redirector = new Redirector( url, target );
var tags = tag_names_comma_separated.split( "," );
var values = tag_values_comma_separated.split( ",");
for( var i = 0; i< tags.length; i++ )
{
redirector.addParameter( tags[i], values[i] );
}
redirector.redirect();
};
One caveat: you cannot add a FORM tag to the document using innerHTML. You must add it by creating a new DOM element. You can add fields using innerHTML, but not the form itself.

Resources