Sharepoint 2013 Online: Attach file to sharepoint list item by sandbox
Download Project MstechsharingSPO
Hello everybody! Today i post this article with the my pleasure. i found the limitation of sandbox in upload and attach file to list item. It is System.IO namespace, the sandbox code can not read the Path.GetFileName (it inherit from System.IO), so we get filename's value is null.
I thought the solution: attach file using upload file of sharepoint. Moreover, we attach file when we add new item, so we must have the existing item. The final, i create the List "MstechsharingTemp" to store attachment file of each users login to system. When i click attach file, file will be saved into list "MstechsharingTemp" with existing item then when click Post (Save) button, i will store item into my "Mstechsharing" and copy attachment file from "MstechsharingTemp" list to my list "Mstechsharing".
Here is step by step i did:
Login to sharepoint online site (my case is SPO). Create new list MstechsharingTemp by go to Settings >> Add an app >> choose Custom list template
Continue create the next custom list "Mstechsharing"
Now we create Visual webpart in sandbox solution. we don't have available visual webpart for sandbox, so we must download "SpPowerTools_x86_enu_DeployVSWebpartAsSandbox". Setup it then wait some minutes we will see it by Open visual studio >> New project >> Empty Sharepoint Project with name is MstechsharingSPO
Deploy as Sandbox solution
Right click to project Mstechsharing >> New Item >> choose Visual Web Part (Sandboxed) with name is Mstechsharing
User interface look like
Open MstechsharingSPO.ascx
code here
<%@ Assembly Name="$SharePoint.Project.AssemblyFullName$" %>
<%@ Assembly Name="Microsoft.Web.CommandUI, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls"
Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Register TagPrefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages"
Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="Mstechsharing.ascx.cs"
Inherits="MstechsharingSPO.Mstechsharing.Mstechsharing" %>
<script type="text/javascript">
function callback() {
alert('document uploaded');
}
function openPopup() {
var elem = document.getElementById('<%= hdnURL.ClientID %>');
var options = {
url: elem.value,
title: 'Modal Dialog',
allowMaximize: false,
showClose: true,
width: 500,
height: 200,
dialogReturnValueCallback: callback
}
SP.UI.ModalDialog.showModalDialog(options);
return false;
}
</script>
Title:
<asp:TextBox ID="txtObject" runat="server" Width="300px"></asp:TextBox>
<br />
<input type="button" value="Attach file" id="btnAttachFile" runat="server" onclick="return SP.SOD.executeFunc('sp.ui.dialog.js', 'SP.UI.ModalDialog.showModalDialog', function () { openPopup(); });"
disabled="disabled" style="width: 128px" />
<input type="hidden" runat="server" id="hdnURL" />
<asp:Button ID="btnSave" runat="server" Text=" Save into Mstechsharing "
Width="170px" onclick="btnSave_Click" />
<asp:HiddenField ID="hdnItemID" runat="server" />
Open MstechsharingSPO.ascx.cs and Copy code into Page_Load.
Note: Change you ListId is very important
Code here
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
int itemID = DeleteExistingAttachments();
if (itemID == 0)
{
using (SPSite site = new SPSite(SPContext.Current.Web.Url.ToString()))
{
using (SPWeb web = site.OpenWeb())
{
web.AllowUnsafeUpdates = true;
SPList SPLData = web.Lists["MstechsharingTemp"];
SPListItem item = SPLData.Items.Add();
item.Update();
hdnItemID.Value = item.ID.ToString();
}
}
}
else
{
hdnItemID.Value = itemID.ToString();
}
}
string urlFormat = "/_layouts/AttachFile.aspx?ListId={0}&ItemID={1}";
string url = string.Format(urlFormat, "{E4D0A1CC-CEE0-4FF1-98DE-19B5D2AF943F}", hdnItemID.Value);
hdnURL.Value = url;
btnAttachFile.Disabled = false;
}
Continue copy 2 method DeleteExistingAttachments() and CopyAttachments below Page_Load
code here
private int DeleteExistingAttachments()
{
int itemId = 0;
// Follow the steps to delete list item attachment from your sharepoint list.
// Create new instance of site with your current application
using (SPSite site = new SPSite(SPContext.Current.Web.Url.ToString()))
{
// Create new web instance and open web for current application
using (SPWeb web = site.OpenWeb())
{
web.AllowUnsafeUpdates = true;
// Create new list object and get your list
SPList SPLData = web.Lists["MstechsharingTemp"];
// Create new query object to hold query which fetches list item of the list
SPQuery spMyQuery = new SPQuery();
// Assign query with value to it in ID field of the list item
spMyQuery.Query = "<Where><Eq><FieldRef Name='Author'/><Value Type='Integer'><UserID Type='Integer' /></Value></Eq></Where>";
SPListItemCollection collection = SPLData.GetItems(spMyQuery);
if (collection.Count > 0)
{
SPListItem listItem = collection[0];
itemId = Convert.ToInt32(listItem["ID"]);
if (listItem.Attachments.Count > 0)
{
foreach (string fileName in listItem.Attachments)
{
listItem.Attachments.Delete(fileName);
listItem.Update();
}
}
}
web.AllowUnsafeUpdates = false;
}
}
return itemId;
}
/// <summary>
///
/// </summary>
/// <param name="sourceItem"></param>
/// <param name="targetItem"></param>
private void CopyAttachments(SPListItem sourceItem, SPListItem targetItem)
{
try
{
//get the folder with the attachments for the source item
SPFolder sourceItemAttachmentsFolder =
sourceItem.Web.Folders["Lists"].SubFolders[sourceItem.ParentList.Title].SubFolders["Attachments"].SubFolders[sourceItem.ID.ToString()];
//Loop over the attachments, and add them to the target item
foreach (SPFile file in sourceItemAttachmentsFolder.Files)
{
byte[] binFile = file.OpenBinary();
targetItem.Attachments.AddNow(file.Name, binFile);
}
}
catch { }
finally
{
sourceItem.Web.Dispose();
}
}
Double click to button Save and paste this code
Code here
protected void btnSave_Click(object sender, EventArgs e)
{
try
{
using (SPSite spSite = new SPSite(SPContext.Current.Web.Url))
{
using (SPWeb spWeb = spSite.OpenWeb())
{
SPList spListTopics = spWeb.Lists["Mstechsharing"];
SPListItemCollection spListItemCollectionTopics = spListTopics.Items;
SPListItem item = spListItemCollectionTopics.Add();
item["Title"] = txtObject.Text;
item.Update();
SPList spListTemp = spWeb.Lists["MstechsharingTemp"];
SPListItem spListItemTemp = spListTemp.GetItemById(Convert.ToInt32(hdnItemID.Value));
SPListItem spListItemTopics = spListTopics.GetItemById(item.ID);
CopyAttachments(spListItemTemp, spListItemTopics);
DeleteExistingAttachments();
// Page.Response.Redirect(SPContext.Current.Web.Url);
}
}
}
catch (Exception ex)
{
Page.Response.Write(ex.Message);
}
}
All code
using System;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
namespace MstechsharingSPO.Mstechsharing
{
[ToolboxItem(false)]
public partial class Mstechsharing : System.Web.UI.WebControls.WebParts.WebPart
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
InitializeControl();
}
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
int itemID = DeleteExistingAttachments();
if (itemID == 0)
{
using (SPSite site = new SPSite(SPContext.Current.Web.Url.ToString()))
{
using (SPWeb web = site.OpenWeb())
{
web.AllowUnsafeUpdates = true;
SPList SPLData = web.Lists["MstechsharingTemp"];
SPListItem item = SPLData.Items.Add();
item.Update();
hdnItemID.Value = item.ID.ToString();
}
}
}
else
{
hdnItemID.Value = itemID.ToString();
}
}
string urlFormat = "/_layouts/AttachFile.aspx?ListId={0}&ItemID={1}";
string url = string.Format(urlFormat, "{E4D0A1CC-CEE0-4FF1-98DE-19B5D2AF943F}", hdnItemID.Value);
hdnURL.Value = url;
btnAttachFile.Disabled = false;
}
/// <summary>
///
/// </summary>
private int DeleteExistingAttachments()
{
int itemId = 0;
// Follow the steps to delete list item attachment from your sharepoint list.
// Create new instance of site with your current application
using (SPSite site = new SPSite(SPContext.Current.Web.Url.ToString()))
{
// Create new web instance and open web for current application
using (SPWeb web = site.OpenWeb())
{
web.AllowUnsafeUpdates = true;
// Create new list object and get your list
SPList SPLData = web.Lists["MstechsharingTemp"];
// Create new query object to hold query which fetches list item of the list
SPQuery spMyQuery = new SPQuery();
// Assign query with value to it in ID field of the list item
spMyQuery.Query = "<Where><Eq><FieldRef Name='Author'/><Value Type='Integer'><UserID Type='Integer' /></Value></Eq></Where>";
SPListItemCollection collection = SPLData.GetItems(spMyQuery);
if (collection.Count > 0)
{
SPListItem listItem = collection[0];
itemId = Convert.ToInt32(listItem["ID"]);
if (listItem.Attachments.Count > 0)
{
foreach (string fileName in listItem.Attachments)
{
listItem.Attachments.Delete(fileName);
listItem.Update();
}
}
}
web.AllowUnsafeUpdates = false;
}
}
return itemId;
}
/// <summary>
///
/// </summary>
/// <param name="sourceItem"></param>
/// <param name="targetItem"></param>
private void CopyAttachments(SPListItem sourceItem, SPListItem targetItem)
{
try
{
//get the folder with the attachments for the source item
SPFolder sourceItemAttachmentsFolder =
sourceItem.Web.Folders["Lists"].SubFolders[sourceItem.ParentList.Title].SubFolders["Attachments"].SubFolders[sourceItem.ID.ToString()];
//Loop over the attachments, and add them to the target item
foreach (SPFile file in sourceItemAttachmentsFolder.Files)
{
byte[] binFile = file.OpenBinary();
targetItem.Attachments.AddNow(file.Name, binFile);
}
}
catch { }
finally
{
sourceItem.Web.Dispose();
}
}
protected void btnSave_Click(object sender, EventArgs e)
{
try
{
using (SPSite spSite = new SPSite(SPContext.Current.Web.Url))
{
using (SPWeb spWeb = spSite.OpenWeb())
{
SPList spListTopics = spWeb.Lists["Mstechsharing"];
SPListItemCollection spListItemCollectionTopics = spListTopics.Items;
SPListItem item = spListItemCollectionTopics.Add();
item["Title"] = txtObject.Text;
item.Update();
SPList spListTemp = spWeb.Lists["MstechsharingTemp"];
SPListItem spListItemTemp = spListTemp.GetItemById(Convert.ToInt32(hdnItemID.Value));
SPListItem spListItemTopics = spListTopics.GetItemById(item.ID);
CopyAttachments(spListItemTemp, spListItemTopics);
DeleteExistingAttachments();
Page.Response.Redirect(SPContext.Current.Web.Url);
}
}
}
catch (Exception ex)
{
Page.Response.Write(ex.Message);
}
}
}
}
Now we build and package project then Open your site and go to Settings >> Site setting >> at Web Designer Galleries category click to Solutions >> Upload and active wsp file
Open MstechsharingTemp we don't see any item
Add webpart "Mstechsharing Title"to page
Go back MstechsharingTemp we see an item was created with current user in page_load
Note: we check user is existing or not, if not exist we create new, else we delete all attachment file into existing item of current user login. So, make sure we f5 the item will not create
Now we upload file
Uploaded successful.
Go back to MstechsharingTemp we see file was attached to list item
Continue add new item and click button Save
Go back Mstechsharing list we see item and attachment file is created
Login to another user, we will see item was created in MstechsharingTemp list
So, you can create item and attach file similar at above steps.
Thanks.