How to create custom control of existing user control - c#

I have created one user control for multiple file upload ,
i need to create its custom control so that I can have a dll of that control.
What are the ways that I can do this?
usercontrol.ascx
<script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
<script src="Scripts/jquery.MultiFile.pack.js" type="text/javascript"></script>
<div><%-- accept attribute can be used like accept="png|jpg"--%>
Multiple File Upload<br />
<asp:FileUpload ID="FileUpload10" runat="server" class="multi" accept="" />
<asp:Button ID="Button3" runat="server" Text="Submit" OnClick="jQueryUploadFiles" />
<br />
<asp:Label ID="lblMessage" runat="server" EnableViewState="false" ForeColor="Green" />
<br />
<asp:Label ID="lblError" runat="server" EnableViewState="false" ForeColor="Red" />
</div>
usercontrol.ascx.cs
private void FileUploadUsingJQuerySelectionMethod()
{
// check if file has been selected
HttpFileCollection files = Request.Files;
for (int i = 0; i < files.Count; i++)
{
HttpPostedFile file = files[i];
if (file.ContentLength > 0)
{
string path = ConfigurationManager.AppSettings["FilePath"];
string fileName = Path.GetFileName(file.FileName);
// now save the file to the disk
file.SaveAs(path + fileName);
lblMessage.Text += "File : <b>" + fileName + "</b> uploaded successfully !<br />";
}
}
}
I tried like following:
public class MultipleFileUpload : WebControl
{
#region declare controls here
Label lblMessage;
Label lblError;
FileUpload FileUpload10;
Button btnUpload;
#endregion
[Bindable(true)]
[Category("Appearance")]
[DefaultValue("")]
[Localizable(true)]
public string FilePath
{// prop to get filepath
get
{
String s = (String)ViewState["FilePath"];
return ((s == null) ? "[" + this.ID + "]" : s);
}
set
{
ViewState["FilePath"] = value;
}
}
protected override void RenderContents(HtmlTextWriter output)
{
output.Write(FilePath);
}
// create the layout (html) of your control here
// all the HTML code including <div>
// Add all controls to the <div>, below code is very crude.<br/>
// Also you need to register the script tags and add the script to it<br/>
protected override void CreateChildControls()
{
base.CreateChildControls();
Table table = new Table();
this.Controls.Add(table);
lblMessage = new Label();
lblMessage.ID = "lblMessage";
lblError = new Label();
lblError.ID = "lblError";
FileUpload10 = new FileUpload();
FileUpload10.ID = "FileUpload10";
btnUpload = new Button();
btnUpload.ID = "btnUpload";
btnUpload.Text = "Submit <br/> ";
// table.Controls.Add(lblMessage);
}
// invoke this method were ever required
private void FileUploadUsingJQuerySelectionMethod()
{
// check if file has been selected
HttpFileCollection files = HttpContext.Current.Request.Files;
for (int i = 0; i < files.Count; i++)
{
HttpPostedFile file = files[i];
if (file.ContentLength > 0)
{
string path = FilePath;
string fileName = Path.GetFileName(file.FileName);
// now save the file to the disk
file.SaveAs(path + fileName);
lblMessage.Text += "File : <b>" + fileName + "</b> uploaded successfully !<br />";
}
}
}

You can put your control in a dll following the steps detailed here: Turning an .ascx User Control into a Redistributable Custom Control.
I think that it would be worth converting your user control to a proper server control, however, it's not that hard and you would end up with easier to maintain code (as you will see, the process described there is rather awkward).

You could add the js files by embedding them in the dll i.e.
Including them as normal in the custom control project
Right clicking and selecting 'embedded resources'
Accessing through the resource manager as they are now part of the default resource file i.e.
Stream ms = Assembly.GetExecutingAssembly()
.GetManifestResourceStream("resourcename including namespace");
Then read the stream to get the script as a string
Register the script string with ScriptManager in the usual way

To build a web control you need to inherit from UserControl or another control, in your case FileUpload, then override the init event to add other controls (e.g. button) to the tree. Override any other events as needed.
Old article but pretty clear e.g. of principal:
http://www.codeproject.com/KB/validation/textboxwithvalidator.aspx

Related

Label text not updating during file transfer ASP.NET

I am having troubles trying to update a label during a fileupload file transfer. I essentially am trying to keep a running tab on the status of the file transfer. For whatever reason however I cannot get the label to update inside the function that I am initiating the background worker to do the file transfer. I can change the Label.Text before it enters the else statement before the file transfer (this is the part that states that there is a duplicate of a file in the desired directory).
I've been looking around for an answer for approximately two days and the conventional methods of putting the Label into an UpdatePanel and setting the UpdateMode="Conditional" and then manually calling UpdatePanel1.Update() did not work.
Other questions also addressed the problem of having errant javascript in the page and that is not the case in this situation. I do not have any javascript on this web page.
I have also tried setting the Label.Text through both a ui background worker and through a loop that ran in the SaveFile() method after the background worker for the fileupload was started. Neither worked.
Also of note I have noticed that the Label.Text contents will update when I assign it through any medium, but it does not refresh the UI on the client side until the file transfer completes, which renders the progress report in the label moot.
Here is the HTML snippet
<form id="form1" runat="server">
<!-- Here's all of the contents for the asp part of the page -->
<br />
<h1>Upload File</h1>
<asp:ScriptManager ID="ScriptMgr" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="true">
<ContentTemplate>
<p>
<asp:Label ID="UploadLabel" runat="server"></asp:Label>
</p>
</ContentTemplate>
</asp:UpdatePanel>
<asp:FileUpload ID="UploadFile" runat="server"/>
<br />
<!-- OnClick="BtnUpload_Click" -->
<asp:Button ID="BtnUpload" runat="server" Text="Upload File" OnClick="BtnUpload_Click" />
<br />
<br />
<asp:Label ID="RebootLabel" runat="server" Text=""></asp:Label>
<br />
<asp:Button ID="BtnReboot" runat="server" Text="Reboot" OnClick="BtnReboot_Click" />
</form>
Here is the relevant .cs methods
protected void SaveFile(HttpPostedFile file)
{
try
{
String savePath = Resources.Resource.INSTALLER_PATH + UploadFile.FileName; //save path on the server
//check to see if there are any duplicate file names in the destination
if (System.IO.File.Exists(savePath))
{
//then the file already exists and we should notify the user
//do not write anything to the directory if this occurs
UploadLabel.Text = "A file with the desired name already exists in the destination directory, please choose another file";
}
else
{
//then it is safe to upload the file to the TOD
/*UploadLabel.Text = "Uploading file...";
BtnReboot.Enabled = false;
System.Drawing.Color temp = BtnReboot.BackColor;
BtnReboot.BackColor = System.Drawing.Color.Black;
UploadFile.SaveAs(savePath); //upload the file to the TOD
BtnReboot.BackColor = temp;
BtnReboot.Enabled = true;
UploadLabel.Text = "Finished uploading file.";*/
try
{
UploadLabel.Text = "Uploading file...";
uploadingFileName = savePath; //get the path that is being uploaded to
uploadingFileSize = UploadFile.PostedFile.ContentLength; //get the size in bytes to upload
BackgroundWorker bgw = new BackgroundWorker();
bgw.DoWork += Bgw_DoWork;
bgw.RunWorkerAsync();
//progress report ui worker
BackgroundWorker uiWorker = new BackgroundWorker();
uiWorker.DoWork += UiWorker_DoWork;
uiWorker.RunWorkerAsync();
bgw.Dispose();
uiWorker.Dispose();
}
catch (Exception err)
{
UploadLabel.Text = err.ToString();
}
}
}
catch (System.Web.HttpException err)
{
UploadLabel.Text = "Exception: " + err.ToString();
}
catch (System.InvalidOperationException err)
{
UploadLabel.Text = "Exception: " + err.ToString();
}
catch (System.UriFormatException err)
{
UploadLabel.Text = "Exception: " + err.ToString();
}
}
private void UiWorker_DoWork(object sender, DoWorkEventArgs e)
{
while(uploadingFileSize != 0)
{
//redraw the label
if (File.Exists(uploadingFileName))
{
FileInfo fi = new FileInfo(uploadingFileName);
long currentSize = fi.Length;
UploadLabel.Text = "Progress: " + currentSize + " / " + uploadingFileSize;
UpdatePanel1.Update();
}
}
}
/// <summary>
/// Bgw_DoWork
/// Asynchronous function that gets called for the background worker to start work
/// Is used for file uploading. Combined with the timer to give feedback on current upload progress
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Bgw_DoWork(object sender, DoWorkEventArgs e)
{
UploadLabel.Text = "Hello from the bgw";
UploadFile.SaveAs(uploadingFileName);
uploadingFileSize = 0;
uploadingFileName = "";
//BackgroundWorker worker = sender as BackgroundWorker;
//worker.ReportProgress(0);
}
The main problem is that you want to do the both actions (Uploading file and updating the label) with the same request. Consider the fact that once you upload a file you're sending a stream of bytes to the server and you need to wait for the response and the response would be after file being completely uploaded. So what you need to do is triggering 2 ajax requests throw jquery( $.ajax() method) or XMLHttpRequest. Using update panels is not an option for what you're up to do.
Take a look into this to see how you can do it : http://abandon.ie/notebook/simple-file-uploads-using-jquery-ajax

Sharepoint Custom text Web part Property

When a user enters custom text in a web part property. It will display on a form.
this is the code for the web part property it is on the the testTextWebPart.ascx.cs
public partial class testTextWebPart: WebPart
{
private string _customtxt;
[WebBrowsable(true),
Category("Miscellaneous"),
Personalizable(PersonalizationScope.Shared),
WebDisplayName("Enter some text")]
public string CustomTextProp
{
get
{
return _customtxt;
}
set
{
_customtxt = value;
}
}
I need to display the text onto a form.This page is testTextWebPart.ascx
<script type="text/javascript">
function NAME() {
var ctx = new SP.ClientContext.get_current();
var webURL = ctx.get_url;
var newFormURL = window.location.protocol + '//' + window.location.host + webURL + '/Lists/Testpage/NewForm.aspx';
var options = SP.UI.$create_DialogOptions();
options.title = 'PAGE TITLE';
options.url = newFormURL;
SP.UI.ModalDialog.showModalDialog(options);
}
I need to display it here. This is in my Control templates folder this page is testText.ascx
<div id="divForm" runat="server" style="width:400px; margin-left:auto; margin-right:auto; margin-top:10px;">
<div style="margin-bottom:10px;"> DISPLAY HERE </div>
I need to get the text the user entere via the webpart properties and then display it on the form when the user clicks the newform.
You can just add this method to your code:
protected override void CreateChildControls()
{
base.CreateChildControls();
LiteralControl message = new LiteralControl();
message.Text = CustomTextProp;
Controls.Add(message);
}

Using HTML5 file (Multiple) control in asp.net

I am looking for a way to perfectly manage the <input type="file" multiple="multiple"> tag of HTML 5 in my asp.net 3.5 project.
I have done it before with a single control on page, but what if we have multiple upload controls on the same page. Please see my code:
protected void btnSave_Click(object sender, EventArgs e)
{
//---------Need to check if my upload control has files: Please suggest a perfect way
if (fupAttachment.PostedFile != null || fupAttachment.PostedFile.FileName != "" || fupAttachment.PostedFile.ContentLength>0)//here is a problem, as it does not checks for a blank file upload control
HttpFileCollection hfc = Request.Files;
string strDirectory = Server.MapPath("~/") + "Mailer/" + hidCampID.Value;
if (hfc.Count>0)
{
if (!System.IO.Directory.Exists(strDirectory))
{
System.IO.Directory.CreateDirectory(strDirectory);
}
if (System.IO.Directory.Exists(strDirectory))
{
for (int i = 0; i < hfc.Count - 1; i++)
{
hfc[i].SaveAs(strDirectory + "/" + hfc[i].FileName.Replace(" ", "_"));
}
}
}
}
}
My asp page is something like this:
//----this control is from which I want to multiple upload files
<input type="file" multiple="multiple" runat="server" id="fupAttachment" />
// Another upload control is there which takes input when page loads
<asp:FileUpload ID="fupMailingList" runat="server" />
So, exactly my problem is that when page loads "fupMailingList" has taken a file, and then when I want to use my multiple upload control "fupAttachment", I am unable to check if it has any files or not, as hfc checks for all upload controls and it gets file in one of them. So, please tell me a way to check only "fupAttachment" control and then do my work correctly.
Rather than iterating over all the files in the request, you should check on a per input basis.
var uploadedFiles = Request.Files.GetMultiple("fupAttachment");
if(uploadedFiles.Count > 0)
{
//
}
Just check the HasFile property.
if(fupMailingList.HasFile){
//Do something
}

Browse files on a share folder and return full path selected by client WITHOUT uploading the file

I am attempting to provide a web-based solution for users to select a file on shared drives.
I want to use the typical file selector that is provided by windows when you go to browse for a file. The only info I need from this is the full filename + path. Now an obvious solution would be to just have a free-text textbox where users type in their filename, but I am required to use the file selector. (image below)
As a side note I am using the Telerik controls and this download functionality is in a user control that is inside an ajaxified panel in the parent page.
Currently I have this markup:
Add a Link to a Document: <input type="file" id="upLink" runat="server" onchange="LinkSelected(this);" />
<asp:HiddenField ID="hdnLinkFile" runat="server" />
<asp:Button ID="btnLink" runat="server" CssClass="invisiblebutton" OnClick="LinkFile" />
<script>
function LinkSelected(sender) {
if (sender && sender.value.length > 0) {
//save filename to hidden value as it will not otherwise be usable on the server without a postback
$("#<%= hdnLinkFile.ClientID %>").val(sender.value);
//clear
sender.value = null;
//fire server request on this user control
$find("<%= RadAjaxManager.GetCurrent(Page).ClientID %>").ajaxRequestWithTarget("<%= btnLink.UniqueID %>", "");
}
}
</script>
code behind:
protected void LinkFile(object sender, EventArgs e)
{
if (hdnLinkFile.Value.Length > 2 && hdnLinkFile.Value.Substring(0, 2) != #"\\")
{
Code.Common.DisplayMessage("File must be in a shared location!", Page);
}
else
{
//save link string to database
}
}
The purpose of this code is to prevent a full postback. A full postback will cause the file input (upLink) to upload the selected file to the web server. As we are allowing large files (over 100MB) to be linked to, and all I want is the filepath, (and the internet for some of the clients is very slow) there is no need for the upload.
this code works great in IE - unfortunately for inputs with type=file Firefox returns only the filename - not the full path + name . Being that the reason Firefox doesn't provide this data as it is considered a security risk, and also that the client uses firefox by default, I need to find another way. All I want is the full filename + path, without actually uploading the file - how hard can it be???
Well unfortunately the only way I found how to do it was to build my own file selector dialog. Seeing as I am already using the Telerik controls, I used the RadTreeView and RadWindow as below. I've pulled out all the validation to make it simpler. Its based on the Telerik demo here
Explorer.aspx (the popup window)
<script type="text/javascript">
function onNodeClicking(sender, args) {
//fill path textbox
var textbox = document.getElementById('inpPath');
if (args.get_node()._parent._uniqueId == "RadTreeView1")
textbox.value = args.get_node()._properties._data.value; //root node
else
textbox.value = args.get_node()._parent._properties._data.value + "\\" + args.get_node()._getData().text;
}
function onCancel() {
var wnd = getRadWindow();
var openerPage = wnd.BrowserWindow;
openerPage.OnFileSelected('');
wnd.close();
}
function onOK() {
var wnd = getRadWindow();
var openerPage = wnd.BrowserWindow;
openerPage.OnFileSelected(document.getElementById('inpPath').value);
wnd.close();
}
function getRadWindow() {
var oWindow = null;
if (window.radWindow) oWindow = window.radWindow;
else if (window.frameElement.radWindow) oWindow = window.frameElement.radWindow;
return oWindow;
}
</script>
<div id="divFolderPath" style="padding: 0px 0px 10px 10px;">
<input id="inpPath" runat="server" type="text" style="width:80%;" />
<asp:Button ID="btnGo" runat="server" Text="Go" onclick="btnGo_Click" />
</div>
<div id="divButtons" style="padding: 0px 0px 15px 10px; text-align:center;">
<input id="btnOk" type="button" value="OK" onclick="onOK()" style="padding-right:5px;" disabled="disabled" />
<input id="btnCancel" type="button" value="Cancel" onclick="onCancel()" />
</div>
<telerik:RadTreeView ID="RadTreeView1" runat="server"
OnNodeExpand="RadTreeView1_NodeExpand"
OnClientNodeClicking="onNodeClicking">
</telerik:RadTreeView>
Code behind:
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Web.UI;
using System.IO;
using Telerik.Web.UI;
//extensions we have pics for
private readonly string[] _knownExtensions = new[] { "csv", "doc", "docx", "gif", "html", "jpg", "pdf", "png", "txt", "xls", "xlsx", "xml" };
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
if (Session["nodes"] != null && ((List<string>)Session["nodes"]).Count > 0)
{
foreach (string nod in (List<string>)Session["nodes"])
{
AddNode(nod);
}
}
else
{
AddNode(ConfigurationManager.AppSettings["LinkDocumentStartPath"]);
}
}
}
private void AddNode(string rootpath)
{
Directory.GetDirectories(rootpath);
inpPath.Value = rootpath;
//won't get this far if it fails the first check
var dirNode = new RadTreeNode(rootpath)
{
Value = rootpath,
ImageUrl = "~/Content/Images/folder.png",
Expanded = true,
ExpandMode = TreeNodeExpandMode.ServerSideCallBack
};
dirNode.Attributes.Add("isFile", "false");
RadTreeView1.Nodes.Add(dirNode);
}
protected void RadTreeView1_NodeExpand(object sender, RadTreeNodeEventArgs e)
{
BindTreeToDirectory(e.Node.Value, e.Node);
}
private void BindTreeToDirectory(string path, RadTreeNode parentNode)
{
//get directories
string[] directories = Directory.GetDirectories(path);
foreach (string directory in directories)
{
var dirNode = new RadTreeNode(Path.GetFileName(directory))
{
Value = path + "/" + Path.GetFileName(directory),
ImageUrl = "~/Content/Images/folder.png",
ExpandMode = TreeNodeExpandMode.ServerSideCallBack
};
dirNode.Attributes.Add("isFile","false");
parentNode.Nodes.Add(dirNode);
}
//get files in directory
string[] files = Directory.GetFiles(path);
foreach (string file in files)
{
var node = new RadTreeNode(Path.GetFileName(file));
node.Attributes.Add("isFile", "true");
//get extension
string extension = Path.GetExtension(file);
if (!string.IsNullOrEmpty(extension))
{
extension = extension.ToLower().TrimStart('.');
}
//choose an image for the extension
if (Array.IndexOf(_knownExtensions, extension) > -1)
{
node.ImageUrl = "~/Content/Images/" + extension + ".png";
}
else
{
node.ImageUrl = "~/Content/Images/unknown.png";
}
parentNode.Nodes.Add(node);
}
}
//go to a new directory
protected void btnGo_Click(object sender, EventArgs e)
{
string nod = inpPath.Value.Trim();
if (!string.isNullOrEmpty(nod))
{
var nodeslst = new List<string>();
if (Session["nodes"] != null)
{
nodeslst = (List<string>) Session["nodes"];
}
else
{
//session has expired - get nodes from radtree
nodeslst.AddRange(from RadTreeNode rtn in RadTreeView1.Nodes select rtn.Value);
}
if (nodeslst.Contains(nod, StringComparer.OrdinalIgnoreCase) == false)
{
AddNode(nod);
nodeslst.Add(nod);
}
Session["nodes"] = nodeslst;
}
}
and this code goes on the page that has the file select button:
<span style="width:200px; display:inline-block; text-align:right; padding-right:5px;">Add a Link to a Document:</span>
<telerik:RadTextBox ID="txtLinkFileName" runat="server" Width="325px" Enabled="False"></telerik:RadTextBox>
<asp:Button ID="selectFile" OnClientClick="OpenFileExplorerDialog(); return false;" Text="Browse..." runat="server" />
<asp:Button ID="btnLink" runat="server" CssClass="invisiblebutton" OnClick="LinkFile" CausesValidation="false" />
<telerik:RadWindow runat="server" Width="550px" Height="560px" VisibleStatusbar="false"
ShowContentDuringLoad="false" NavigateUrl="Explorer.aspx" ID="ExplorerWindow"
Modal="true" Behaviors="Close,Move,Resize">
</telerik:RadWindow>
<script type="text/javascript">
function OpenFileExplorerDialog() {
var wnd = $find("<%= ExplorerWindow.ClientID %>");
wnd.show();
}
//This function is called from code on the Explorer.aspx page
function OnFileSelected(fileSelected) {
if (fileSelected && fileSelected.length > 0) {
var textbox = $find("<%= txtLinkFileName.ClientID %>");
textbox.set_value(fileSelected);
$find("<%= RadAjaxManager.GetCurrent(Page).ClientID %>").ajaxRequestWithTarget("<%= btnLink.UniqueID %>", "");
}
}
</script>
code behind:
protected void LinkFile(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(txtLinkFileName.Text))
{
if (txtLinkFileName.Text.Length > 2 && txtLinkFileName.Text.Substring(0, 2) != #"\\")
{
Code.Common.DisplayMessage("File must be in a shared location!", Page);
}
else
{
//just a link to a file - no need to upload anything
//save filepath to database
//filepath = txtLinkFileName.Text;
}
}
}
As you can see it would be a lot easier if smartypants browsers weren't trying to protect us from ourselves, but still accomplishable.

Getting the path of a file using fileupload control

I am using a fileupload control to display the contents of a text file in a textbox..if i use this
<asp:FileUpload ID="txtBoxInput" runat="server" Text="Browse" />
string FilePath = txtBoxInput.PostedFile.FileName;
it will get only the file name like bala.txt.i need like this D:\New Folder\bala.txt
Instead of fileupload control i have used textbox to get the path like this D:\New Folder\bala.txt
<asp:TextBox ID="txtBoxInput" runat="server" Width="451px"></asp:TextBox>
string FilePath = txtBoxInput.Text;
But i need browse button instead of textbox to get the path...Any Suggestion??
EDIT:My button click event
protected void buttonDisplay_Click(object sender, EventArgs e)
{
string FilePath = txtBoxInput.PostedFile.FileName;
if (File.Exists(FilePath))
{
StreamReader testTxt = new StreamReader(FilePath);
string allRead = testTxt.ReadToEnd();
testTxt.Close();
}
}
You can get the file name and path from FileUpload control only when you are in debug mode but when you deployed your app. in server then you cant because that is your client address which you are trying to access by server side code.
protected void Button1_Click(object sender, EventArgs e)
{
string filePath,fileName;
if (FileUpload1.PostedFile != null)
{
filePath = FileUpload1.PostedFile.FileName; // file name with path.
fileName = FileUpload1.FileName;// Only file name.
}
}
If you really want to change properties or rename client file then you can save file on server on temp folder then you can do all thing which you want.
http://forums.asp.net/t/1077850.aspx

Categories

Resources