I want users to upload the .doc files only in the document library.
To do so, I have developed an event receiver in Visual Studio 2010.
My code is as follows:
public override void ItemAdding(SPItemEventProperties properties)
{
try
{
base.ItemAdding(properties);
EventFiringEnabled = false;
if (!properties.AfterUrl.EndsWith("doc"))
{
properties.ErrorMessage = "You are allowed to updload only .doc files";
properties.Status = SPEventReceiverStatus.CancelWithError;
properties.Cancel = true;
}
}
catch (Exception ex)
{
properties.Status = SPEventReceiverStatus.CancelWithError;
properties.ErrorMessage = ex.Message.ToString();
properties.Cancel = true;
}
}
The code is referred from this example.
My problem is that while I am uploading non-doc files it is preventing but with the system error message not the user friendly as defined in properties.ErrorMessage.
How do I solve this?
Please help.
I used the same code you have provided in your question, I get custom error message displayed as shown in below image -
Please provide details of the error you are getting.
Related
Using a service account, Google Drive API and Google SpreadSheet API, I create a spreadsheet that i then move to a specific folder, using the following code :
public async Task<File> SaveNewSpreadsheet(Spreadsheet spreadsheet, File folder)
{
try
{
Spreadsheet savedSpreadsheet = await _sheetService.Spreadsheets.Create(spreadsheet).ExecuteAsync();
string spreadsheetId = GetSpreadsheetId(savedSpreadsheet);
File spreadsheetFile = await GetFileById(spreadsheetId);
File spreadsheetFileMoved = await MoveFileToFolder(spreadsheetFile, folder);
return spreadsheetFileMoved;
}
catch (Exception e)
{
_logger.LogError(e, $"An error has occured during new spreadsheet save to Google drive API");
throw;
}
}
public async Task<File> MoveFileToFolder(File file, File folder)
{
try
{
var updateRequest = _driveService.Files.Update(new File(), file.Id);
updateRequest.AddParents = folder.Id;
if (file.Parents != null)
{
string previousParents = String.Join(",", file.Parents);
updateRequest.RemoveParents = previousParents;
}
file = await updateRequest.ExecuteAsync();
return file;
}
catch (Exception e)
{
_logger.LogError(e, $"An error has occured during file moving to folder.");
throw;
}
}
This used to work fine for a year or so, but since today, the MoveFileToFolder request throw the following exception:
Google.GoogleApiException: Google.Apis.Requests.RequestError
Increasing the number of parents is not allowed [403]
Errors [
Message[Increasing the number of parents is not allowed] Location[ - ] Reason[cannotAddParent] Domain[global]
]
The weird thing is that if I create a new service account and use it instead of the previous one, it works fine again.
I've looked for info on this "cannotAddParent" error but I couldn't find anything.
Any ideas on why this error is thrown ?
I have the same problem and filed in issue in the Google Issue Tracker. This is intended behavior, unfortunately. You are no longer able to place a file in multiple parents as in your example. See the linked documentation for migration.
Beginning Sept. 30, 2020, you will no longer be able to place a file in multiple parent folders; every file must have exactly one parent folder location. Instead, you can use a combination of status checks and a new shortcut implementation to accomplish file-related operations.
https://developers.google.com/drive/api/v2/multi-parenting
I want to print a node to a pdf file using "Microsoft Print to PDF" printer. Supposing that the Printer object is already extracted I have the next function which is working perfectly.
public static void printToPDF(Printer printer, Node node) {
PrinterJob job = PrinterJob.createPrinterJob(printer);
if (job != null) {
job.getJobSettings().setPrintQuality(PrintQuality.HIGH);
PageLayout pageLayout = job.getPrinter().createPageLayout(Paper.A4, PageOrientation.PORTRAIT,
Printer.MarginType.HARDWARE_MINIMUM);
boolean printed = job.printPage(pageLayout, node);
if (printed) {
job.endJob();
} else {
System.out.println("Printing failed.");
}
} else {
System.out.println("Could not create a printer job.");
}
}
The only issue that I have here, is that a dialog box is popping up and asking for a destination path to save the pdf. I was struggling to find a solution to set the path programmatically, but with no success. Any suggestions? Thank you in advance.
After some more research I came with an ugly hack. I accessed jobImpl private field from PrinterJob, and I took attributes out of it. Therefore I inserted the destination attribute, and apparently it is working as requested. I know it is not nice, but ... is kind of workable. If you have any nicer suggestion, please do not hesitate to post them.
try {
java.lang.reflect.Field field = job.getClass().getDeclaredField("jobImpl");
field.setAccessible(true);
PrinterJobImpl jobImpl = (PrinterJobImpl) field.get(job);
field.setAccessible(false);
field = jobImpl.getClass().getDeclaredField("printReqAttrSet");
field.setAccessible(true);
PrintRequestAttributeSet printReqAttrSet = (PrintRequestAttributeSet) field.get(jobImpl);
field.setAccessible(false);
printReqAttrSet.add(new Destination(new java.net.URI("file:/C:/deleteMe/wtv.pdf")));
} catch (Exception e) {
System.err.println(e);
}
I'm simply trying to attach a file named Document.pdf in the DocumentsLibrary to an email using the Share Charm. My code below works perfectly on the Local Machine:
private async void OnDataRequestedFiles(DataTransferManager sender, DataRequestedEventArgs e)
{
List<IStorageItem> shares = new List<IStorageItem>();
StorageFile filetoShare = await Windows.Storage.KnownFolders.DocumentsLibrary.GetFileAsync("Document.pdf");
if (filetoShare != null)
{
shares.Add(filetoShare);
filetoShare = null;
}
if (shares != null)
{
DataPackage requestData = e.Request.Data;
requestData.Properties.Title = "Title";
requestData.Properties.Description = "Description"; // The description is optional.
requestData.SetStorageItems(shares);
shares = null;
}
else
{
e.Request.FailWithDisplayText("File not Found.");
}
}
But when I run the exact same code on a Windows Surface Tablet, I get the dreaded "There's nothing to share right now." on the right in the Charms flyout area.
Here's a little more background to help:
I'm not looking to use a File Picker...I know the exact file I'm looking for
I've enabled the Documents Library Capability in the manifest
I've added a File Type Association for pdf in the manifest
and yes, the file does exist and is in the Documents Library
an email account is properly setup in the Mail App on the surface
I can successfully send text emails from the Tablet...just not emails with attachments
Like I said, this works on my Win 8 Development Machine as expected...just not on the Surface. I'm wondering if the Surface has different file or folder permissions?
Thanks for the help...this is driving me CRAZY
I finally figured it out - the problem was that my Event Handler was async (so that I could use await to set the StorageFile variable).
I solved it by setting the StorageFile variable earlier in my code so that it was already available when the Event Handler was called.
I still have no idea why it worked on my development machine, but no on the WinRT surface...
The handler can be an async method. In this case, it is critical to use DataTransferManager. Please refer to the MSDN page specifically for this scenario. For your convenience, the code from the page is copied to here:
private void RegisterForShare()
{
DataTransferManager dataTransferManager = DataTransferManager.GetForCurrentView();
dataTransferManager.DataRequested += new TypedEventHandler<DataTransferManager,
DataRequestedEventArgs>(this.ShareStorageItemsHandler);
}
private async void ShareStorageItemsHandler(DataTransferManager sender,
DataRequestedEventArgs e)
{
DataRequest request = e.Request;
request.Data.Properties.Title = "Share StorageItems Example";
request.Data.Properties.Description = "Demonstrates how to share files.";
// Because we are making async calls in the DataRequested event handler,
// we need to get the deferral first.
DataRequestDeferral deferral = request.GetDeferral();
// Make sure we always call Complete on the deferral.
try
{
StorageFile logoFile =
await Package.Current.InstalledLocation.GetFileAsync("Assets\\Logo.png");
List<IStorageItem> storageItems = new List<IStorageItem>();
storageItems.Add(logoFile);
request.Data.SetStorageItems(storageItems);
}
finally
{
deferral.Complete();
}
}
It is critical to place the following statement before any async method is called:
DataTransferManager dataTransferManager = DataTransferManager.GetForCurrentView();
You only have half a second to get the whole job done (getting the file, attaching...etc.). If the half-second deadline occurs you'll get this "driving crazy" message. Consider implementing some resumable logic and replace the message with "the attachment is being prepared please try again in a few seconds" (or else).
Your WinRT device might be just slower than your development machine. The latter just does the job before the deadline...
I'm trying to implement a customization in SharePoint 2010 so that when a document is uploaded to a library, the file name is changed to include the Document ID in the name. (I know that people shouldn't worry about file names as much any more, but we have a lot of legacy files already named and users who like to have local copies).
I was able to implement a custom Event Receiver on the ItemAdded event that renames the file by adding the Document ID before the file name. This works correctly from the web Upload.
The problem is with the Explorer View. When I try to add the file using WebDAV in the Explorer View, I get two copies of the file. It seems that when a file is uploaded via the Web the events that fire are
ItemAdding
ItemAdded
But when I copy/paste a file into Explorer View I see the following events:
ItemAdding
ItemAdded
ItemAdding
ItemAdded
ItemUpdating
ItemUpdated
The result is I have two files with different names (since the Document IDs are different).
I've found a lot of people talking about this issue online (this is the best article I found). Anyone have any other ideas? Would it make more sense to do this in a workflow instead of an event receiver? I could use a scheduled job instead, but that might be confusing to the user if the document name changed a few minutes later.
This is my code that works great when using the Web upload but not when using Explorer View:
public override void ItemAdded(SPItemEventProperties properties)
{
try
{
SPListItem currentItem = properties.ListItem;
if (currentItem["_dlc_DocId"] != null)
{
string docId = currentItem["_dlc_DocId"].ToString();
if (!currentItem["BaseName"].ToString().StartsWith(docId))
{
EventFiringEnabled = false;
currentItem["BaseName"] = docId + currentItem["BaseName"];
currentItem.SystemUpdate();
EventFiringEnabled = true;
}
}
}
catch (Exception ex)
{
//Probably should log an error here
}
base.ItemAdded(properties);
}
I have found that using a Visual Studio workflow allows me the most flexibility to do this. A SharePoint Designer Workflow would be simpler, but would be harder to deploy to different sites and libraries.
After reading some good articles including this and this I have come up with this code which seems to work. It starts a workflow and waits until the document is not in a LockState and then processes the filename.
The workflow looks like this:
And here is the code behind:
namespace ControlledDocuments.RenameWorkflow
{
public sealed partial class RenameWorkflow : SequentialWorkflowActivity
{
public RenameWorkflow()
{
InitializeComponent();
}
public Guid workflowId = default(System.Guid);
public SPWorkflowActivationProperties workflowProperties = new SPWorkflowActivationProperties();
Boolean continueWaiting = true;
private void onWorkflowActivated1_Invoked(object sender, ExternalDataEventArgs e)
{
CheckFileStatus();
}
private void whileActivity(object sender, ConditionalEventArgs e)
{
e.Result = continueWaiting;
}
private void onWorkflowItemChanged(object sender, ExternalDataEventArgs e)
{
CheckFileStatus();
}
private void CheckFileStatus()
{
if (workflowProperties.Item.File.LockType == SPFile.SPLockType.None)
{
continueWaiting = false;
}
}
private void renameFile(object sender, EventArgs e)
{
try
{
SPListItem currentItem = workflowProperties.Item;
if (currentItem["_dlc_DocId"] != null)
{
string docId = currentItem["_dlc_DocId"].ToString();
if (!currentItem["BaseName"].ToString().StartsWith(docId))
{
currentItem["BaseName"] = docId + currentItem["BaseName"];
currentItem.SystemUpdate();
}
}
}
catch (Exception ex)
{
//Should do something useful here
}
}
}
}
Hope this helps someone else if they have the same problem.
Well i'd go for the workflow workaround... there are 2 options imo:
1) Create a boolean fied in your document library, then create a SPD workflow that fires when the item is added and set that field to "Changed" or something. In the EventReceiver you then check whether that field has been set..
2) Do everything with the SPD workflow - changing the title like in this example should be no problem.
I am currently developing an eclipse plugin, i created my own property page which will be displayed when right-clicking on the context menu of selected project. I tried to save values of that page by pressing OK button on that page, but i got exception saying: "Exception occurred while saving project preferences: /test/.settings/com.example.plugin.prefs.Resource is out of sync with the file system: '/test/.settings/com.example.plugin.prefs'."
Following is what i implemented:
//Get the project
IAdaptable resource = getElement();
if (resource != null) {
IProject project = (IProject) resource.getAdapter(IProject.class);
}
//Define project scope
IScopeContext projectScope = new ProjectScope(project);
//Get node by qualified name
Preferences projectNode = projectScope.getNode(MyPlugin.PLUGIN_ID);
//set the value and save it
if (projectNode != null) {
projectNode.put(PROPERTIES_SERVICENAME, serviceName);
}
try {
projectNode.flush(); // Exception occurs here!!!
} catch (BackingStoreException e) {
e.printStackTrace();
}
To my knowledge, it should automatically save a file like "com.example.plugin.prefs" under runtime-EclipseApplication\test.settings as well, is that correct?
Anybody has idea how to solve this problem?