SharePointCommunity
Die deutschsprachige Community für SharePoint, Microsoft 365, Teams, Yammer und mit Azure

Sponsored by

Willkommen im Forum Archiv.
Einträge sind hier nicht mehr möglich, aber der Bestand von 12 Jahren SharePoint-Wissen ist hier recherchierbar.




C# - Listen Attachment auslesen

Unbeantwortet Dieser Beitrag hat 20 Antworten

Ohne Rang
53 Beiträge
Jan D erstellt 15 Nov. 2010 15:27
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Hallo zusammen,

ich würde gerne eine TXT-Datei, die ich in einer Liste als Attachment angehängt habe auslesen.

 

Die Artikel, welche ich bei MSDN finde gehen jedoch davon aus, dass ich den Dateinamen kenne. Besteht auch eine Möglichkeit auf das Attachment zuzugreifen, wenn der Name nicht bekannt ist?

 

Mit meinem bisherigen Ansatz kann ich leider nur den Pfad, jedoch nicht die Datei sehen:

 

 

SPContext context = SPContext.Current;
SPSite site = context.Site;
SPWeb web = context.Web;

SPSite oSiteCollection = SPContext.Current.Site;
SPWebCollection collWebsites = oSiteCollection.AllWebs;
SPWeb oWebsite = collWebsites[web.Title.ToString()];
SPList oList = oWebsite.Lists["test"];
SPListItemCollection collItem = oList.Items;
SPListItem oListItem = collItem[0];



SPAttachmentCollection attachments = oListItem.Attachments;

 

Könnte mir da vielleicht jmd einen Hinweis geben?

 

Lg

Jan

 

Alle Antworten

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 15 Nov. 2010 15:46
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Jetzt hast Du doch die Collection mit den Anhängen. Die kannst Du z.B. mit foreach durchgehen. Oder per Indexer auf die Anhänge zugreifen.

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
53 Beiträge
Jan D Als Antwort am 15 Nov. 2010 16:15
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Da hast Du vollkommen Recht :)

 

Mein Problem an dieser Stelle:

 

SPAttachmentCollection attachments = oListItem.Attachments;

foreach(SPFile oFile in attachments){
;
}

 

==> Sharepoint beschwert sich, dass oFile nicht auf den Datentypen SPFile passt.

 

Könnte mir vielleicht jmd sagen, welcher Datentyp der richtige ist, oder wie ich die attachments korrekt aufrufe?

 

Danke und LG

 

Jan

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 15 Nov. 2010 16:33
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

foreach (SPAttachment ...

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
53 Beiträge
Jan D Als Antwort am 15 Nov. 2010 16:43
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

So etwas in dieser Art habe ich schon schon probiert - funktioniert leider nicht :(

 

Das einzige SP-Objekt, was den Attachments ein wenig ähnlich sieht ist "SPAttachmentCollection".

 

Beste Grüße

 

Jan

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 15 Nov. 2010 17:28
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Tut mir leid, da war ich zu voreilig. Das passiert, wenn man seine Angaben nicht nachprüft, sondern einfach aus dem (schlechten) Gedächtnis schreibt ...

In der SPAttachmentCollection sind nur Strings für die Dateinamen, mit denen man nicht wirklich was anfängt.

An die eigentlichen Dateien kommst Du so:
hole Dir den Ornder, in dem die Anhänge zu einem Element liegen
SPFolder folder = listItem.ParentList.RootFolder.
                  SubFolders["Attachments".SubFolders[
                  listItem.ID.ToString()];
if (folder != null) {
foreach (SPFile file in folder.Files) { ... }
}

Das ganze mußt Du evtl. innerhalb von SPSecurity.RunWithElevatedPriviledges ausführen.

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
53 Beiträge
Jan D Als Antwort am 16 Nov. 2010 15:35
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Vielen Dank für Deine schnelle und ausführliche Antwort!

 

Code, wie Du ihn gepostet hast habe ich ebenfalls auf der MSDN-Seite finden können. Leider erschließt sich mir jedoch eine Sache nicht ganz:

 

Den folgende Code kann problemlos ausgeführt werden:

 

SPAttachmentCollection attachments = oListItem.Attachments;
SPFolder folder = oListItem.ParentList.RootFolder.SubFolders["Attachments"].SubFolders[oListItem.ID.ToString()];

if (folder != null) {
   foreach (SPFile file in folder.Files) {
      Label1.Text = "Success!";
   }
}

 

 

Möchte ich nun aber in der forach-Schleife auf das SPFile Objekt über "file.Title.ToString();" zugreifen, erhalte ich die folgende Fehlermeldung:

 

"NullReferenceException wurde nicht von Benutzercode behandelt."

"Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt."

 

Mein Problem besteht also leider weiterhin darin, dass ich scheinbar nicht auf die Datei zugreifen kann. Über Ideen und anregungen würde ich mich aus diesem Grund sehr freuen.

 

Mit besten Grüßen

Jan

Ohne Rang
1714 Beiträge
C.Kaiser Als Antwort am 16 Nov. 2010 15:50
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Also ich hab die Attachments damals in einen Memory Stream geladen und per Email verschickt.

Code:

//Download the content of the file with a WebClient
WebClient webClient = new WebClient();

 //Supply the WebClient with the network credentials of our user
webClient.Credentials = CredentialCache.DefaultNetworkCredentials;

SPAttachmentCollection attachments = item.Attachments;

//SPFileCollection subsubFile = subroolFolder.Files; 
foreach (string file in attachments)
 {
   //Download the byte array of the file
   byte[] data = webClient.DownloadData(item.Attachments.UrlPrefix + file.ToString());
   MemoryStream memoryStreamOfFile = new MemoryStream(data);
   mailMessage.Attachments.Add(new System.Net.Mail.Attachment(memoryStreamOfFile, file.ToString()));
 }

Eventuell hilft dir das weiter, halt ohne Email verschicken.

Beste Grüße,
Christian

http://www.sharepoint-rhein-ruhr.de

Ohne Rang
53 Beiträge
Jan D Als Antwort am 17 Nov. 2010 10:54
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Danke Euch Beiden für die schnellen und guten Antworten.

 

Dein Code C.Kaiser war für mein Verständnis der Thematik ausgesprochen hilfreich!

 

Lg

Jan

Ohne Rang
53 Beiträge
Jan D Als Antwort am 17 Nov. 2010 11:13
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Eine Frage stelle ich mir jedoch an dieser Stelle noch:

 

Angenommen der Fall, dass ein Event-Receiver ausgelöst wird, sobald ein Listenitem hinzugefügt wird, so soll meine Funktion die in diesem Event-Receiver steht das neu hinzu gefügte (also das letzte Listenelement) ausgeben.

Im Moment umgehe ich das Problem durch relativ inperformanten Code:

 

foreach (SPListItem oListItem in collItem){
   SPAttachmentCollection attachments = oListItem.Attachments;
   foreach(string file in attachments){
        Label1.Text = "Last Item: " + attachments.UrlPrefix.ToString() + file.ToString();
     }
}

Wenn an dieser Stelle jmd. eine Bessere Idee hat, wie ich das neue Listenitem (also collItem[integer des letzten Listenelements] ) performanter angeben kann würde ich mich wirklich freuen.

 

Lg

Jan

Ohne Rang
1714 Beiträge
C.Kaiser Als Antwort am 17 Nov. 2010 11:37
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

hmmmm geht das nicht ungefähr so (ohne es jetzt getestet zu haben):

SPListItemCollection col = SPContext.Current.Web.List("Liste").Items;
SPItem item = col.GetItemById(col.Count -1);

Beste Grüße,
Christian

http://www.sharepoint-rhein-ruhr.de

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 17 Nov. 2010 11:44
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

@Christian: das ist extrem unsicher. Die letzte ID muß nicht zwangsweise der Anzahl Elemente entsprechen. Was ist, wenn welche gelöscht wurden?

@Jan: wenn Dein Code doch innerhalb eines EventReceivers läuft, dann hast Du Zugriff auf das aktuelle Element über die SPItemEventProperties.

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
1714 Beiträge
C.Kaiser Als Antwort am 17 Nov. 2010 11:53
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Hallo Andi,

ja dachte ich mir auch, aber der ToolTip von GetItemByID ist dann etwas uneindeutig oder ich versteh es falsch:

Returns the item with the specified integer ID from the collection

Ist damit die ID des Listenitems gemeint, die ja durchaus nicht fortlaufend nummeriert ist, oder eine interne ID der Collection, die ja bei 0 anfängt und bei n aufhört. Irgendwie muss man ja das Array ansprechen können (bzw. das Array muss sich ja interne IDs merken) oder sehe ich das falsch?

Beste Grüße,
Christian

http://www.sharepoint-rhein-ruhr.de

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 17 Nov. 2010 12:12
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

GetItemById bezieht sich auf die ID des Elements, die man sich z.B. auch in einer Ansicht anzeigen lassen kann (beginnt immer bei eins). Das andere wäre der Index, also die laufende Nummer beginnend bei null. Darauf kann man über den Indexer der SPListItemCollection zugreifen.

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
1714 Beiträge
C.Kaiser Als Antwort am 17 Nov. 2010 12:34
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Ja da war was, dann ersetz ich mal die Aussage von oben

SPItem item =  col.GetItemByID(col.Count -1);

durch

SPItem item = col[col.Count -1];

Beste Grüße,
Christian

http://www.sharepoint-rhein-ruhr.de

Ohne Rang
53 Beiträge
Jan D Als Antwort am 17 Nov. 2010 13:29
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

@Christian: Danke für Deine Antwort!

 

@ Andi Fandrich:

Ebenfalls Danke für Deine Antwort! Nur leider erkenne ich nicht, wie ich via SPItemEventProperties auf das eigentliche ListItem zugreifen soll.

Die Liste mit ID, Listenname usw. kann ich zwar über die SPItemEventProperties abrufen - jedoch bleibt z.B. die ListItemID leider bei "null". Hier der Code:

 

public override void ItemAdding(SPItemEventProperties properties)
  {
  string hallo = properties.ListTitle.ToString(); // funktioniert
string id = properties.ListItemId.ToString(); // gibt null zurück
  base.ItemAdding(properties);
}

Danke und mit besten Grüßen

Jan

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 17 Nov. 2010 13:41
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Beim Ereignis ItemAdding steht die ID noch nicht fest, weil das Element ja noch nicht gespeichert wurde. Bei allen anderen Ereignissen stimmt sie aber. Außerdem kannst Du über properties.ListItem auf das Element selbst zugreifen (und daran auch Änderungen vornehmen).

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
53 Beiträge
Jan D Als Antwort am 17 Nov. 2010 14:14
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Mit dem properties.ListItem habe ich ebenfalls schon herumgespielt. Allerdings erschließt sich mir hier eine Sache nicht:

Folgender Quellcode aus dem Receiver:

 

public override void ItemAdding(SPItemEventProperties properties)
{
  SPListItem oListItem = properties.ListItem;
SPAttachmentCollection attachments = oListItem.Attachments;
 }

 

...bedeutet nach meinem Verständnis, dass ich ein SPListItem erzeuge, dass über die Attribute und Funktionen eines jeden Objekts "SPListItem" verfügt.

 

Darum frage ich mich: Warum erhalte ich an dieser Stelle eine NULL-Exception? Und wird das Objekt etwa ebenfalls erst nach dem Ausführen dieser Funktion initialisiert? Und wenn ja: Wie greife ich dann weiterhin darauf zu?

 

Ich bin gerade echt ein wenig verwirrt ...

 

Lg

Jan

 

P.S.

Danke Andi Fandrich für deine Ausdauer :)

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 17 Nov. 2010 14:25
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Sorry für die Fehlinformation. properties.ListItem ist bei ItemAdding auch nicht belegt. Ich denke, Du wirst in diesem Erignis keine Chance haben an die Anhänge ranzukommen. Falls Du nichts am Element selbst verändern möchtest, kannst Du aber auf ItemAdded ausweichen, da funktioniert es dann, weil das Element schon gespeichert ist und auch eine ID hat.

Jetzt weiß ich wenigsten, für wen ich Blogbeiträge erstelle - dort habe ich nämlich nachgeschaut ;-)
http://blogs.evocom.de/af/archive/2010/10/12/beforeproperties-und-afterproperties-bei-verschiedenen-ereignissen.aspx

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
53 Beiträge
Jan D Als Antwort am 17 Nov. 2010 15:02
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Es funktioniert perfekt!

 

Letzte Frage:

Der Event-Receiver soll nur bei einer benutzerdefinierten Liste aktiv werden. Dies habe ich nun mit der IF-Abfrage:

 

if (properitites.ListTitle == "foo") {
   ;
}

 

Könnte mir vielleicht noch jemand sagen, ob es hier einen dauerhaft performanteren Weg gibt?

 

Lg

Jan

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 17 Nov. 2010 15:06
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Das ist doch schon ziemlich performant. Die Abfrage des Titels ist mit Sicherheit um ein vielfaches schneller, als der Rest des Codes und deshalb zu vernachlässigen.

Ansonsten: den Eventhandler einfach nur an die gewünschte Liste hängen. Entweder per Programmcode oder samt Liste als Feature verteilen.

Viele Grüße
Andi
af @ evocom de
Blog