opening url based file in filestream - sharepoint-2010

I have a document which is stored in doc library of sharepoint..now i want to open and read data from it ...how can i do it ..filestream does not take url as input ..please help.

Try SPFile.OpenBinaryStream
From SharePoint 2007 - Read content from SPFile:
string content = string.Empty;
using (SPSite oSite = new SPSite("http://localhost/"))
{
using (SPWeb oWeb = oSite.OpenWeb())
{
SPDocumentLibrary doclib = (SPDocumentLibrary)oWeb.GetList(DocLibUrl);
SPFile htmlFile = doclib.Items[0].File;
using (System.IO.StreamReader reader = new System.IO.StreamReader(htmlFile.OpenBinaryStream()))
{
content = reader.ReadToEnd();
}
}
}

Sounds like you need to use a HTTPRequest object to retrieve the file. Here is a code example:
http://geeknotes.wordpress.com/2008/01/10/saving-a-possibly-binary-file-from-a-url-in-c/

Related

Error using OpenXML to read a .docx file from a memorystream to a WordprocessingDocument to a string and back

I have an existing library that I can use to receive a docx file and return it. The software is .Net Core hosted in a Linux Docker container.
It's very limited in scope though and I need to perform some actions it can't do. As these are straightforward I thought I would use OpenXML, and for my proof of concept all I need to do is to read a docx as a memorystream, replace some text, turn it back into a memorystream and return it.
However the docx that gets returned is unreadable. I've commented out the text replacement below to eliminate that, and if I comment out the call to the method below then the docx can be read so I'm sure the issue is in this method.
Presumably I'm doing something fundamentally wrong here but after a few hours googling and playing around with the code I am not sure how to correct this; any ideas what I have wrong?
Thanks for the help
private MemoryStream SearchAndReplace(MemoryStream mem)
{
mem.Position = 0;
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(mem, true))
{
string docText = null;
StreamReader sr = new StreamReader(wordDoc.MainDocumentPart.GetStream());
docText = sr.ReadToEnd();
//Regex regexText = new Regex("Hello world!");
//docText = regexText.Replace(docText, "Hi Everyone!");
MemoryStream newMem = new MemoryStream();
newMem.Position = 0;
StreamWriter sw = new StreamWriter(newMem);
sw.Write(docText);
return newMem;
}
}
If your real requirement is to search and replace text in a WordprocessingDocument, you should have a look at this answer.
The following unit test shows how you can make your approach work if the use case really demands that you read a string from a part, "massage" the string, and write the changed string back to the part. It also shows one of the shortcomings of any other approach than the one described in the answer already mentioned above, e.g., by demonstrating that the string "Hello world!" will not be found in this way if it is split across w:r elements.
[Fact]
public void CanSearchAndReplaceStringInOpenXmlPartAlthoughThisIsNotTheWayToSearchAndReplaceText()
{
// Arrange.
using var docxStream = new MemoryStream();
using (var wordDocument = WordprocessingDocument.Create(docxStream, WordprocessingDocumentType.Document))
{
MainDocumentPart part = wordDocument.AddMainDocumentPart();
var p1 = new Paragraph(
new Run(
new Text("Hello world!")));
var p2 = new Paragraph(
new Run(
new Text("Hello ") { Space = SpaceProcessingModeValues.Preserve }),
new Run(
new Text("world!")));
part.Document = new Document(new Body(p1, p2));
Assert.Equal("Hello world!", p1.InnerText);
Assert.Equal("Hello world!", p2.InnerText);
}
// Act.
SearchAndReplace(docxStream);
// Assert.
using (WordprocessingDocument wordDocument = WordprocessingDocument.Open(docxStream, false))
{
MainDocumentPart part = wordDocument.MainDocumentPart;
Paragraph p1 = part.Document.Descendants<Paragraph>().First();
Paragraph p2 = part.Document.Descendants<Paragraph>().Last();
Assert.Equal("Hi Everyone!", p1.InnerText);
Assert.Equal("Hello world!", p2.InnerText);
}
}
private static void SearchAndReplace(MemoryStream docxStream)
{
using (WordprocessingDocument wordDocument = WordprocessingDocument.Open(docxStream, true))
{
// If you wanted to read the part's contents as text, this is how you
// would do it.
string partText = ReadPartText(wordDocument.MainDocumentPart);
// Note that this is not the way in which you should search and replace
// text in Open XML documents. The text might be split across multiple
// w:r elements, so you would not find the text in that case.
var regex = new Regex("Hello world!");
partText = regex.Replace(partText, "Hi Everyone!");
// If you wanted to write changed text back to the part, this is how
// you would do it.
WritePartText(wordDocument.MainDocumentPart, partText);
}
docxStream.Seek(0, SeekOrigin.Begin);
}
private static string ReadPartText(OpenXmlPart part)
{
using Stream partStream = part.GetStream(FileMode.OpenOrCreate, FileAccess.Read);
using var sr = new StreamReader(partStream);
return sr.ReadToEnd();
}
private static void WritePartText(OpenXmlPart part, string text)
{
using Stream partStream = part.GetStream(FileMode.Create, FileAccess.Write);
using var sw = new StreamWriter(partStream);
sw.Write(text);
}

OneDrive REST API get files without folderID

I'm trying to use the oneDrive REST API to get files in a specific folder.
I have the path to the folder (For example "myApp/filesToDownload/", but don't have the folder's oneDrive ID. Is there a way to get the folder ID or the files in the folder with the REST API?
The only way I see to get it is by using https://apis.live.net/v5.0/me/skydrive/files?access_token=ACCESS_TOKEN
to get the list of folders in the root, and then splitting the path string on "/" and looping on it, each time doing a GET https://apis.live.net/v5.0/CURRENT_FOLDER/files?access_token=ACCESS_TOKEN request for each hierarchy.. I would prefer to avoid doing all those requests because the path may be quite long..
Is there a better/simpler way of getting the files of a specific folder?
Thanks
As Joel has pointed out, Onedrive API supports path based addressing also (in addition to ID based addressing). So you don't need the folder ID. You can use the Onedrive API (api.onedrive.com) for getting the files/folders of a specific folder as follows:
String path = "path/to/your/folder"; // no '/' in the end
HttpClient httpClient = new DefaultHttpClient();
// Forming the request
HttpGet httpGet = new HttpGet("https://api.onedrive.com/v1.0/drive/root:/" + path + ":/?expand=children");
httpGet.addHeader("Authorization", "Bearer " + ACCESS_TOKEN);
// Executing the request
HttpResponse response = httpClient.execute(httpGet);
// Handling the response
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
StringBuilder builder = new StringBuilder();
for (String line = null; (line = reader.readLine()) != null;) {
builder.append(line).append("\n");
}
JSONTokener tokener = new JSONTokener(builder.toString());
JSONObject finalResult = new JSONObject(tokener);
JSONArray fileList = null;
try{
fileList = finalResult.getJSONArray("children");
for (int i = 0; i < fileList.length(); i++) {
JSONObject element = (JSONObject) fileList.get(i);
// do something with element
// Each element is a file/folder in the form of JSONObject
}
} catch (JSONException e){
// do something with the exception
}
For more details see here.

PDF generation in mvc4 with itextsharp

I am working on pdf generation, it is successfully implemented using itextsharp.dll. It’s working fine on local environment after publish also. We have our own server at other site
But same code doesn't work on the server,pdf is not generated instead it gives an error: 'The document has no pages.'
Initially I thought it is due to no data in document but it works locally with or without data in the document.
I had code implemented as follows to make a web request Is any problem in that ??
try
{
var myHttpWebRequest = (HttpWebRequest)WebRequest.Create(strPdfData + "?objpatId=" + patID);
var response = myHttpWebRequest.GetResponse();
myHttpWebRequest.Timeout = 900000;
var stream = response.GetResponseStream();
StreamReader sr = new StreamReader(stream);
content = sr.ReadToEnd();
}
create a method in the controller:
[HttpGet]
public JsonResult GetFile()
{
var json = new WebClient().DownloadFile(string address, string fileName);
//This code is just to convert the file to json you can keep it in file format and send to the view
dynamic result = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
var oc = Newtonsoft.Json.JsonConvert.DeserializeObject<countdata[]>(Convert.ToString(result.countdata));
return Json(oc, JsonRequestBehavior.AllowGet);
}
In the view just call this function:
#Url.Action('genPDF','GetFile');

SgmlReader and System.Xml Windows 8

I'm trying to convert HTML stream to XML using SgmlReader for further parsing. This conversion is part of an APP i'm developing for Windows 8 Store. Below is the method that convert Html to XML:-
public static void ConvertToXml(string webResponse)
{
StringWriter sWriter = new StringWriter();
XmlWriter xmlWriter = XmlWriter.Create(sWriter);
SgmlReader sgmlReader = new SgmlReader();
sgmlReader.DocType = "HTML";
sgmlReader.WhitespaceHandling = WhitespaceHandling.All;
sgmlReader.CaseFolding = CaseFolding.ToLower;
sgmlReader.InputStream = new StringReader(webResponse);
sgmlReader.IgnoreDtd = true;
while (!sgmlReader.EOF)
{
xmlWriter.WriteNode(sgmlReader, true);
}
xmlWriter.Flush();
XmlString = sWriter.ToString();
}
The sgmlReader.WhitespaceHandling = WhitespaceHandling.All; is the problem as Xml.WhitespaceHandling is not present. Is there anyother way to do this?
After alot of reading and testing/debugging just found that sgmlReader.WhitespaceHandling = WhitespaceHandling.All is not needed atleast in my case, as sgmlReader.WhitespaceHandling is set to All by default. However i removed sgmlReader.IgnoreDtd = true; and now my Xml file look Normal ;)
Hope this will help someone

Creating a SharePoint 2010 page via the client object model

I am attempting to create pages in a Sharepoint 2010 pages library via the client object model but I cannot find any examples on how to do it. I have tried two approaches:
The first is to treat the Pages library as a list and try to add a list item.
static void createPage(Web w, ClientContext ctx)
{
List pages = w.Lists.GetByTitle("Pages");
//ListItem page = pages.GetItemById(0);
ListItemCreationInformation lici = new ListItemCreationInformation();
ListItem li = pages.AddItem(lici);
li["Title"] = "hello";
li.Update();
ctx.ExecuteQuery();
}
As expected, this failed with the error message:
To add an item to a document library, use SPFileCollection.Add()
The next approach I tried was to add it as a file. The problem is that the FileCreationInformation object is expecting a byte array and I am not sure what to pass to it.
static void createPage(Web w, ClientContext ctx)
{
List pages = w.Lists.GetByTitle("Pages");
FileCreationInformation file = new FileCreationInformation();
file.Url = "testpage.aspx";
file.Content = new byte[0];
file.Overwrite = true;
ctx.Load(pages.RootFolder.Files.Add(file));
ctx.ExecuteQuery();
}
The piece of code above will add an item in the Pages library but opening the file brings up a blank page which I cannot edit. From reading various topics, I suspect that it may only be possible to add pages via server side code. Any thoughts?
Thanks
The problem is that the
FileCreationInformation object is
expecting a byte array and I am not
sure what to pass to it.
You could you whatever method you want to get the page contents into a string (read it from a file, create it using a StringBuilder, etc) and then convert the string to a byte array using
System.Text.Encoding.ASCII.GetBytes()
First of all, Publishing API is not supported via Client Side Object Model (CSOM) in SharePoint 2010. But you could consider the following approach that demonstrates how to create a publishing page using SharePoint 2010 CSOM.
How to create a publishing page using SharePoint 2010 CSOM
public static void CreatePublishingPage(ClientContext ctx, string listTitle, string pageName, string pageContent)
{
const string publishingPageTemplate = "<%# Page Inherits=\"Microsoft.SharePoint.Publishing.TemplateRedirectionPage,Microsoft.SharePoint.Publishing,Version=14.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c\" %> <%# Reference VirtualPath=\"~TemplatePageUrl\" %> <%# Reference VirtualPath=\"~masterurl/custom.master\" %>";
var pagesList = ctx.Web.Lists.GetByTitle(listTitle);
var fileInfo = new FileCreationInformation
{
Url = pageName,
Content = Encoding.UTF8.GetBytes(publishingPageTemplate),
Overwrite = true
};
var pageFile = pagesList.RootFolder.Files.Add(fileInfo);
var pageItem = pageFile.ListItemAllFields;
if (!ctx.Site.IsPropertyAvailable("ServerRelativeUrl"))
{
ctx.Load(ctx.Site);
ctx.ExecuteQuery();
}
pageItem["PublishingPageLayout"] = string.Format("{0}_catalogs/masterpage/ArticleLeft.aspx, ArticleLeft",ctx.Site.ServerRelativeUrl);
pageItem["PublishingPageContent"] = pageContent;
pageItem.Update();
ctx.ExecuteQuery();
}
Usage
using (var ctx = new ClientContext(url))
{
ctx.Credentials = new NetworkCredential("username", "password", "domain");
CreatePublishingPage(ctx, "Pages", "Greetings.aspx", "Welcome to SharePoint!");
}