I am at my wits end on this one. I have a user interface that creates and edits documents stored in a SharePoint document library. The trick part is I need to allow the user to update the document no problem just use SPFile.SaveBinary() right?
This definitely updates the contents of the file but somehow the old file name and the old extension persist, this is a problem. Deleting and re-adding the list item is not a solution either because the id of the item is being referenced in the url.
My question is how can I update the extension and filename metadata of the SPFile item?
So far all of my attempts using the object library have failed, i've tried updating the fields below none have been successful. It seems like there has to be an easier way to do this.
SPFile file = item.File;
file.Item[SPBuiltInFieldId.FileLeafRef] = resolvedFileName;
file.Item[SPBuiltInFieldId.FileRef] = "/File/" + resolvedFileName;
file.Item[SPBuiltInFieldId.BaseName] = System.IO.Path.GetFileNameWithoutExtension(resolvedFileName);
file.Item["Name"] = System.IO.Path.GetFileNameWithoutExtension(resolvedFileName);
file.SaveBinary(conduitFile);
file.Update();
[EDIT] - Here is my working solution.
SPFile file = item.File;
string resolvedFileName = item.ID.ToString() + "-" + conduitFileName;
item["Title"] = resolvedFileName;
file.SaveBinary(conduitFile);
file.MoveTo(item.ParentList.RootFolder.Url + "/" + resolvedFileName, true);
file.Item["Name"] = resolvedFileName;
file.Update();
After the file is saved to the library, use the MoveTo method and pass the modified file name in the newUrl parameter.
SPFile.MoveTo Method (String)
Quick & Easy: Rename Uploaded File Using SharePoint Object Model Via an Event Receiver
Another way that is simpler than using the MoveTo is to use the BaseName property of the SPListItem. You would set this by running
item["BaseName"] = resolvedFileName; //Whatever you want the new file name to be
item.Update();
This is easier than MoveTo because you don't have to worry about the folder hierarchy and you don't have to worry about the file extension.
For some reason the property is not listed on the MSDN documentation, but it seems to work well without a problem.
Related
In my project I'm frequently passing one AccountID in different packages and classes and that accountid is hardcoded wherever it used.
This AccountID may change for some resons in the future. And in order not to go over all files in my my project and replace it, I want to write it in one place.
I heard that there are some properties in IntelliJ where I can do that. I don't know how to google my problem, so if you have any sources, please share.
I think you should use the Properties.class for that purpose.
just write a txt file anywere (I recomend your Resources folder) and name it to "myProperties.properties" for instance
The text in your propertiefile would look like the following:
AccountID = "whateverIDyouWant"
to get the data of your propertiefile call:
Properties props = new Properties();
FileInputStream in = new FileInputStream("G:\\your\\path\\myProperties.properties");
props.load(in);
in.close();
String AccountID = props.getProperty("AccountID");
if your AccountID is an int just parse your string using Integer.parseInt(yourString);
if you want to set your properties through hard code, that can also be done:
props.setProperty("AccountID", "whateverIDyouWant");
Edit:
to create a resources folder, create a folder in your classpath. Afterwards go to the "Project view" in IntelliJ. Rightclick the new folder and select "Mark directory as" -> "Sources Root". Thats how its done.
Basically I have some attachments listed in the Generic Object Services (GOS) and I need to download all of them to my computer.
I need to know how do download these attachments programatically from my program/report.
I've never actually had to do this myself, but I think this is how it's done:
Get the list of attachments by calling cl_binary_relation=>read_links passing in the ID of the object that the attachments are attached to. The it_relation_options table should be filled with a relation like so:
la_relat-sign = 'I'.
la_relat-option = 'EQ'.
la_relat-low = 'ATTA'. "Attachements
APPEND la_relat TO lt_relat.
This tells read_links to get the related objects classed as attachments.
Once you've successfully got the attachment details, you should be able to loop over the results table and pass each to the SO_OBJECT_READ function module (if that doesn't work try SO_DOCUMENT_READ_API1). This expects a folder id and a document id; in the results of read_links these may be concatenated together into one string (with the object type, e.g. SOFM at the front).
SO_OBJECT_READ will give you the binary content. You can then call SO_OBJECT_DOWNLOAD with (I think) filetype = 'BIN'.
Hope that helps!
I'm writing a program that can upload files to multiple FTP servers.
There is a table, at the top row there are the sites, and at the far left column there are the files. through this table I define what should be uploaded to where.
the program is already working, but what i want to do now is to upload the files parallely on each site. so when i hit start each column will go through the rows on its own and upload the files to that site if the content of the specific cell says so. sites can be any number between 1 and 50. and all uploads should be in parallel. (one file at the time for each site)
what i am asking is what is the best way to handle such thing? i know i have to set up multiple uploaders, but what is confusing me is how to keep track what each site is doing. the only thing i can come up with is an array of arrays. where each position is for a site, and the array at that position defines what file is beeing uploaded and all the informations it needs for that. would that be a good solution?
thanks!
You can put your data into array then use for loop
use this code
$web = ['www.firstSite.com','www.secondSite.com']
$user = ['firstUser','secondUser']
$pass = ['firstPass','secondPass']
for($i=0;$i<sizeof($web);$i++)
{
$conn_id = ftp_connect($web[$i]);
$login_result = ftp_login($conn_id,$user[$i],$pass[$i]);
if (ftp_put($conn_id, $server_file, $local_file, FTP_BINARY))
{echo "Success";}
else {echo "Failed";}
}
You can make a custom class and use a List(Of SiteFiles) for a collection of them. You iterate the sites data and create a new SiteFiles object for each site and add the files names to the Files property that need to be uploaded to that site. Then when your done making this List(Of SiteFiles) then you can iterate each file in SiteFiles.Files for each SiteFiles object and use threading/async methods if needed and upload the files. This gives you a neat and tidy way to organize what your doing.
Public Class SiteFiles
Public Property Site As String
Public Property Files As New List(Of String)
End Class
I've tried many variations.
Send To Library - That creates a Zipped file in the Drop Off Library, then it doesn't route via the rules in Content Organizer
API - I've tried to do an Export, Import, but always receive the same error. This is per this MSDN documentation: http://msdn.microsoft.com/en-us/library/microsoft.office.documentmanagement.documentsets.documentset.create.aspx
Sample snippet:
byte[] exportedFile = set.Export();
DocumentSet.Import(exportedFile, DocSetNameToCreate, targetFolder, dsCt.Id, properties, web.CurrentUser);
Error Received:
DocID: Site prefix not set.
Finally got it to run. This is related to the Document ID Feature. Make sure it is activated in each site. Let is run over night (timer jobs need to run). Then the content organizer will successfully move and unpackage your document sets.
You don't have to activate the document id feature, just ensure that in the property bag of the root web of the destination site collection (where the document set will be imported again) exists a property named "docid_msft_hier_siteprefix" with an value of "" (empty string).
Use this powershell-script:
$site = Get-SPSite http://host/sites/yoursite
$properties = $site.RootWeb.Properties
if ($properties["docid_msft_hier_siteprefix"] -eq $null)
{
$properties["docid_msft_hier_siteprefix"] = ""
$properties.Update()
}
Note that i use the old property bag RootWeb.Properties instead of the new hashtable RootWeb.AllProperties, thats because the class Microsoft.Office.DocumentManagement.Internal.OobProvider still uses that.
So why is it failing when a document set is imported? The function DocumentSet.ImportProperties() catches an ArgumentException while trying to set the document id of the document set list item (so there's no problem if the document id column doesn't exist yet).
But they missed that the function OobProvider.GetSitePrefix() which is called through the function OobProvider.GenerateDocumentId() throws an InvalidOperationException if the property bag doesn't contain the prefix property.
I need to make a bunch of redirect pages as I've recently updated my web site which previously used .html files and now all the files are .aspx. I have a tab-delimited file containing a list of original filenames and the corresponding new filename.
It seems like there should be a language out there that I should be able to create a file using the first column for the filename and insert the second column as its content with some additional text for the 301 redirect.
Could someone point me in the right direction as to what language(s) would be able to accomplish this? Also, if you could also point out the name of the method/function I would be using so I know where to begin when creating the file.
I've needed to do this type of thing many times and am willing to learn a new language (Perl, Python, or whatever) to accomplish this, but I just need pointed in the right direction. I am using Windows XP to develop on.
Thank you for your time.
This can be done in a few lines of C# if you already are working with aspx you can process this in the codebehind on a dummy page.
System.IO.StreamReader myreader = new System.IO.StreamReader(Server.MapPath("~/Text.txt"));
while (!myreader.EndOfStream)
{
//9 is Ascii value of Tab bad idea to split if the second set of values might contain tabs but can reconstruct the data if inputString.length >2
string[] inputString = myreader.ReadLine().Split(char.ConvertFromUtf32(9).ToCharArray());
//construct the path to where you want to save the file, or if the filename is the full path all the better
System.IO.StreamWriter filemaker = new System.IO.StreamWriter(#"C:\" + inputString[0]);
filemaker.Write(inputString[1]);
filemaker.Close();
}