I've been tasked with adding file uploading to a web based application that is using Classic ASP. Unfortunately I am not allowed to use any other technology, and was told it is what it is so suggesting anything but ASP won't help in this instance.
A form POST with $.ajax is called upon submitting a simple form with some input fields and one file field, that points to a Classic ASP file that handles recordset inserts via request.form. I have added contentType: false in hopes to enctype="multipart/form-data" but been getting the following error:
Object doesn't support this property or method: 'Binary' because I changed the request.form in the insert posted below, but it won't work with request.form either. With request.form I get this error: [Microsoft][ODBC Microsoft Access Driver] Data type mismatch in criteria expression.
$.ajax({
type : 'POST',
url : 'manipulateData.asp?sqlType='+newdbTable+'&sqlRecordId='+recordId+'',
data : formData,
encode : true,
contentType : false,
success: function(data) {
// do something with data
},
error: function(data) {
console.log("ERROR" + JSON.stringify(data));
}
})
Inside the Classic ASP file manipulateData.asp is a connection string that is called inside a case statement and beneath that is more Classic ASP file for a single file upload shown below.
I was trying to implement Shadow Wizards solution but wanted to try this first as I was trying to keep things simple.
cn.execute("INSERT INTO CONTENT (contentTitle, contentContent, contentDate, categoryId, userLevel) VALUES ('" & Request.Form("contentTitle") & "','" & Request.Form("contentContent") & "','" & Request.Form("contentDate") & "','" & Request.Form("categoryTitle") & "','" & Request.Form("userLevel") & "')")
' TEST FILE UPLOAD
Dim objUpload
Dim strFile, strPath
' Instantiate Upload Class '
Set objUpload = New clsUpload
strFile = objUpload.Fields("file").FileName
strPath = server.mappath("/files") & "/" & strFile
' Save the binary data to the file system '
objUpload("file").SaveAs strPath
Set objUpload = Nothing
Is what I am attempting to do even possible as I've ready that request.form and request.binary can't be used at the same time? If not then what would be some alternatives?
I do not like this answer for the record but calling another function on success to then get the path of the file then passing that in another ajax call to a Classic ASP file to upload worked.
$.ajax({
type : 'POST',
url : 'manipulateData.asp?sqlType='+newdbTable+'&sqlRecordId='+recordId+'',
data : formData,
encode : true,
contentType : false,
success: function(data) {
// file upload function
uploadFile()
},
error: function(data) {
console.log("ERROR" + JSON.stringify(data));
}
})
And the upload ajax
function uploadFile(formData) {
var data = new FormData();
$.each($('#file1')[0].files, function(i, file) {
data.append('file-'+i, file);
});
$.ajax({
type : 'POST',
url : 'uploadFileTest.asp',
data : data,
async: true,
cache: false,
contentType: false,
processData: false,
success: function(data) {
// do something else here or not
},
error: function(data) {
// SHOW ERROR
console.log("ERROR" + JSON.stringify(data));
}
})
}
I would still very much like to know if I could eliminate the second function call or if this is the nature of how Classic ASP handles FORM and BINARY posts, that they must be separate?
Related
We have a custom API which is running in a pod on Kubernetes server, with Graphileon also running in a pod on the same server.
The custom API takes spreadsheet as form-data, uploads it and processes it on to Neo4j database (also running in a pod on the same server).
All our 3 pods (custom API, Graphileon and Neo4j) are running in same namespace.
Our requirement is that we want to create a "HTMLView" on Graphileon which can open a small dialog box where we can upload the spreadsheet and hit our API on the backend.
Graphileon team advised us to use the proxy feature, but that seems to be not working in this case. Here is what we did:
LOCAL TESTING
We started neo4j, graphileon and custom API on local. We created the HTML view and used ajax call to call our API:
function createSchema(schemaType,formData)
{
var schemaUrl = "http://localhost:8080/create-schema/"+schemaType;
$.ajax({
url: schemaUrl,
type: "POST",
data: formData,
mimetype: "multipart/form-data",
cache: false,
processData: false,
success: function(data,status,xhr){
$("#result").html("");
$("#reset").show();
$("#schemaFileUpload").hide();
$("#result").append("<h4>Create "+ schemaType +" Schema Success <span style=\'color:green\' >"+xhr.responseText + " with Status code "+xhr.status+"<span></h4> </br>" );
$("#verticalSchemaFile").attr("disabled","disabled");
$("#customerSchemaFile").attr("disabled","disabled");
},
error: function(xhr,status,error){
$("#result").html("");
$("#reset").show();
$("#schemaFileUpload").hide();
$("#result").append( schemaType +" create Schema Failed. <span style=\'color:red\' >"+xhr.responseText + " with Status code "+xhr.status+"<span> </br>" );
$("#verticalSchemaFile").attr("disabled","disabled");
$("#customerSchemaFile").attr("disabled","disabled");
}
});
}
This works!
SERVER TESTING
When I put the same code over the server, its gives error - couldn't reach URL. So I did the proxy settings and tried the proxy way:
function createSchema(schemaType,formData)
{
var schemaUrl = "http://customapi:8080/create-schema/"+schemaType;
$.ajax({
url: "/proxy",
type: "POST",
data: "{\"url\": \"" + schemaUrl + "\", \"method\": \"POST\", \"data\": \"" + formData + "\"}",
mimetype: "multipart/form-data",
cache: false,
processData: false,
success: function(data,status,xhr){
$("#result").html("");
$("#reset").show();
$("#schemaFileUpload").hide();
$("#result").append("<h4>Create "+ schemaType +" Schema Success <span style=\'color:green\' >"+xhr.responseText + " with Status code "+xhr.status+"<span></h4> </br>" );
$("#verticalSchemaFile").attr("disabled","disabled");
$("#customerSchemaFile").attr("disabled","disabled");
},
error: function(xhr,status,error){
$("#result").html("");
$("#reset").show();
$("#schemaFileUpload").hide();
$("#result").append( schemaType +" create Schema Failed. <span style=\'color:red\' >"+xhr.responseText + " with Status code "+xhr.status+"<span> </br>" );
$("#verticalSchemaFile").attr("disabled","disabled");
$("#customerSchemaFile").attr("disabled","disabled");
}
});
}
This gives error saying "No JSON request parameters specified"
Appreciate any help here. Thanks
Disclamer: i am a lead developer at Graphileon.
The /proxy endpoint of Graphileon is more of a Remote Procedure Call. It calls request(...) with the parameters received as JSON in the request body (GET or POST data).
It is not designed to handle file uploads.
The only way to simulate a file upload in the target API is to send the file data in the formData parameter. The problem is that with JSON you can only send text files. So no binary data.
$.ajax({
url: "/proxy",
type: "POST",
data: JSON.stringify({
url: schemaUrl,
method: 'POST',
formData: {
file: {
value: '<file-contents>',
options: {
filename: 'my-file.txt',
contentType: 'text/plain'
}
}
}
})
})
You can read the selected file contents with the Javascript's FileReader API.
I am currently working on an ASP.NET MVC site and I am having trouble with ajax posts in my release build. The site has two database connections, one to a "dummy" server that allows me to test code without affecting the live server. So, I had to configure the site to point to the live server for the release configuration, and the dummy server for the debug configuration.
Everything other than the database connection is the same, but for some reason my ajax call works fine on the debug build but throws an error on the release build. I get an ERROR THROWN: Not found alert on the ajax failure, but it only fails in the release build.
My call to the controller method looks like this:
$.ajax({
type: "GET",
url: "#Url.Action("ReleasePlotFieldName", "TestRecord")" + '?fieldName=' + x + '&fileName=' + filename,
contentType: "application/json; charset=utf-8",
data: {},
dataType: "json",
success: function (data) {
alert("success");
for (var key in data) {
let b = {
name: data[key][0],
value: data[key][1],
line: data[key][2],
arc: data[key][3]
};
chartData.push(b);
}
PlotData();
//the parameter data contains the array returned from the json PlotFieldName function
},
error: function (xhr, textStatus, errorThrown) {
alert('STATUS: ' + textStatus + '\nERROR THROWN: ' + errorThrown);
}
and the controller method looks like this:
[HttpPost]
public JsonResult ReleasePlotFieldName(string fieldName, string fileName)
{
var spiData = (DataDecoder)Session["dataDecode"];
var selectedItem = fieldName;
spiData.DecodeData(selectedItem);
List<float[]> toPlot = spiData.returnPlotVector();
return new JsonResult()
{
Data = toPlot,
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
MaxJsonLength = int.MaxValue // Use this value to set your maximum size for all of your Requests
};
}
I have absolutely no clue why the release build is not executing as expected (as the debug build is doing). I welcome any and all suggestions.
Here is the network tab of the browser when the call is made
Your controller action is decorated with a [HttpPost] attribute but your jquery .ajax() request is a GET. Change one or the other depending on your use case (looks like GET could be more appropriate).
From client side A, I want to create a file on the fly by javascript and send it to a Django server B via Ajax for further processing.
The javascript code in A is like below. I use blob to create a file without a real uploaded one and send it via Ajax.
console.log("start sending binary data...");
var form = new FormData();
var blob = new Blob([bytesArray], {type: 'example/binary'});
form.append('file_name', blob, 'test.bin');
$.ajax({
url: THIRD_SERVER + 'test_binary',
type: 'POST',
data: form,
processData: false,
success: function(data){
console.log('test_binary ' + JSON.stringify(data));
}
});
However, on the Django server, what I got is like this (when i print request.POST), hence when i used Django FileUpload, it returned an exception.
<QueryDict: {u' name': [u'"file_name"'], u'------WebKitFormBoundarybCp3z7mAduz8BBDq\r\nContent-Disposition: form-data': [u''], u' filename': [u'"test.bin"\r\nContent-Type: example/binary\r\n\r\n\ufffd\ufffd\ufffd\x01\x05\x06\r\n------WebKitFormBoundarybCp3z7mAduz8BBDq--\r\n']}>
So I guess the above javascript doesn't do the right thing to send file to a Django server. Is there any proper way that I can use the FileUpload to handle?
Thanks,
You have to tell $.ajax not to set a content type otherwise it will be set incorrectly
$.ajax({
url: THIRD_SERVER + 'test_binary',
type: 'POST',
data: form,
processData: false,
contentType: false,
success: function(data){
console.log('test_binary ' + JSON.stringify(data));
}
});
I'm trying to do a simple odata query and the call is successful, but the results are always undefined. I've thrown the URL into the description, copy and pasted it, and it works just fine. I've tested dozens of different ways to see what the object is, and the results are undefined. What am I missing??
UPDATE: As mentioned below, part of the problem was referencing data.d.results. When I referenced data.d.results[0], I actually got the error message "Unable to get property '0' of undefined or null reference." I wanted to add that here because I found almost NO help when searching for that error message.
The final answer was a combination of:
data.d for only one result
correct casing for system fields; "resProd.Description" as opposed to "resProd.description."
Back to orig Question:
Below is the code I'm using:
function setOPDefaults() {
// Create lookup
var lookupItem = new Array();
lookupItem = Xrm.Page.getAttribute("productid").getValue();
if (lookupItem != null)
{
var guid = lookupItem[0].id;
}
var crmOrg = window.location.pathname.split('/')[1];
var serverUrl = window.location.protocol + "//" + window.location.host + (crmOrg == 'userdefined' ? '' : '/' + crmOrg);
var ODATA_ENDPOINT = "/XRMServices/2011/OrganizationData.svc";
var ODATA_PREP = serverUrl + ODATA_ENDPOINT;
$.ajax({
type: "GET",
contentType: "application/json; charset=utf-8",
datatype: "json",
// Tried both of the following URLS (obviously not at the same time)
url: ODATA_PREP + "/ProductSet(guid'" + guid + "')",
url: "http://crm/<<orgname>>/XRMServices/2011/OrganizationData.svc/ProductSet(guid'67BA90A3-39D8-E211-8D1E-0050569A6113')",
beforeSend: function (XMLHttpRequest) {
XMLHttpRequest.setRequestHeader("Accept", "application/json");
},
success: function (data, textStatus, XmlHttpRequest) {
var resProd = data.d.results;
alert(resProd.length); // This is undefined
// Below is where I load the URL into description just for testing.
// When I copy and paste this URL into the browser, it pulls up results with correct data
Xrm.Page.getAttribute("description").setValue(ODATA_PREP + "/ProductSet(guid'" + guid + "')");
},
error: function (XmlHttpRequest, textStatus, errorThrown) {
alert("Ajax call failed: " + textStatus + " - " + errorThrown + " || " + XmlHttpRequest.responseText);
}
});
}
You're acessing just one record, so try put something like that:
data.d
data.d.results is used for multiple results. Another thing you can do to validate the results is put your url directly in browser.
In such cases, I use Fiddler. You can use it to debug your http/https trafic.
Or. If you have crm 2011 RU 12, you can use built-in Chrome debugger. Press F12. In console tab - right click -> Log XMLHttpRequest
The following code returns a blank response no matter whether or not the Function exists, or even the Web Service file entirely:
$.ajax({
url: "/ws.asmx/HelloWorld"
, type: "POST"
, contentType: 'application/json; charset=utf-8'
, data: '{ FileName: "' + filename + '" }'
, dataType: 'json'
, success: function (data) {
}
});
Why is this?
Also, might be worth noting, $.load() works fine!
Your error is that you try to construct JSON data manually and do this in the wrong way:
'{ FileName: "' + filename + '" }'
You should fix the code at least to the following
'{ "FileName": "' + filename + '" }'
because correspond to the JSON specification the property names must be also double quoted.
Next problem can you has if the filename has some special characters. For example, in case of
var filename = '"C:\\Program Files"'; // the '\' must be escaped in the string literal
you should has as the data the corresponding JSON string
'{ "FileName": "\\"C:\\\\Program Files\\"" }'
as the corresponding JSON data because of '\' and '"' must be escaped. It looks dificult. So I stricly recommend you to construct JSON strings with respect of JSON.stringify function from the json2.js. Then the code will be
$.ajax({
type: "POST",
url: "ws.asmx/HelloWorld",
data: JSON.stringify({ FileName: filename }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
alert(data.d);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("Error Occured!" + " | " + XMLHttpRequest.responseText +
" | " + textStatus + " | " + errorThrown);
}
});
which is simple and clear enough. The next advantage of the usage JSON.stringify is that the most modern web browsers has native support of the function and the function work very quickly.
By the way in case of the usage of JSON.stringify you can easy call web service methd having very complex data structures (classes) as the parameters and not only strings.
UPDATED: One more remrk to reduce possible misunderstanding. It you later deceide to use HTTP GET instead of HTTP POST to call the web method you will have to change the data parameter from
JSON.stringify({ FileName: filename })
to
{ FileName: JSON.stringify(filename) }
UPDATED 2: You can download this Visual Studio 2010 project which I used to test all before I posted my answer. I included as "Web-3.5.config" the web.config for .NET 3.5. All different commented data values included in the default.htm work. If you want make tests with HTTP GET you should uncomment the section in web.config which allows HttpGet and use ScriptMethod having UseHttpGet = true. All the lines are included in the demo as comments.
just to try use:
$.getJSON("/ws.asmx/HelloWorld", function(data){
alert(data);
});
Check if you get the data back.
Use AJAX-Enabled Web Service
Make sure you have loaded the jquery.js file properly.
Does the service return a value? If not, it will just POST and not give you back anything, because there is no data to see...
If you want to watch for errors, you can add an error callback
$.ajax({
url: "/ws.asmx/HelloWorld"
, type: "POST"
, contentType: 'application/json; charset=utf-8'
, data: '{ FileName: "' + filename + '" }'
, dataType: 'json'
, success: function (data) {
}
, error: function (a, b, c) {
}
});
From jQuery:
error(jqXHR, textStatus, errorThrown)Function
A function to be called if the request fails. The function receives
three arguments: The jqXHR (in jQuery
1.4.x, XMLHttpRequest) object, a string describing the type of error
that occurred and an optional
exception object, if one occurred.
Possible values for the second
argument (besides null) are "timeout",
"error", "abort", and "parsererror".
This is an Ajax Event. As of jQuery
1.5, the error setting can accept an array of functions. Each function will
be called in turn. Note: This handler
is not called for cross-domain script
and JSONP requests.
I read somewhere that the contentType header for POST must be:
xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
and I use it blindly: it's always worked.
-- pete