Sharepoint 2010 Custom WCF service returns 400 - "bad request" with OpenXML - wcf

I'm developing a custom Sharepoint 2010 service to work with Excel files. I'm using VS2015 on my local workstation.
The service works and debugs just fine getting the SPFile, reading it's properties and converting it into a stream. However, as soon as I include the code to create the SpreadsheetDocument using SpreadsheetDocument.Open() it doesn't even debug anymore but simply retuns a response of 400 "Bad Request".
Service Code
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using Microsoft.SharePoint;
using System;
using System.IO;
using System.ServiceModel.Activation;
namespace Lifeco.Corp.Sharepoint
{
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class ExcelItemToSapService : IExcelItemToSapService
{
public ServiceResult SubmitSpreadsheet(string documentUrl)
{
// Ensure we have the neccessary information.
if (string.IsNullOrEmpty(documentUrl))
{
return new ServiceResult() { Status = "error", Message = "List item url is required as the 'documentUrl' parameter." };
}
SPFile doc = SPContext.Current.Web.GetFile(documentUrl);
if (doc == null || !doc.Exists)
{
return new ServiceResult() { Status = "error", Message = string.Format("Document item at '{0}' was not found.", documentUrl) };
}
using (Stream dataStream = doc.OpenBinaryStream())
{
// As is this works. Uncommenting the following 'using' block and I receive 400 - Bad Request without even getting to step into the code and debug.
//using (SpreadsheetDocument document = SpreadsheetDocument.Open(dataStream, false))
//{
// // work with spreadsheet...
//}
}
ServiceResult response = new ServiceResult() { Status = "success" };
response.Message = string.Format("Title: {0} | Version: {1} | Modified By: {2}", doc.Title, doc.UIVersionLabel, doc.ModifiedBy.Name);
return response;
}
}
}
.svc
# ServiceHost
Language="C#"
Debug="true"
Service="Lifeco.Corp.Sharepoint.ExcelItemToSapService, $SharePoint.Project.AssemblyFullName$"
CodeBehind="ExcelItemToSapService.svc.cs"
Factory="Microsoft.SharePoint.Client.Services.MultipleBaseAddressWebServiceHostFactory, Microsoft.SharePoint.Client.ServerRuntime, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
The error is received the same whether calling the service directly in the browser or with the following jquery on a Sharepoint page
$.ajax({
type: "GET",
url: webServerRelativeUrl + '/_vti_bin/ExcelItemToSapService/ExcelItemToSapService.svc/SubmitSpreadsheet',
contentType: "application/json; charset=utf-8",
data: { "documentUrl": "http://s040997/Corporate/Insurance Risk Sample 2.xlsm" },
dataType: 'json',
success: function (data) {
//alert('Success\n' + JSON.stringify(data));
$resultEl.html('<pre>' + JSON.stringify(data) + '</pre>');
},
error: function (jqXHR, status, error) {
$resultEl.html('');
alert('Error\n' + jqXHR.responseText + '\nstatus: ' + status);
//alert('Error\n' + jqXHR.responseText + '\nheader: ' + jqXHR.getResponseHeader() + '\nerror: ' + error);
}
});
Any thoughts?
Thanks

Figured out the issue.
I needed to add the DocumentFormat.OpenXml.dll as an Additional Assembly to my Sharepoint package.
Open /Package/Package.package from Solution Explorer
Advanced tab
Add -> Add Existing assembly
Entered the source path to the DocumentFormat.OpenXml.dll
Selected Deployment Target = GlobalAssemblyCache
OK
And the next test succeeded.

Related

How to call Azure function from Kotlin

I currently have deployed an Azure function used to get an AD token.
Function:
https://getadtokennet.azurewebsites.net/api/getadtokennet
Request header:
x-functions-key = {key}
How can I call this function from my Kotlin app?
This is the way I call it from Javascript
function getTokenAzure(onsuccess, onerror) {
var tokenUrl = 'https://getadtokennet.azurewebsites.net/api/getadtokennet';
$.ajax(tokenUrl, {
method: 'GET',
beforeSend: function (request) {
request.setRequestHeader("x-functions-key", "function key");
},
success: function (data) {
onsuccess(data);
console.log('token: ' + data.token);
},
error: function (xhr, status, error) {
var failureMessage = "GetToken error: " + status + " - " + error;
onerror(failureMessage);
console.log(failureMessage);
}
});
}
In IntelliJ IDEA, select Create New Project.
In the New Project window, select Maven from the left pane.
Select the Create from archetype check box, and then select Add Archetype for the azure-functions-kotlin-archetype.
In the Add Archetype window, complete the fields as follows:
GroupId: com.microsoft.azure
ArtifactId: azure-functions-kotlin-archetype
Version: Use the latest version from the central repository
Select OK, and then select Next.
Enter your details for current project, and select Finish.
For complete information refer to the below links which has same information.
Kotlin Function and Running Kotlin in Azure Functions
I found the way, here it is.
fun getToken(): String {
val tokenUrl = URL("https://getadtokennet.azurewebsites.net/api/getadtokennet")
val connection = tokenUrl.openConnection() as HttpURLConnection
connection.requestMethod = "POST"
connection.setRequestProperty("x-functions-key", "function key")
connection.doOutput = true
val responseCode = connection.responseCode
if (responseCode == HTTP_OK) {
val readerIn = BufferedReader(InputStreamReader(connection.inputStream))
var inputLine = readerIn.readLine()
val response = StringBuffer()
do {
response.append(inputLine)
} while (inputLine.length < 0)
readerIn.close()
// Return token
return response.toString()
} else {
val responseError = Error(code = "BadRequest", message = "There was an error getting the token.")
throw IOException(responseError.toString())
}
}

Intervention image 405 method not found outside laravel

I used the Intervention image in my api. Then, I am trying to access it from my web, which is also Laravel but in different project. (I separated the web from the api due to some testing purposes for the api). But the image was successfully resized and saved to my public folder. But in my api there's an error then, when I comment the Image::make(), the error is gone. Why is that?
EDIT: Code from my api where I used Image::make()
$plant_image = $_FILES['image']['tmp_name'];
move_uploaded_file($plant_image, public_path()."\gallery\images\\".$_FILES['image']['name']);
$file_path = public_path() . "\gallery\images\\" . $_FILES['image']['name'];
$img = Image::make($file_path)->resize(216, 145);
$img->save();
Here is the code for the web
$(document).ready(function() {
$("form#addplant").submit(function() {
var form_data = new FormData($("#addplant")[0]);
$.ajax({
url: 'http://127.0.0.1/identificare_api/public/api/plants',
data: form_data,
type: "POST",
processData : false,
contentType: false,
success: function( json ) {
//console.log(json);
if (json.indexOf("error") > -1) {
var jsonparse = JSON.parse(json);
if(jsonparse.hasOwnProperty('error')){
location.reload(true);
alert("Code: " + jsonparse.error.code + "\n" + "Message: " + jsonparse.error.message);
}else{
location.reload(true);
alert("Please fill in empty fields");
}
}else{
window.location.href = "/home/"+ user_token;
alert("This item is currently under review! Please wait for admin's confirmation. Thank you!");
}
},
error: function(){
alert("Something's wrong with your api. Come on fix it!");
}
});
});
});

Uploaded image on parse.com gives 403 error

I am trying to upload image to parse.com using REST API, and associating to an object as shown in docs
I am getting the fileUrl from phonegap / appgyver-supersonic camera api.
The Image is uploaded successfully and also associated successfully to the "receipt" object but accessing the url gives 403 error.
How do I access the URL and view the uploaded image, I get a white page (with broken image icon) and 403 error.
File :
http://files.parsetfss.com/68087456-8a5a-403a-820f-13912d2c0911/tfss-5d0edbdb-730b-4cd6-a44f-f0ce1e2ab120-pic.jpg
My receipt class has public write/read access.
Here is my code :
$scope.send = function(fileURL, mimeType){
function win(r) {
$scope.textvar = r;
var response = JSON.parse(r.response);
console.log("Code = " + r.responseCode);
console.log("Response = " + r.response);
console.log("Sent = " + r.bytesSent);
var req = {
method: 'POST',
url: 'https://api.parse.com/1/classes/receipt',
headers: {
'X-Parse-Application-Id':'XXXXXXXXXXXXX',
'X-Parse-REST-API-Key':'XXXXXXXXXXXXXXXX',
"Content-Type": "application/json"
},
data: {"name": "user_receipts",
"images": {
"name": response.name,
"__type" : "File"
}
}
}
$http(req).success(function(data, status, headers, config) {
// this callback will be called asynchronously
// when the response is available
console.log("image association success ");
console.log(data);
console.log(headers);
console.log(status);
console.log(config);
}).
error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
}
function fail(error) {
console.log("An error has occurred: Code = " + error.code);
console.log("upload error source " + error.source);
console.log("upload error target " + error.target);
console.log("upload error http-code " + error.http_status);
}
var uri = encodeURI("https://api.parse.com/1/files/pic.jpg");
var options = new FileUploadOptions();
options.fileKey="data-binary";
options.fileName=fileURL.substr(fileURL.lastIndexOf('/')+1);
options.mimeType=mimeType;
var headers = {"X-Parse-Application-Id": "XXXXXXXXXXXXXXXXX",
"X-Parse-REST-API-Key":"XXXXXXXXXXXXXXXX",
"Content-Type":"image/jpeg"};
options.headers = headers;
var ft = new FileTransfer();
ft.onprogress = function(progressEvent) {
if (progressEvent.lengthComputable) {
console.log("length : "+progressEvent.loaded/progressEvent.total);
} else {
console.log("loaded : "+progressEvent.loaded);
}
};
ft.upload(fileURL, uri, win, fail, options);
};
I have wasted 5 days on this already, Please Help.
I am no expert in either appgyver / phonegap or parse.com

Problems with download link in phonegap android pdf

Someone know how to download an file (pdf) using phonegap for android
I already looked a lot of tutorial but any of them work for me.
THank you.
You will need to make use of the FileTransfer object here: http://docs.phonegap.com/en/3.3.0/cordova_file_file.md.html#FileTransfer.
With this, you will need to call the download method - passing in the file URI, destination and success/error callbacks.
I.e., if I want to download a PDF, you could do so as follows:
var win = function(r) {
console.log("Should not be called.");
}
var fail = function(error) {
// error.code == FileTransferError.ABORT_ERR
alert("An error has occurred: Code = " + error.code);
console.log("upload error source " + error.source);
console.log("upload error target " + error.target);
}
var ft = new FileTransfer();
ft.download(
'http://www.mydomain.com/mypdfdoc.pdf',
myURI, // you can obtain this via a window.requestFileSystem(...)
function (fileEntry) {
// do something with fileEntry
},
function (error) {
// handle error appropriately
});

Corrupted file when uploading file to server using ajax and WCF

I'm trying to implement image upload using jquery, ajax and wcf on server side.
Operation contract:
[WebInvoke(UriTemplate = "/createnewsfeedpost?fileName={fileName}", Method = "POST", ResponseFormat = WebMessageFormat.Json)]
[OperationContract]
void CreateNewsfeedPost(Stream imageContent, string fileName);
Operation implementation:
public void CreateNewsfeedPost(Stream imageContent, string fileName)
{
byte[] buffer = new byte[32768];
using (var ms = new FileStream(#"C:/Temp/test.png", FileMode.CreateNew))
{
int bytesRead, totalBytesRead = 0;
do
{
bytesRead = imageContent.Read(buffer, 0, buffer.Length);
totalBytesRead += bytesRead;
ms.Write(buffer, 0, bytesRead);
} while (bytesRead > 0);
}
}
Client side code:
<a id="createNewsFeedPostButton" href="javascript:;">Share</a>
<input type="file" id="newsFeedImage" />
Javascript:
$(document).ready(function () {
$("#createNewsFeedPostButton").click(function () {
createNewsFeedPost();
});
});
function createNewsFeedPost() {
var fd = new FormData();
fd.append('file', $('#newsFeedImage')[0].files[0]);
$.ajax({
url:/createnewsfeedpost + "?fileName=test.png",
data: fd,
processData: false,
contentType: false,
type: 'POST',
success: function (data) {
alert('sas');
},
error: function (jqXHR, textStatus, errorThrown) {
alert(textStatus + ' / ' + errorThrown);
}
});
}
I am able to get populated Stream object in service implementation but the problem is that it is somewhat corrupted. If i open saved file using notepad i can see some strange header and footer in it.
Header:
-----------------------------7de17128101f8
Content-Disposition: form-data; name="file"; filename="C:\icon.png"
Content-Type: image/png
Footer:
-----------------------------7de17128101f8--
Is there any way to get rid of this footer and header?
Thanks to Ray Nicholus for the solution. I needed to parse message body as multipart data to be able to access image content. I took multipart parser from here.
Updated server side code:
var parser = new MultipartParser(imageContent);
if (!parser.Success)
throw new ApplicationException("Error while parsing image file");
using (var ms = new FileStream(#"C:/Temp/test.png", FileMode.CreateNew))
{
ms.Write(parser.FileContents, 0, parser.FileContents.Length);
}