AsyncFileUpload and repeater - asp.net

I have an asyncfileupload control and a repeater that I would like to use to show list of added files. On FileUploadedComplete event I add the new file's name and size to a data table and use it to bind the repeater. I can select a file and add it (SaveAs()), add the info to data table (I can see it is there) but after calling repeater's databind() nothing happens, can't see the file data.
This is what I have (watered down version):
<asp:UpdatePanel runat="server" ID="upnlFU">
<ContentTemplate>
<ajaxToolkit:AsyncFileUpload
runat="server"
ID="fuAttchedDocs"
ThrobberID="myThrobber"
UploaderStyle="Modern"
onuploadedcomplete="fuAttchedDocs_UploadedComplete"
onuploadedfileerror="fuAttchedDocs_UploadedFileError" />
<asp:Repeater runat="server" ID="rptAttachments">
<HeaderTemplate>
<table>
<tr>
<td>File Name</td>
<td>File Size</td>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td><%# Eval("FileName")%></td>
<td><%# Eval("FileSize")%></td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
</ContentTemplate>
</asp:UpdatePanel>
Code behind:
DataTable dtAttachments;
protected void Page_Load(object sender, EventArgs e)
if (!Page.IsPostBack)
{
dtAttachments = new DataTable();
dtAttachments.Columns.Add("FileName", Type.GetType("System.String"));
dtAttachments.Columns.Add("FileSize", Type.GetType("System.Int32"));
dtAttachments.AcceptChanges();
}
else
{
dtAttachments = (DataTable)ViewState["Attachments"];
}
BindAndSaveAttachmentData();
}
void BindAndSaveAttachmentData()
{
ViewState["Attachments"] = dtAttachments;
rptAttachments.DataSource = dtAttachments;
rptAttachments.DataBind();
}
protected void fuAttchedDocs_UploadedComplete(object sender, AsyncFileUploadEventArgs e)
{
string sFileName = fuAttchedDocs.FileName;
string sFileSize = e.FileSize;
fuAttchedDocs.SaveAs(FilePath.TEMP_FOLDER + sFileName); // Saving to d:\blah\yada temporary folder
dtAttachments.Rows.Add(new object[] { sFileName, int.Parse(sFileSize) });
BindAndSaveAttachmentData();
}
Both file upload and repeater are inside an update panel.

Related

Repeater causes postback of the whole page even if it's inside an update panel

I have an user control that contains an update panel with a repeater. The repeater has a button used to delete records.
The problem is when I press the delete button, and a record from the repeater gets deleted, a postback on the whole page is triggered. From my understanding, only the section inside the update panel should refresh.
I should also mention that on my master page I have a script manager with the property "EnablePartialRendering" set to true.
Can someone help me with this problem? Thanks in advance.
ASP file:
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="ActivityFiles.ascx.cs" Inherits="Training.User_Controls.ActivityFiles" %>
<asp:Repeater ID="FilesRepeater" runat="server">
<HeaderTemplate>
<table class="table table-bordered">
<tr>
<td><b>Name</b></td>
<td><b>Description</b></td>
<td><b>Actions</b></td>
</tr>
</HeaderTemplate>
<ItemTemplate>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<tr>
<td><%# Eval("Name")%></td>
<td><%# Eval("Description")%></td>
<td>
<asp:LinkButton ID="DownloadFile" runat="server" OnClick="DownloadFile_Click" Font-Size="Large"
file-path='<%# Eval("Url")%>'>
<span class="glyphicon glyphicon-floppy-disk text-info" aria-hidden="true"></span>
</asp:LinkButton>
<asp:LinkButton ID="DeleteFile" runat="server" OnClick="DeleteFile_Click" Font-Size="Large"
file-id='<%# Eval("Id") %>'
file-path='<%# Eval("Url") %>'>
<span class="glyphicon glyphicon-trash text-danger" aria-hidden="true"></span>
</asp:LinkButton>
</td>
</tr>
</ContentTemplate>
</asp:UpdatePanel>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
.cs File:
protected void Page_Load(object sender, EventArgs e)
{
activityId = (int)Context.Items["activityId"];
if ( ! IsPostBack && Visible)
{
if (activityId != 0)
{
LoadFiles();
}
}
}
private void LoadFiles()
{
DataTable files = DatabaseHelper.SelectAsDatatable(FilesQueries.GET_ACTIVITY_FILES, new Dictionary<string, object> {
{ "activityId", activityId }
});
FilesRepeater.DataSource = files;
FilesRepeater.DataBind();
if (files.Rows.Count == 0)
{
FilesRepeater.Visible = false;
NoRecords.Visible = true;
}
}
protected void DeleteFile_Click(object sender, EventArgs e)
{
// TODO: modify this function to work only with the fild id
LinkButton deleteButton = (LinkButton)sender;
string fileId = deleteButton.Attributes["file-id"];
string filePath = deleteButton.Attributes["file-path"];
DatabaseHelper.ExecuteNonQuery(FilesQueries.DELETE_FILE, new Dictionary<string, Object>() {
{ "#fileId",fileId },
});
//delete file from disk
string path = Server.MapPath(filePath);
FileInfo file = new FileInfo(path);
if (file.Exists)
{
file.Delete();
}
LoadFiles();
}
Found the solution on another stackoverflow post (See Eugene S answer)
You have to manually add you control to Script Manager. You should do that inside File Repeater's Item created event. Good luck.

When i click button in gridview it does't work

I am a beginner of Asp.net, making l small project but having big problems, :) ...
Right now I have a situation, I used gridview to retrieve data from Access database and I done that, I added buttons in grid view. When I click on button the following error comes
Server Error in '/E Shop' Application. Invalid postback or callback argument. Event validation is enabled using in configuration or <%# Page
EnableEventValidation="true" %> in a page. For security purposes,
this feature verifies that arguments to postback or callback events
originate from the server control that originally rendered them. If
the data is valid and expected, use the
ClientScriptManager.RegisterForEventValidation method in order to
register the postback or callback data for validation.
HTML
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
Width= "100%" CellPadding="3">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<table class="style17" width="100%" border=" 0">
<tr>
<td height="100%" width="25%">
<asp:Image ID="Image6" runat="server" Height="144px"
ImageUrl='<%# "data:image/jpg;base64, " + Convert.ToBase64String((byte[]) Eval("Picture")) %>'
Width="158px" BorderColor="Black" BorderStyle="Inset" BorderWidth="1px" />
</td>
<td align="center" height="100%" width="75%">
<table align="right" class="style17">
<tr>
<td align="left">
<asp:Label ID="Label7" runat="server" style="font-size: 15pt; color: #0000FF"
Text='<%# Bind("Title") %>'></asp:Label>
</td>
<td>
<asp:Label ID="Label6" runat="server" Text='<%# Bind("Brand") %>'
CssClass="style18" Font-Size="15pt"></asp:Label>
</td>
<td align="right">
<asp:ImageButton ID="ImageButton1" runat="server" Height="51px"
ImageUrl="~/Images/orange_addtocart-trans.png" Width="159px"
onclick="ImageButton1_Click" />
</td>
</tr>
<tr>
<td align="left">
<strong>Rs:</strong><asp:Label ID="Label2" runat="server"
Text='<%# Bind("Price") %>' CssClass="style18" Font-Size="15pt"></asp:Label>
</td>
<td>
<asp:Label ID="Label3" runat="server" Text='<%# Bind("Color") %>'
CssClass="style18" Font-Size="15pt"></asp:Label>
</td>
<td align="right">
<asp:ImageButton ID="ImageButton2" runat="server" Height="51px"
ImageUrl="~/Images/orange_addtocart-trans.png" Width="159px"
onclick="ImageButton2_Click" />
</td>
</tr>
<tr>
<td align="left">
<asp:Label ID="Label4" runat="server" Text='<%# Bind("Condition") %>'
CssClass="style18" Font-Size="15pt"></asp:Label>
</td>
<td>
<asp:Label ID="Label5" runat="server" Text='<%# Bind("Material") %>'
CssClass="style18" Font-Size="15pt"></asp:Label>
</td>
<td>
</td>
</tr>
</table>
</td>
</tr>
</table>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<EmptyDataTemplate>
<table class="style17">
<tr>
<td align="left" height="100%" width="30%">
<asp:Image ID="Image5" runat="server" Height="144px"
ImageUrl='<%# "data:image/jpg;base64, " + Convert.ToBase64String((byte[]) Eval("Picture")) %>'
Width="193px" />
</td>
<td>
</td>
</tr>
</table>
</EmptyDataTemplate>
</asp:GridView>
c#
public partial class Shirts : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
OleDbConnection con = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source =" + Server.MapPath("~\\App_Data\\Products.mdb"));
con.Open();
OleDbCommand cmd = new OleDbCommand();
cmd.CommandText = "select * from Shirts";
cmd.Connection = con;
OleDbDataAdapter Adaptor = new OleDbDataAdapter(cmd);
DataSet ds = new DataSet();
Adaptor.Fill(ds);
GridView1.DataSource = ds;
GridView1.DataBind();
con.Close();
}
protected void ImageButton1_Click(object sender, ImageClickEventArgs e)
{
// Session["Title"] = "Label7.Text";
}
protected void ImageButton2_Click(object sender, ImageClickEventArgs e)
{
// Response.Redirect("Cart.aspx");
}
protected void Button1_Click(object sender, EventArgs e)
{
// Response.Redirect("Cart.aspx");
}
protected void Button2_Click(object sender, EventArgs e)
{
Response.Redirect("Cart.aspx");
}
}
Please Help me to make the buttons work
Thanks in Advance
You can't create an event handler for controls present in Gridview control like this, because they are not static and they repeat for each item coming from the datasource for the Gridview.
When a button is clicked in Gridview, RowCommand event is raised, so you need to write your logic in this event by identifying your control, something like this:-
To identify each control individually in Gridview RowCommand event, you need to add CommandName & CommandArgument properties to your control:-
<asp:ImageButton ID="ImageButton1" runat="server" Height="51px" ImageUrl="~/Images/orange_addtocart-trans.png" Width="159px" OnCommand="Foo" CommandArgument="<%# ((GridViewRow) Container).RowIndex %>"/>
Here, CommandName is used to identify the control which raised the event and CommandArgument is used to identify the current row.
Finally, you can read them in code behind like this:-
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Foo")
{
int index = Convert.ToInt32(e.CommandArgument);
GridViewRow row = GridView1.Rows[index];
// Add you logic here
}
}
I follow the Example you provide, i set commandname and commandargument properties and in Rowcommand event i try to same steps like example but again i got that Error
Server Error in '/E Shop' Application.
Invalid postback or callback argument. Event validation is enabled using in configuration or <%# Page EnableEventValidation="true" %> in a page. For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them. If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.
Source:
<asp:ImageButton ID="ImageButton1" runat="server" Height="51px"
commandname="Foo" CommandArgument="<%# ((GridViewRow) Container).RowIndex %>"
ImageUrl="~/Images/orange_addtocart-trans.png" Width="159px"
onclick="ImageButton1_Click2"/>
C#
public partial class raff : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
OleDbConnection con = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source =" + Server.MapPath("~\\App_Data\\Products.mdb"));
con.Open();
OleDbCommand cmd = new OleDbCommand();
cmd.CommandText = "select * from Shirts";
cmd.Connection = con;
OleDbDataAdapter Adaptor = new OleDbDataAdapter(cmd);
DataSet ds = new DataSet();
Adaptor.Fill(ds);
GridView1.DataSource = ds;
GridView1.DataBind();
con.Close();
}
protected void GridView1_RowCommand(object sender,
GridViewCommandEventArgs e)
{
if (e.CommandName == "AddToCart")
{
// Retrieve the row index stored in the
// CommandArgument property.
int index = Convert.ToInt32(e.CommandArgument);
// Retrieve the row that contains the button
// from the Rows collection.
GridViewRow row = GridView1.Rows[index];
// Add code here to add the item to the shopping cart.
Response.Redirect("Cart.aspx");
}
}
protected void ImageButton1_Click(object sender, ImageClickEventArgs e)
{
// Session["Title"] = "Label7.Text";
}
protected void ImageButton2_Click(object sender, ImageClickEventArgs e)
{
// Response.Redirect("Cart.aspx");
}
protected void Button1_Click(object sender, EventArgs e)
{
// Response.Redirect("Cart.aspx");
}
protected void Button2_Click(object sender, EventArgs e)
{
// Response.Redirect("Cart.aspx");
}
protected void Button1_Click1(object sender, EventArgs e)
{
Response.Redirect("Cart.aspx");
}

wont display drop down

<form>
<asp:Repeater id="rptComments" runat="server">
<HeaderTemplate>
<table class="detailstable FadeOutOnEdit">
<tr>
<th style="width:200px;">Answers</th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<th style="width:200px;"><asp:DropDownList ID="dropDownForChecklistAnswers" runat="server" /></th>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
<asp:Button id="button" text="Submit" OnClick="Page_Load" runat="server" />
</FooterTemplate>
</asp:Repeater>
</form>
Code Behind:
List<Checklist_Record_Choice> CLRC =
(from choice in db.Checklist_Record_Choices
select choice).ToList();
dropDownForChecklistAnswers.DataSource = CLRC;
DropDownList1.DataTextField = Text;//Text being the name of column2 in the table (which contains yes, no, n/a)
dropDownForChecklistAnswers.DataBind();
ERROR: dropDownForChecklistAnswers does not exist in the current context???
please advise
EDIT;
thanks for reply. I have
public void OnReptDataBound(object sender, RepeaterItemEventArgs e)
{
ClarkeDBDataContext db1 = new ClarkeDBDataContext();
List<string> CLRC =
(from choice in db1.Checklist_Record_Choices
select choice.Text).ToList();
DropDownList ddl = (DropDownList)e.Item.FindControl("dropDownForChecklistAnswers");
ddl.DataSource = CLRC;
}
but DropDownList ddl is coming back as object ref not set to instance of an object...why is it null??
You need to use FindControl to access a control which is part of a Repeater's template.
Subscribe to the OnItemDataBound of the Repeater (set the attribute OnItemDataBound="OnReptDataBound")
And then in your code behind do the following
void OnReptDataBound(object sender, RepeaterItemEventArgs e)
{
if(e.Item.ItemType == ListItemType.Item)
{
DropDownList ddl = (DropDownList )e.Item.FindControl("dropDownForChecklistAnswers");
ddl.DataSource = ....

ListView fields not getting posted

I know I've done something like this before, but I have no idea why it isn't working now. I have a ListView with some textboxes. I want to read the text out of those boxes when I click a button (linkbutton, whatever).
<asp:ListView runat="server" ID="lv_bar" EnableViewState="true">
<LayoutTemplate>
<table>
<tr>
<th>Foo</th>
</tr>
<tr runat="server" id="itemPlaceholder"></tr>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td><asp:LinkButton ID="lb_delete" CausesValidation="false" runat="server" Text="Del" /></td>
<td><asp:TextBox id="txt_foo" runat="server" /></td>
</tr>
</ItemTemplate>
</asp:ListView>
<asp:LinkButton ID="lb_add" CausesValidation="false" runat="server" Text="Add" />
And then here's the relevant code-behind stuff:
protected void Page_Load(object sender, EventArgs e)
{
lb_chapter_add.Click += lb_chapter_add_Click;
if (!IsPostBack)
{
lv_chapters.DataSource = new List<Foo>() { new Foo() { Name = "harbl"} };
lv_chapters.DataBind();
}
}
void lb_add_Click(object sender, EventArgs e)
{
foreach (ListViewDataItem item in lv_bar.Items)
{
var txt_foo = (TextBox)item.FindControl("txt_foo");
Response.Write("foo: " + txt_foo.Text);
}
Response.Write("<br />the end");
Response.End();
}
But what I see when I enter some text into txt_foo and click lb_add is just "the end". What am I doing wrong here?
The problem it that you are using a a non persistent object as DataSource.
Due to clicking the button, you generate a postback and lv_chapters does not contain any items. Set a breakpoint in the line where the foreach is and you will see that lv_chapters.Items in null, or that it's Count property returns 0.

Asp.Net ListView how to delete a row without deleting from datasource

Through CommandName="Delete" I try to delete a line from the ListView control but not from the datasource. On Pressing Delete I expect the webpage to reload and show me the updated ListView(with one line deleted). But nothing changes, the ListView will display the same content after pressing Delete. What do I do wrong?
<asp:ListView ID="ListView1"
DataSourceID="XmlDataSource1"
ItemContainerId="DataSection"
runat="server">
<LayoutTemplate>
<h3>Protocols to Upload...</h3>
<table border=0 style="background-color:#9C9EFF; width: 100%;">
<tr align=left>
<th>Region/Exam/Program</th><th>Protocol</th><th>Position</th>
</tr>
<asp:PlaceHolder ID="itemPlaceholder" runat="server"></asp:PlaceHolder>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td><%#XPath("Location/Path")%></td>
<td><%#XPath("Location/Name")%></td>
<td><%#XPath("Location/Position")%></td>
<td style="width:40px">
<asp:LinkButton ID="SelectCategoryButton" runat="server" Text="Select" CommandName="Select"/>
</td>
</tr>
</ItemTemplate>
<SelectedItemTemplate>
<tr id="Tr1" runat="server" style="background-color:#F7F3FF">
<td><%#XPath("Location/Path")%></td>
<td><%#XPath("Location/Name")%></td>
<td><%#XPath("Location/Position")%></td>
<td style="width:40px">
<asp:LinkButton runat="server" ID="SelectCategoryButton" Text="Delete" CommandName="Delete" />
</td>
</tr>
</SelectedItemTemplate>
<%-- <ItemSeparatorTemplate>
<div style="height: 0px;border-top:dashed 1px #ff0000"></div>
</ItemSeparatorTemplate>--%>
</asp:ListView>
<asp:XmlDataSource ID="XmlDataSource1" XPath="HttpRequestBO/ProtocolsDTO/ProtocolDTO" runat="server"
DataFile="~/HttpRequestBo.Sample.xml"></asp:XmlDataSource>
And this is the code behind:
protected void Page_Load(object sender, EventArgs e)
{
}
protected void ListView1_OnItemDeleted(Object sender, ListViewDeletedEventArgs e)
{
if (e.Exception != null)
{
e.ExceptionHandled = true;
}
}
protected void ListView1_OnItemCommand(object sender, ListViewCommandEventArgs e)
{
if (String.Equals(e.CommandName, "Delete"))
{
ListViewDataItem dataItem = (ListViewDataItem)e.Item;
ListView1.Items.Remove(dataItem);
}
}
If I don't use the e.ExceptionHandled = true;, after pressing the Delete link the web page will come up with a "Specified method is not supported." message. Why?
If I use the above mentioned line, then the page refreshes but I can still see all original lines (although on debugging I can see that the ListVieItem collection now only contains an item less.)
It's because of the DatasourceID parameter, which binds at every single postback on the original file.
What you should do is to bind your list on the first page load only. The delete button will work as you expect then.
--- after comments.
OK.
In fact, the Delete command would work if you had defined the Delete method on your datasource. Since that's not what you want, you must define the ItemCommand event handler
and tell it to remove the ListViewItem that issued the event.
protected void yourListView_OnItemCommand(object sender, ListViewCommandEventArgs e)
{
if (String.Equals(e.CommandName, "Delete"))
{
ListViewDataItem dataItem = (ListViewDataItem)e.Item;
yourListView.Items.Remove(dataItem);
}
}
It will do so without touching the XML file beneath. Do not databind against it, else the "deleted" row will appear again.

Resources