Reputation: 740
Here is what I am trying to do (unsuccessfully, I might add) and would appreciate any direction you can give me
From my HTML5 site, I want to upload a file to a cross domain WCF service that is hosted in IIS 7.5.
In addition to uploading the files, I need to send additional parameters to the upload function on the server
Is this possible to do?
Here is what my operationContract looks like:
[OperationContract]
[WebInvoke( Method = "POST",
UriTemplate = "/uploadmodeldata/?id={Id}&customerdatatype={customerdatatype}&data={data}")]
void UploadModelData(string Id, string customerdataType, byte[] data);
Here is what my jquery ajax request
function FileVisits() {
var uid = checkCookie1();
userid = uid.toString().replace(/"/g, '');
var fileData = JSON.stringify({
Id:userid ,customerdatatype:scanupload,
data: $('#fileBinary').val()
});
alert(fileData);
"use strict";
var wcfServiceUrl = "http://xxxxx:1337/Service1.svc/XMLService/";
$.ajax({
cache: false,
url: wcfServiceUrl + "uploadmodeldata/",
data: fileData,
type: "POST",
processData: false,
contentType: "application/json",
timeout: 10000,
dataType: "json",
headers: {
'User-agent': 'Mozilla/5.0 (compatible) Greasemonkey',
'Accept': 'application/atom+xml,application/xml,text/xml',
},
beforeSend: function (xhr) {
$.mobile.showPageLoadingMsg();
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
},
complete: function () {
$.mobile.hidePageLoadingMsg();
},
success: function (data) {
var result = data;
},
error: function (data) {
alert("Error");
}
});
}
if file size is less then 100 kb this error occurred
Method not allowed
but if file is greater then 100 kb this error occurred
413 Request entity to large
How can I upload a file from jquery ajax to cross domain wcf. Thanks
Upvotes: 2
Views: 3872
Reputation: 41
The problem is with the "POST". To solve the problem do the following
Create a Global.asax and add following to enable Ajax cross-domain POST.
public void Application_BeginRequest(object sender, EventArgs e)
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST,OPTIONS");
if ((HttpContext.Current.Request.HttpMethod == "OPTIONS"))
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
HttpContext.Current.Response.End();
}
}
}
Upvotes: 0
Reputation: 71
It took me a lot of work but here is my code(in case someone needs it):
$("#UploadFileBtn").click(function () {
fileName = document.getElementById("filePicker").files[0].name;
fileSize = document.getElementById("filePicker").files[0].size;
fileType = document.getElementById("filePicker").files[0].type;
var file = document.getElementById("filePicker").files[0];
if (file) {
// create reader
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function(e) {
var content = e.target.result;
content = content.substring(content.indexOf('64') + 3);
bhUploadRequest = "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" " +
"xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\" " +
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
"<SOAP-ENV:Header>"+
"<m:FileName xmlns:m=\"http://tempuri.org/\">" + fileName + "</m:FileName>" +
"<m:Length xmlns:m=\"http://tempuri.org/\">" + fileSize + "</m:Length>" +
"</SOAP-ENV:Header>" +
"<SOAP-ENV:Body>" +
"<m:RemoteFileInfo xmlns:m=\"http://tempuri.org/\">" +
"<m:FileByteStream>" + content + "</m:FileByteStream>" +
"</m:RemoteFileInfo>" +
"</SOAP-ENV:Body>" +
"</SOAP-ENV:Envelope>";
$.ajax({
type: "POST",
async: true,
url: wsFtransferUrl,
data: bhUploadRequest,
timeout: 10000,
contentType: "text/xml",
crossDomain: true,
beforeSend: function (xhr) {
xhr.setRequestHeader("SOAPAction", "http://tempuri.org/IFileTransferService/UploadFile");
xhr.setRequestHeader("TICKET", Ticket);
},
success: function (data) {
alert('succes');
$(data).find("UploadFileResponse").each(function () {
alert($(this).find("UploadFileResult").text());
});
},
error: function (xhr, status, error) {
alert('error:' + error);
}
});
};
}
return;
});
and here is my WCF transfer service:
public void UploadFile(RemoteFileInfo request)
{
string filePath = string.Empty;
string guid = Guid.NewGuid().ToString();
int chunkSize = 1024;
byte[] buffer = new byte[chunkSize];
long progress = 0;
filePath = Path.Combine(uploadFolder, request.FileName);
if (File.Exists(filePath))
File.Delete(filePath);
using (FileStream writeStream = new FileStream(filePath, FileMode.CreateNew, FileAccess.Write))
{
do
{
// read bytes from input stream
int bytesRead = request.FileByteStream.Read(buffer, 0, chunkSize);
if (bytesRead == 0)
break;
progress += bytesRead;
// write bytes to output stream
writeStream.Write(buffer, 0, bytesRead);
}
while (true);
}
}
Upvotes: 1
Reputation: 17724
You are getting the Method not allowed
cause you are trying to call a service on another domain. This violates the Same origin policy. This is a security limitation. Most older browsers will deny such requests.
You will need to setup Cross-Origin Resource Sharing if you want to access a different domain the webservice in javascript.
Cross-origin resource sharing (CORS) is a mechanism that allows a web page to make XMLHttpRequests to another domain. Such "cross-domain" requests would otherwise be forbidden by web browsers, per the same origin security policy. CORS defines a way in which the browser and the server can interact to determine whether or not to allow the cross-origin request
If you have access to the webservice code, you can enable CORS requests at the server.
Enable cors is a good resource. Here is some explaination on cors
On IIS 7, you need to set a few custom headers in your web.config.
<system.webserver>
<httpprotocol>
<customheaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
</customheaders>
</httpprotocol>
</system.webserver>
As for the 413 error, that is related to the max file size you allow on your binding
<bindings>
<webHttpBinding>
<binding maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" />
</webHttpBinding>
</bindings>
Upvotes: 0