webservice CopyIntoItems is not working to upload file to sharepoint - c#

The following piece of C# is always failing with
1
Unknown
Object reference not set to an instance of an object
Anybody some idea what i am missing?
try
{
//Copy WebService Settings
String strUserName = "abc";
String strPassword = "abc";
String strDomain = "SVR03";
String FileName = "Filename.xls";
WebReference.Copy copyService = new WebReference.Copy();
copyService.Url = "http://192.168.11.253/_vti_bin/copy.asmx";
copyService.Credentials = new NetworkCredential
(strUserName,
strPassword,
strDomain);
// Filestream of attachment
FileStream MyFile = new FileStream(#"C:\temp\28200.xls", FileMode.Open, FileAccess.Read);
// Read the attachment in to a variable
byte[] Contents = new byte[MyFile.Length];
MyFile.Read(Contents, 0, (int)MyFile.Length);
MyFile.Close();
//Change file name if not exist then create new one
String[] destinationUrl = { "http://192.168.11.253/Shared Documents/28200.xls" };
// Setup some SharePoint metadata fields
WebReference.FieldInformation fieldInfo = new WebReference.FieldInformation();
WebReference.FieldInformation[] ListFields = { fieldInfo };
//Copy the document from Local to SharePoint
WebReference.CopyResult[] result;
uint NewListId = copyService.CopyIntoItems
(FileName,
destinationUrl,
ListFields, Contents, out result);
if (result.Length < 1)
Console.WriteLine("Unable to create a document library item");
else
{
Console.WriteLine( result.Length );
Console.WriteLine( result[0].ErrorCode );
Console.WriteLine( result[0].ErrorMessage );
Console.WriteLine( result[0].DestinationUrl);
}
}
catch (Exception ex)
{
Console.WriteLine("Exception: {0}", ex.Message);
}

If you will use instead the IP address (http://192.168.11.253) the server name (http://...) this web service works well.

Without understanding more about your specific error, I too would be grasping at straws. It looks like your destinationUrl is an incomplete path. You typically need to specify the entire URL to a site or site collection. So, I would expect your destinationUrl to be something like http://192.168.11.253/[SiteName]/Shared Documents/28200.xls instead of http://192.168.11.253/Shared Documents/28200.xls".

Related

Windows Service Filestream giving System.IO.IOException: The process cannot access the file "filename" because it is being used by another process

I've got a windows service that I have to modify. Current code is this:
public IRecord2 GetRecord(string name)
{
string path = Path.Combine(this.DirectoryPath, name);
if (!File.Exists(path))
return null;
byte[] contents;
lock (locker) {
using(FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, bufferSize:4096, useAsync:true)) //WHERE THE PROBLEM IS OCCURRING
{
using (BinaryReader br = new BinaryReader(fs))
{
contents = br.ReadBytes((int)fs.Length);
br.Close(); //unnecessary but threw it in just to be sure
fs.Close(); //unnecessary but threw it in just to be sure
}
}
}
return new Record2()
{
Name = name,
Contents = contents
};
}
Code that calls the function:
public void Process(string pickupFileName)
{
string uniqueId = DateTime.Now.ToString("(yyyy-MM-dd_HH-mm-ss)");
string exportFileName = Path.GetFileNameWithoutExtension(pickupFileName) + "_" + uniqueId + ".csv";
string archiveFileName = Path.GetFileNameWithoutExtension(pickupFileName) + "_" + uniqueId + Path.GetExtension(pickupFileName);
string unprocessedFileName = Path.GetFileNameWithoutExtension(pickupFileName) + "_" + uniqueId + Path.GetExtension(pickupFileName);
try
{
_logger.LogInfo(String.Format("Processing lockbox file '{0}'", pickupFileName));
IRecord2 record = _pickup.GetRecord(pickupFileName);
if (record == null)
return;
_archive.AddOrUpdate(new Record2() { Name = archiveFileName, Contents = record.Contents });
string pickupFileContents = UTF8Encoding.UTF8.GetString(record.Contents);
IBai2Document document = Bai2Document.CreateFromString(pickupFileContents);
StringBuilder sb = Export(document);
_export.AddOrUpdate(new Record2() { Name = exportFileName, Contents = Encoding.ASCII.GetBytes(sb.ToString()) });
_pickup.Delete(pickupFileName);
}
catch(Exception ex)
{
throw ex;
}
}
Function that calls Process:
public void Process()
{
foreach (ConfigFolderPath configFolderPath in _configSettings.ConfigFolderPaths)
{
IRecordRepository pickup = new FileRepository(configFolderPath.PickupFolderPath);
IRecordRepository export = new FileRepository(configFolderPath.ExportFolderPath);
IRecordRepository archive = new FileRepository(configFolderPath.ArchiveFolderPath);
IRecordRepository unprocessed = new FileRepository(configFolderPath.UnprocessedFolderPath);
Converter converter = new Converter(Logger,pickup, export, archive, unprocessed);
foreach (string fileName in pickup.GetNames())
{
if (_configSettings.SupportedFileExtensions.Count > 0 && !_configSettings.SupportedFileExtensions.Any(extension => extension.ToLower() == Path.GetExtension(fileName).ToLower()))
continue;
Action action = () => converter.Process(fileName);
_queue.TryEnqueue(action, new WorkTicket() { Description = String.Format("Processing '{0}'", fileName), SequentialExecutionGroup = fileName });
}
}
}
When 1 file is sent to the service, it processes and reads the file correctly. However, if two files are sent (difference of 3 minutes), the first file will process correctly, but the second will give me "System.IO.IOException: The process cannot access the file "filename" because it is being used by another process.
Is the solution to use a mutex as per https://stackoverflow.com/a/29941548/4263285 or is there a better solution to solve this?
Edit: More context:
Service is constantly running - as soon as files are dropped into a folder, it begins the process.
get the file data (function up above)
take the data, transform it, and put it into a different file
Delete the original file from the one up above
rinse and repeat if more files
if one file is placed in the folder, it works correctly.
if two files are placed in the folder, it breaks on the second file
if service is stopped and restarted, it works again
In your code add ".Close()" here, at the end of the line :
using(FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, bufferSize:4096, useAsync:true).Close())

Replacing Files in Google Drive UpdateMediaUpload

I have no idea, why the content of the file will not be updated. Has anybody a hint?
The DriveFile.Id is valid. The source File is existing readable. Creating and deleting of files works fine. But not the Update.
I have read the migration from v2 to v3 uses generell the Http-PATCH Method for Update. Is this the answer.
I don't want to delete the file and create a new one.
public long DriveUpdateFile(string fileID, string filename, string description, string parent, string mimeType)
{
int lError = (int)Win32ErrorCode.ERROR_SUCCESS;
if (System.IO.File.Exists(filename))
{
FilesResource.GetRequest get = m_Drive.Files.Get(fileID);
File body = get.Execute();
if(!string.IsNullOrEmpty(description))
body.Description = description;
if (!string.IsNullOrEmpty(mimeType))
body.MimeType = mimeType;
// v3 Sematics
if (!string.IsNullOrEmpty(parent))
{
body.Parents = new List<string>();
body.Parents.Add(parent);
}
try
{
// File's content.
using (System.IO.FileStream sr = System.IO.File.OpenRead(filename))
{
FilesResource.UpdateMediaUpload request = m_Drive.Files.Update(body, body.Id, sr, body.MimeType);
request.Upload();
}
}
catch (Exception e)
{
Console.WriteLine("An error occurred: " + e.Message);
lError = e.HResult;
}
}
else
{
Console.WriteLine("File does not exist: " + filename);
lError = (int)Win32ErrorCode.ERROR_FILE_NOT_FOUND;
}
return (lError);
}
Use scopes as below,
string[] scopes = new string[] {
DriveService.Scope.Drive,
DriveService.Scope.DriveFile,
DriveService.Scope.DriveMetadata,
DriveService.Scope.DriveAppdata,
DriveService.Scope.DriveScripts
};//DriveService.Scope.DriveReadonly
and I check above code. the problem is ParentFolderId. please remove this line
body.Parents = new List<string>();
body.Parents.Add(parent);
direct assignment is not allowed in this scope. it should mention with request object like : request.Parent ... bla bla
and try.

"Process cannot access the file because it is being used by another process"

I need to upload a CSV file to an ASP.NET application, on an Azure server. Although it works fine on my local machine, when uploading it to the server the following error is thrown:
"Process cannot access the file
'C:\inetpub\wwwroot\ImportFiles\9_11.csv' because it is being used by
another process"
My code:
string fileName = DateTime.Now.ToString().Replace(':', '_').Replace('/', '_').Replace(' ', '_') + Convert.ToString((new Random()).Next(0, 999) * (new Random()).Next(0, 999));
string path = Server.MapPath("ImportFiles") + "\\" + fileName + "" + FileImport.FileName.Substring(FileImport.FileName.IndexOf('.'));
FileImport.SaveAs(path);
string pathforSeconStream = path;
try
{
Response.Write("<script> alert('In Try Block');</script>");
bool flag = true;
int visiblemessageCount = 0;
int rollNo = 1;
StreamReader ColLine = new StreamReader(path);
string ColInputline = ColLine.ReadLine();
String[] ColsInput = ColInputline.Split(',');
ColLine.Close();
ColLine.Dispose();
string preFix = "", RollNumber = "";
StreamReader sr = new StreamReader(pathforSeconStream);
}
catch(Exception ex)
{
}
The code to generate a unique filename is wrong. Use Path.GetTempFileName.
PS never eat an exceptiion. Please remove catch (Exception ex) {};
Revision
Instead of FileImport.Save(...) just save the request in a MemoryStream and then work on it.

File gets locked when overwriting

Title explains a small part so let me explain 2 scenarios. Scenario 1 is raising errors, scenario 2 works like a charm.
Scenario 1:
I checkout a document with the method below, when the document is saved to a location where already is a file with that name it gets overwritten, But surprisingly it also locks the file for some reason:
public bool SaveDocument(int bestandsId, string fileName, string path)
{
//Initialize the Sql Query
var sql = "SELECT DATA FROM Documenten WHERE BESTAND_ID = " + bestandsId;
//Initialize SqlConnection
var connection = new SqlConnection(Instellingen.Instance.DmsConnectionString);
//Initialize SqlCommand
var command = new SqlCommand(sql, connection);
try
{
//Open Connection
connection.Open();
//Fill 'data' from command.ExecuteScalar()
var data = (byte[]) command.ExecuteScalar();
//Write 'data' to file.
File.WriteAllBytes(path + #"\" + fileName, data);
//Return true if no exceptions are raised.
return true;
}
catch (Exception ex)
{
//Initialize Dms Exception
var dmsEx = new DmsException(ex);
//Write Dms Exception to Log File.
DmsException.WriteErrorsToLog(dmsEx);
//Return false, because something went wrong...
return false;
}
finally
{
//Close Sql Connection
connection.Close();
}
}
The method runs smoothly. No problems occur. But when I check in the document with the method below, I get this exception:
Scenario 2:
When I use the SaveDocument method to save the document to a location where there isn't a file with the same name, the file is newly created and is ready to be edited or what ever you want to do with it.
Using scenario 2 is working perfect. The document is ready to be checked in again without receiving an error as shown in the picture above.
Request for code by: #CodeCaster
---------------------------------BEGIN EDIT---------------------------------
public static bool InsertDocument(Document document)
{
try
{
//Exception is thrown when Initializing the FileStream
var fileStream = new FileStream(document.Fileinfo.FullName, FileMode.Open, FileAccess.Read);
var binaryReader = new BinaryReader(fileStream);
var totalNumberOfBytes = new FileInfo(document.Fileinfo.FullName).Length;
var data = binaryReader.ReadBytes((Int32) totalNumberOfBytes);
fileStream.Close();
fileStream.Dispose();
binaryReader.Close();
binaryReader.Dispose();
var pdftext = string.Empty;
try
{
if (document.DocumentType == ".pdf")
{
var reader = new PdfReader(document.Fileinfo.FullName);
var text = string.Empty;
for (var page = 1; page <= reader.NumberOfPages; page++)
{
text += PdfTextExtractor.GetTextFromPage(reader, page);
}
reader.Close();
pdftext = text;
}
}
catch (Exception ex)
{
var dmsEx = new DmsException(ex);
DmsException.WriteErrorsToLog(dmsEx);
}
return InsertIntoDatabase(document.BestandsNaam, document.Eigenaar, document.Omschrijving,
document.DatumToevoeg.ToString(), document.DatumIncheck.ToString(),
document.DatumUitcheck.ToString(), document.UitgechecktDoor,
document.DocumentType, data, pdftext, document.Versie, document.Medewerker,
document.DossierNummer, document.PersonalFolderId.ToString(),
document.DossierFolderId, -1, document.DocumentProgres,
document.OriBestandId.ToString(), 0);
}
catch (Exception ex)
{
var dmsEx = new DmsException("Fout bij inlezen voor toevoeging van nieuw document",
"Klasse Document (InsertDocument)", ex);
ExceptionLogger.LogError(dmsEx);
return false;
}
}
---------------------------------END EDIT---------------------------------
My questions:
What is the cause for the file being locked when it gets overwritten?
How can I prevent this from happening?
Is there some sort of function or parameter that I can set so it doesn't get locked?
Using a tool called "Unlocker" I managed to see what program is locking the file, and YES -> DMS.exe is my application.......:
using(var stream = File.Create(newPath)){}
File.WriteAllBytes(newPath, item.File);
With StreamWriter
using (FileStream fs = File.Create(newPath))
{
fs.Write(item.File, 0, item.File.Length);
}
Or:
File.WriteAllBytes(newPath, item.File);
Reference: "The process cannot access the file because it is being used by another process" with Images

Read Image file metadata

I want to upload an image file and then extract its basic information (author, dimensions, date created, modified, etc) and display it to the user. How can I do it.
A solution or reference to this problem in asp.net c# code would be helpful. But javascript or php would be ok as well.
Check this Link. You will get more Clearance about GetDetailsOf() and its File Properties based on the Win-OS version wise.
If you want to use C# code use below code to get Metadata's:
List<string> arrHeaders = new List<string>();
Shell shell = new ShellClass();
Folder rFolder = shell.NameSpace(_rootPath);
FolderItem rFiles = rFolder.ParseName(filename);
for (int i = 0; i < short.MaxValue; i++)
{
string value = rFolder.GetDetailsOf(rFiles, i).Trim();
arrHeaders.Add(value);
}
C# solution could be found here:
Link1
Link2
Bitmap image = new Bitmap(fileName);
PropertyItem[] propItems = image.PropertyItems;
foreach (PropertyItem item in propItems)
{
Console.WriteLine("iD: 0x" + item.Id.ToString("x"));
}
MSDN Reference
C# Tutorial Reference
try this...
private string doUpload()
{
// Initialize variables
string sSavePath;
sSavePath = "images/";
// Check file size (mustn’t be 0)
HttpPostedFile myFile = FileUpload1.PostedFile;
int nFileLen = myFile.ContentLength;
if (nFileLen == 0)
{
//**************
//lblOutput.Text = "No file was uploaded.";
return null;
}
// Check file extension (must be JPG)
if (System.IO.Path.GetExtension(myFile.FileName).ToLower() != ".jpg")
{
//**************
//lblOutput.Text = "The file must have an extension of JPG";
return null;
}
// Read file into a data stream
byte[] myData = new Byte[nFileLen];
myFile.InputStream.Read(myData, 0, nFileLen);
// Make sure a duplicate file doesn’t exist. If it does, keep on appending an
// incremental numeric until it is unique
string sFilename = System.IO.Path.GetFileName(myFile.FileName);
int file_append = 0;
while (System.IO.File.Exists(Server.MapPath(sSavePath + sFilename)))
{
file_append++;
sFilename = System.IO.Path.GetFileNameWithoutExtension(myFile.FileName)
+ file_append.ToString() + ".jpg";
}
// Save the stream to disk
System.IO.FileStream newFile
= new System.IO.FileStream(Server.MapPath(sSavePath + sFilename),
System.IO.FileMode.Create);
newFile.Write(myData, 0, myData.Length);
newFile.Close();
return sFilename;
}

Categories

Resources