Logging to TextFile from SharePoint - c#

I'm trying to debug a webpart installed on a client's SharePoint instance. I wanted a quick and easy logging feature, so I thought of writing messages to a text file in the temp directory. SharePoint doesn't seem to like it, so what are my options?

IF you are writing to the temp directory, you will need to give the file (if it exists) or the directory rights for the IIS Application pool that the SharePoint IIS application is running under.

There are few ways of custom logging in sharepoint -
Use SPDiagnosticsService - You may write to the ULS via SPDiagnosticsService class.
Utilize diagnostics.asmx web service -
SharePointDiagnostics SharePointDiagnosticsObject = new SharePointDiagnostics();
SharePointDiagnosticsObject.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
string Response = SharePointDiagnosticsObject.SendClientScriptErrorReport(message, file, line, client, stack, team, originalFile);
For more details on usage of diagnostics.asmx refer the following link -
https://vivekkumar11432.wordpress.com/2016/09/23/how-to-do-logging-in-uls-from-csom-in-c/
For more details on logging refer the following link -
http://www.codeproject.com/Articles/620996/Five-suggestions-to-implement-a-better-logging-in
Don't use
Microsoft.Office.Server.Diagnostics.PortalLog.LogString("Message");
According to Microsoft documentation - LogString is reserved for internal use and is not intended to be used directly from your code.

I would guess that this is a permissions issue that SharePoint is blocking you on (and probably not telling you that it is). When you try to write to a text file on the server, you need to have elevated permissions in order to do it. You can accomplish this using SPSecurity.RunWithElevatedPrivileges. Something like the following, if you want just a simple, small-code solution.
SPSecurity.RunWithElevatedPrivileges(delegate() {
using (StreamWriter sw = new StreamWriter(#"C:\log.txt"))
{
//log information here
}
});

Try a logging framework like log4net, or write a small logging framework writing into an external database, you could also use lists to log if you want to stay inside sharepoint

Related

Open file directly from SharePoint path with CSOM

I have a SharePoint server and I want to open files directly from the Server with SharePoint CSOM.
User clicks button --> the file (Excel, Word, ...) opens at the client machine with the standard software.
Directly means, that if I change something to the file and click save, that the file is directly saved on the SharePoint server (or if I click e.g. 'Save as' in Excel the suggested path is 'https://sharpoint.url.com/folder').
Actually I have:
using Microsoft.SharePoint.Client;
var clientContext = new ClientContext("https://sharpoint.url.com");
string relativePath = "/folder/file.xls";
clientContext.Credentials = CredentialCache.DefaultCredentials;
var file = clientContext.Web.GetFileByServerRelativeUrl(relativePath);
clientContext.Load(file);
clientContext.ExecuteQuery();
What do I have to do now, if I want to open the file directly (no download)?
I assume you ask how to access the file's stream instead of downloading it to a local folder.
You can use the File.OpenBinaryDirect method to get access to its ETag and stream, eg :
using(var fileInfo=File.OpenBinaryDirect(clientContext,"/folder/file.xls"))
using(var reader=new StreamReader(fileInfo.Stream))
{
//Do whatever you want with the data
}
BTW you shouldn't use the old xls files. The format is deprecated for over 10 years. The current Excel format, xlsx, is a zipped package of XML files that's better supported by SharePoint itself, doesn't require Excel to generate or read.
For example, if you wanted to read cell values from an xlsx file, you could use the popular EPPlus library to read directly from the stream:
using(var fileInfo=File.OpenBinaryDirect(clientContext,"/folder/file.xlsx"))
using(var package=new ExcelPackage(fileInfo.Stream))
{
var sheet=package.Workbook.Worksheets[0];
var value=ws.Cells["A1"].Value;
//...
}
UPDATE
It seems the question isn't related to programming after all. All that's needed to save or open a SharePoint document is clicking on the document's link. What happens then depends on the Open Documents in Client Applications setting at the site and document library level.
This affects the headers the server sends to the browser when the user clicks on a document link. The browser may still refuse to open the registered application and display the Save dialog.
If that doesn't work, you should check why instead of writing code. It's probably a configuration error or a browser setting. Solving it is easier than creating workarounds, pushing them to all client machines. And then keeping track of all the patches, where they are deployed and deploying new ones.
Apart from that, the Office applications know about SharePoint and document libraries since 2003. They can browse them, display SharePoint properties for the document, show collaborators etc.
As I mentioned in the question comments, a lot of what people think as "SharePoint Developoment" is nothing more that configuration, administration and end user features.
MSDN docs don't help either - they actually cause harm by not covering SP administration or explaining the features and how they are used. You'll find that in Technet. For years, people created webparts in code to change how grids looked because MSDN didn't explain how eg the DataViewWebPart worked or how you could style a grid from the UI.
In general, the best place for such questions is http://sharepoint.stackexchange.com. For example, check “Open in the client application” Vs “Use the server default (Open in the client application)” inside the document library advance settings
We can create Map Network Drive for SharePoint library, and open the file from the network location. Check article below:
http://support.sherweb.com/Faqs/Show/how-to-connect-to-a-sharepoint-site-using-webdav-sharepoint-2013
Or we can download the file from SharePoint and open it using the code below:
Application.Workbooks.Open(#"C:\Test\YourWorkbook.xlsx");
Reference: https://msdn.microsoft.com/en-us/library/b3k79a5x.aspx

How can I upload a static HTML site to a Windows Azure Website programmatically?

I am currently building a local static site generator in C#. It compiles a bunch of templates together into a hierarchy of plain old HTML files. I want to upload the resulting files to my Windows Azure Website and have the changes reflected live, and I want to be able to do this programmatically via my script.
As it stands, I'm having to upload the generated files manually using WebMatrix, as I haven't been able to find an API or SDK that lets me directly upload HTML to a Windows Azure Website.
Surely there must be a way to do this from code, other than just using an sFTP library (which, because it doesn't use the WebMatrix/IIS protocol, which I think sends zipped diffs, would be slow and would mean out-of-sync data during the upload while some files have been updated and others haven't.) I'd also rather not have to commit my generated site to source control if I can avoid it. It seems conceptually wrong to me to be putting something into source control merely as an implementation detail of deployment.
Update: WebMatrix internally uses Web Deploy (MSDeploy). Theoretically you should be able to build the deployment package yourself using the API, but 99% of the examples I can find are using the command-line tool or the GUI tools in Visual Studio. I need to build the package and deploy it programmatically from within C#. Any ideas or guidance on how to go about this? The docs on MSDN don't really show any examples for this kind of scenario.
OK, so I worked out what to do with help from a couple of friendly folks at Microsoft. (See David's Ebbo's response to my forum question, and this very helpful info from Sayed Hashimi showing how to do exactly what I wanted to do from the msdeploy.exe console app).
Just grab your PublishSettings file from the Azure web portal. Open it in a text editor to get the values to paste into the below code.
var destinationOptions = new DeploymentBaseOptions()
{
// userName from Azure Websites PublishSettings file
UserName = "$msdeploytest",
// pw from PublishSettings file
Password = "ThisIsNotMyPassword",
// publishUrl from PublishSettings file using https: protocol prefix rather than 443 port
// and adding "/msdeploy.axd?site={msdeploySite-variable-from-PublishSettings}"
ComputerName = "https://waws-prod-blu-003.publish.azurewebsites.windows.net/msdeploy.axd?site=msdeploytest",
AuthenticationType = "Basic"
};
// This option says we're giving it a directory to deploy
using (var deploymentObject = DeploymentManager.CreateObject(DeploymentWellKnownProvider.ContentPath,
// path to root directory of source files
#"C:\Users\ryan_000\Downloads\dummysite"))
{
var syncOptions = new DeploymentSyncOptions();
syncOptions.WhatIf = false;
// "msdeploySite" variable from PublishSettings file
var changes = deploymentObject.SyncTo(DeploymentWellKnownProvider.ContentPath, "msdeploytest", destinationOptions, syncOptions);
Console.WriteLine("BytesCopied: " + changes.BytesCopied.ToString());
Console.WriteLine("Added: " + changes.ObjectsAdded.ToString());
Console.WriteLine("Updated: " + changes.ObjectsUpdated.ToString());
Console.WriteLine("Deleted: " + changes.ObjectsDeleted.ToString());
Console.WriteLine("Errors: " + changes.Errors.ToString());
Console.WriteLine("Warnings: " + changes.Warnings.ToString());
Console.WriteLine("ParametersChanged: " + changes.ParameterChanges.ToString());
Console.WriteLine("TotalChanges: " + changes.TotalChanges.ToString());
}
You might also be able to stumble your way through the obscure documentation on MSDN. There is a lot of passing around of oddly-named options classes, but with a bit of squinting of one's eyes and flailing about in the docs it's possible to see how the command-line options (of which it is much easier to find examples online) map to API calls.
The easiest way is probably to set up Git publishing for your website and programmatically do a git commit followed by a git push. You can think of it as a deployment mechanism instead of source control, given that Azure websites natively support a backing Git repository that doesn't have to have anything to do with your chosen SCM solution.
WebMatrix uses WebDeploy to upload the files to Windows Azure Web Sites.
An alternative is to use the VFS REST API (https://github.com/projectkudu/kudu/wiki/REST-API#wiki-vfs). The diagnostic console uses this to work with the file system today.

Denied acces to a file

I have a code which is similar this:
string file;
using (StreamReader r = new StreamReader("xml.xml"))
{
file = r.ReadToEnd();
}
XElement xml = XElement.Parse(file);
using (XmlWriter w = XmlWriter.Create("xml.xml")) //The point of problem!
{
w.WriteStartDocument();
...;
w.WriteEndDocument();
}
When I try run it like a console application is everything all right. But problems start when I want to use it in an ASP.NET application. At the using line it throws UnauthorizedAccessException exception with a description "access to the path is denied". Why?
You need to check which account your application Pool is using to access your server files/folders, for example, make one code to copy one file to application folder, check all security info, copy and paste on this problem folder, normally use this account "IIS_IURRS" give full control to test only...
If IIS/the web server is configured correctly, an account with a very limited set of permissions is used. As your path points to the application directory, it is very likely that the application pool account is not allowed to write to this location.
If you run the code in a console application, your user's permissions are applied and it is more than likely that you are allowed to write to the output folder of the project as Visual Studio writes the build output there under your account.
I would not recommend to change the application pool account or the permissions of the application folder in the file system - it is a very sensible limitation that limits the amount of trouble an attacker can possibly make.
Therefore I'd recommend to either move the file to a folder that the account can write to without changing permissions or define a special one outside of the application folder hierarchy that the account is given permissions to.
Also keep in mind that multiple users might access the file at the same time, so a database might be a better choice to store the data.

Use external xml file after publishing the c# desktop application

I have developed a c# desktop application that needs to be hosted on a server and will be scheduled to fetch data based on queries stored in XML files. while developing, I was using the following code to read XML files:
var query = new XPathDocument(#"C:\\Documents and Settings\\XYZ\\Desktop\\productplanningquery.xml");
as you can see I had put the XML file conveniently on my desktop and it worked fine while development. What I want to do now, is to give at a path such that where ever I host the application plus the XML files, it does not throw an exception. One way i thought could be to have a folder in a directory where the application will be installed but for that i will have to figure out the path to current directory dynamically (which i could not figure out).
Please help.
You could pass the location of you XML using args this way you're code would look like so:
var query = new XPathDocument(args[0])
You can also use relative path. Make sure that when deploying your code you keep the location of the file in the same relative location. For example if you place the XML in the same directory as the application
var query = new XPathDocument("productplanningquery.xml")
I am not sure what you want to achieve whether you want to read xml using winform app and do some operation and then pass it web app or some thing else. But here is my understandings:
Case 1: If you need to create XML outside the IIS and that XML will be consumed by ASP.Net app, then :
For using a desktop application with IIS server , you need to have full administrative access to the Live Machine. If its not then you should consider building windows services to operate on the XML files or any task that will run behind the scenes to decrease the load of the asp.net app.
Still in this case if you dont own a server then you need some Virtual Private Hosting or similar kind of hosting where you have almost all previleges to access the system. Then deploy the Windows Service, set the output path in such a manner so that it can be accessed by asp.net app too. And do whatever you want.
Case 2: If you want o read XML in ASP.Net Solely, then
In this case you case read it easily by using XDocument.But note, XML should in the same application directory or under the reach of the ASP.Net app
MSDN Article for Web-Windows Services with ASP.Net
You can use something like this:
var path = string.Format("{0}\\{1}", Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "productplanningquery.xml");
var pathForCurrentApp = string.Format("{0}\\{1}", Environment.CurrentDirectory, "productplanningquery.xml");

IIS Permissions for Saving Word Documents

Our ASP.NET/C# lets users edit and manage Word (OpenXML) documents that are hosted on a server. I am using client-side VBScript functions to handle some of the editing functions including saving the document to a folder on the server. For the save functionality, I am using the following function call :
Document.SaveAs "http://server/savefolder/savefile.docx"
I have given "Full Control" permissions on savefolder to both the NETWORK SERVICE and the IUSR_MACHINE users. Yet the above call fails. The error number returned is 5096. The error message is some gibberish that doesn't make any sense.
The server is Windows 2003 and the IIS version is 6.0. I have installed the OpenXML SDK 2.0 CTP on the server.
I can successfully read and print documents.
Does anyone tell me what I am doing wrong? or what additional settings need to be in place?
BTW, the error message ("gibberish" from my post) is:
"EOALPHABETICARABICARABICABJADARABICALPHABAHTTEXTCAPSCARDTEXTCHARFORMATCHI"
No, I am not making this up!
In my case, that error 5096 with description "EOALPHABETICARABICARABICABJADARABICALPHABAHTTEXTCAPSCARDTEXTCHARFORMATCHI"
occurred when using VBA code in Access to drive a Word mail-merge. The cause was trying to save a document with the same name (including path) as an open document.
Error line:
objApp.ActiveDocument.SaveAs saveAsName
where objApp is the object variable representing the Word application and saveAsName is the string variable storing the name I am trying to save the file as e.g. "C:\temp\testdoc.docx".
IF a file with the same name exists but is not open, the above code overwrites it silently.
Turns out WebDAV is not turned on by default in IIS 6.0. Once I turned it on, I was able to save the documents just fine.
Thanks for all your answers!
Just a guess... if the vbscript is running on the client, the code is probably running under the user's account, not under the server's IIS account. So unless you give write access to that user, vbscript probably won't work for this.
Since you're using ASP.NET, you could try writing a web service that takes in Word document data and saves it to the server for you.
I'd try running Fiddler on the client while trying to save the document to get a sense of what's really going on. I wonder if maybe it's trying to do an HTTP PUT (as opposed to a POST).
Have you given write access to the folder in IIS manager?
Is the save folder you're using outside of the websites root directory, i.e. 'hidden' from the internet?
Just to add to SI's information...
I also get this I get the 5096 - EOALPHABETICARABICARABICABJADARABICALPHABAHTTEXTCAPSCARDTEXTCHARFORMATCHI error when my code tries to save a MS Word document with the same name and to the same location as a Word document that is already open in another instance of Word.
Although not entirely relevant to this thread, I hope it may help someone else who stumbles upon this thread!
Regards,
Duane,
this question is old but still active ?
You save the file with a http://... url, i think you should save it with a file URL as
Document.SaveAs "\\server\savefolder\savefile.docx"
Grtz

Categories

Resources