Thursday, December 31, 2009

Calling an External Page into ModelPopup from GridView

In this post the ModalPopup extender is used to pop open an external ASPX page inside GridView,
Here are the steps:

1: Create new ASPX page and add The following controls // call this page MyPage.aspx
a:- GridView to handle data // call is GridView1
b:- Panel to open the external page inside it // call it pnlEdit
c:- LinkButton in GridView to Open The ModelPoup // call it lnkEdit
d:- ModalPopupExtender to popup the Panel // call it MPEEditPopup
e:- Iframe to open the external page and make it as server control // call it ifrEditPopup
f:- HIDDEN LinkButton to virtualy open the popup // call it lnkHidden
g:- DONT FORGET to add ScriptManger

Look to the following code which contains all controls we need

MyPage.aspx
        <asp:ScriptManager ID="ScriptManager1" runat="server">
        </asp:ScriptManager>
        <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
            onrowcommand="GridView1_RowCommand">
            <Columns>
                <asp:BoundField DataField="ID" HeaderText="ID" />
                <asp:BoundField DataField="Description" HeaderText="Description" />
                <asp:TemplateField HeaderText="Edit">
                    <ItemTemplate>
                        <asp:LinkButton ID="lnkEdit" CommandName="OpenEditPopup" runat="server">Edit</asp:LinkButton>
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
        </asp:GridView>
        <asp:Panel Style="display: none" CssClass="modalPopup" ID="pnlDetail" runat="server">
            <table cellpadding="0" cellspacing="0">
                <tr>
                    <td align="right">
                        <asp:Button Text="Close Popup" ID="btnClose" runat="server"  />
                    </td>
                </tr>
                <tr>
                    <td>
                        <iframe id="ifrEditPopup" runat="server" scrolling="no" width="250px" height="140px"
                            frameborder="no"></iframe>
                    </td>
                </tr>
            </table>
        </asp:Panel>
        <ajaxToolkit:ModalPopupExtender ID="MPEEditPopup" runat="server" TargetControlID="lnkHidden"
            PopupControlID="pnlDetail" CancelControlID="btnClose" BackgroundCssClass="modalBackground"
            DropShadow="false" />
        <asp:LinkButton ID="lnkHidden" Style="visibility: hidden" runat="server">Hidden</asp:LinkButton>


The page design will be like this:


2:- In code-behind add the following code to fill grid with data
MyPage.aspx.cs

protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
GridView1.DataSource = LoadDataFromDB(); // This function will retrive data from DB to fill grid;
GridView1.DataBind();
}
// to reset the src attributes for IFrame control
ifrEditPopup.Attributes["src"] = "";

}

3:-Create New Page and call it EditPage.aspx and write anything in this page e.g: This is EDIT Page

4:-In code-behind for The first page add OnRowCommand event to write the code to open the popup, look to the following code

MyPage.aspx.cs

protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "OpenEditPopup")
{
// for IFrame control add new src as new attribute and give it the path for EditPage.aspx
// what is t ??? I've added Ticks as Query String just to avoid cookie problem when trying to open the popup again
ifrEditPopup.Attributes.Add("src", "EditPage.aspx?t=" + DateTime.Now.Ticks);
// call Show method to open the popup
MPEEditPopup.Show();
}
}

5:- now run the project, the result will be like this:


NOTE
   we left the src attribute for IFrame control empty, to avoid loading EditPage.aspx more than one time when loading MyPage.aspx, e.g: if the GridView contains 10 rows then the system will create 10 Iframe controls and for each control the system will call the EditPage, therefore the best solution is to leave the src attribute balnk and fill it with the URL in OnRowCommand event when the user Click on Edit link

Thanks,
Mohammad Al-Shafei 


Tuesday, December 29, 2009

Failed to load expression host assembly error in a SharePoint web part


I was writing a custom Reporting local report(Microsoft Report rdlc) and everything is working fine,but when I placed it in a SharePoint Web Part, I got this error:

Failed to load expression host assembly. Details: Could not load file or assembly 'expression_host_31f4d73d84764f4b9a7332f3673bdf0b, Version=10.8.30729.1, Culture=neutral, PublicKeyToken=null' or one of its dependencies. Failed to grant permission to execute. (Exception from HRESULT: 0x80131418)

This was fixed by setting the ExecuteReportInCurrentAppDomain property like so:
reportViewer1.LocalReport.ExecuteReportInCurrentAppDomain
(System.Reflection.Assembly.GetExecutingAssembly().Evidence);


Thanks,
Mohammed AlShafei

Sunday, December 27, 2009

Converting Web User Control to Web Part in Sharepoint 2007


Many of web part have complex design, of-course we can create this web part by using code-behind code. In other words, creating the controls dynamically, Take a look at this sample web part:

Protected Overloads Overrides Sub CreateChildControls()
MyBase.CreateChildControls()

Dim btnShowMessage As New Button()
btnShowMessage.Text = "show Message"

AddHandler btnShowMessage.Click, AddressOf btnShowMessage_Click
Me.Controls.Add(btnShowMessage)
End Sub

Private Sub btnShowMessage_Click(ByVal sender As Object, ByVal e As EventArgs)
Dim lbl1 As New Label()
lbl1.Text = "Hello Guest"

Me.Controls.Add(lbl1)
End Sub


so if we want to create complex web part (I mean web part contains many controls) this way will take a lot of time and efforts, so I found another way to create a simple or complex web part, after researching, anyway here are the steps:

1) Create your Web User Control. You have the option on how you create it, but in my part, I create it using ASP.NET 2.0 IDE. What I usually did is I create a blank page, then I add a new item which is Web User Control. Take note to uncheck the option which separate your code in a separate file.

2) Design your Web User Control (ascx), from its physical design to its logic coding.
3) compile the solution
4) drag and drop the solution DLL in \windows\assembly 
5) browse the DLL inside the assembly folder the right click and select properties
6) Copy the Public Key Token its look like e3dc1ba93544f2e9
7) open ascx file and insert the following line at the end of Inherits property.
  , NameSpace, Version=1.0.0.0, Culture=neutral, PublicKeyToken=e3dc1ba93544f2e9

8) now after pasting the code the new page register tage will be like this
<%@ Control Language="vb" AutoEventWireup="false" CodeBehind="MyUserControl.ascx.vb"
    Inherits="MyTestSolution.MyUserControl, MyTestSolution, Version=1.0.0.0, Culture=neutral, PublicKeyToken=e3dc1ba93544f2e9" %>




3) Copy the modified ascx file to this directory:

         c:\inetpub\wwwroot\wss\VirtualDirectories\2222\wpresources

   Where: 2222: the number of port that your site using
               wpresources: you can use any other folder.

4) Write the following code for adding your web user control file in your .vb file:

Protected Overrides Sub CreateChildControls()

MyBase.CreateChildControls()
dim objUserControl as Control
objUserControl= Page.LoadControl("~/wpresources/MyUserControl.ascx")
Me.Controls.Add(objUserControl)
End Sub


With Speacial Thanks to Mr. Moutasem Al-awa for his assistance

Friday, December 25, 2009

How to change the maximum upload file size in ASP.NET


In many Application we need to increase the maximum upload file size in ASP.NET,
to do this just Insert
<httpRuntime maxRequestLength="XXXX" /> within
<system.web> and </system.web>

where XXXX is the file size in KB e.g: 1024 KB = 1 MB

The default is 4096 (= 4 MB).
and here is a sample:



<system.web>
          <httpRuntime maxRequestLength="10240/>
</system.web>




Thanks,

Tuesday, December 22, 2009

Storing and Retrieving Files from SQL Database Using ASP.NET 2.0


Most of our application might need to store images, PDFs, Word documents, Excel documents, or other binary data. there are two ways: on the web server's file system, with a reference to the file in the database; or directly in the database itself.
In this Article we will discuss the second way storing directly in the database itself.


1. Creating a Database Table to Store Files:


We need to create simple table to holds Binary Data, (I will use MS SQL Server 2005).




Also we need to Create Stored Procedure to use it to Insert record into UserFile Table, look to the following code:

CREATE PROCEDURE InsertUserFileInfo
(
@FileName nvarchar(400),
@ContentType varchar(100),
@FileLength int,
@FileContent image
)
AS
INSERT INTO UserFile
(
FileName,
ContentType,
FileLength,
FileContent
)
VALUES
(
@FileName,
@ContentType,
@FileLength,
@FileContent
)

2. Creating ASP.NET Page to upload file

We will add only FileUpload Control with Button to upload file, look to the following code:

UploadFile.aspx

<asp:FileUpload ID="FileUpload1" runat="server" />
<asp:Button ID="btnUpload" runat="server" Text="Upload" onclick="btnUpload_Click" />


3. Adding Code to Upload.aspx Page


Once the user has selected a file and posted back the form (by clicking the "Upload" button, for example), the binary contents of the specified file are posted back to the web server. From the server-side code, this binary data is available through the FileUpload control's PostedFile.InputStream property, as the following markup and code illustrates:

UploadFile.aspx.cs

protected void btnUpload_Click(object sender, EventArgs e)
{
if (FileUpload1.HasFile)
{
// string to store allowed file extension
string strAllowedExtenstion = ".doc, .zip, .rar, .docx, .xls, .xlsx, .pdf, .jpg, .gif, .png";
// string to get user file extension
string strFileExtenstion = System.IO.Path.GetExtension(FileUpload1.FileName);
if (strAllowedExtenstion.IndexOf(strFileExtenstion) > -1)
{
// IO Stream to hold uploaded file stream
System.IO.Stream stream = FileUpload1.PostedFile.InputStream;

// array of bytes to hold file stream
byte[] fileData = new byte[stream.Length];
stream.Read(fileData, 0, Convert.ToInt32(stream.Length));
stream.Close();

// now call function to store binary data in DB
_saveDataToDB(fileData, FileUpload1.FileName, _getContentType(strFileExtenstion) );

}
else
{
// Not Allowed file type
}
}
else
{
// no file selected
}
}

private string _getContentType(string pFileExtension)
{
switch (pFileExtension)
{
case ".doc":
return "application/vnd.ms-word";

case ".docx":
return "application/vnd.ms-word";

case ".xls":
return "application/vnd.ms-excel";

case ".xlsx":
return "application/vnd.ms-excel";

case ".jpg":
return "image/jpg";

case ".png":
return "image/png";

case ".gif":
return "image/gif";

case ".pdf":
return "application/pdf";

case ".rar":
return "application/rar";

case ".zip":
return "application/zip";

}
return "";
}


// Store File data into SQL DB using Stored Procedure (InsertUserFileInfo)
private void _saveDataToDB(byte[] pFileData , string pFileName,string pContentType)
{
using (SqlConnection connection = new SqlConnection(ConnectionString))
{
connection.Open();
using (SqlCommand command = new SqlCommand("InsertUserFileInfo", connection))
{
command.CommandType = System.Data.CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("@FileName", pFileName));
command.Parameters.Add(new SqlParameter("@ContentType", pContentType));
command.Parameters.Add(new SqlParameter("@FileLength", pFileData.Length));
command.Parameters.Add(new SqlParameter("@FileContent", pFileData));

command.ExecuteNonQuery();
}
}
}


3. Retrieving File from SQL DB:


The first step is creating new page and call it ViewFile.aspx

The next Step is creating Stored Procedure to retrieve File Data

CREATE PROCEDURE [dbo].[GetUserFileInfo]
(
@FileID INT
)
AS

SELECT FileID,
FileName,
ContentType,
FileLength,
FileContent

FROM UserFile
WHERE (@FileID =FileID)


The Final step is adding code to page behind (into ViewFile.aspx.cs), look down:

ViewFile.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
string pContentType;
Int32 pFileLength;
byte[] pFileContent;
string pFileName;

_getDataFromDB(ref pFileLength, ref pFileName, ref pFileContent, ref pContentType)

Response.Clear();
Response.Charset = "utf-8";
Response.Buffer = true;
this.EnableViewState = false;
Response.ContentEncoding = System.Text.Encoding.UTF8;

Response.AddHeader("Content-Disposition", "attachment;filename=" + pFileName);
Response.BinaryWrite(pFileContent);
Response.ContentType = pContentType;
Response.Flush();
Response.Close();
Response.End();


}


private void _getDataFromDB(ref Int32 pFileLength, ref string pFileName, ref byte[] pFileContent, ref string pContentType)
{
using (SqlConnection connection = new SqlConnection(ConnectionString))
{
connection.Open();
using (SqlCommand command = new SqlCommand())
{
command.Connection = connection;
command.CommandType = System.Data.CommandType.StoredProcedure;
command.CommandText = "GetUserFileInfo";

// FileID from QueryString e.g when calling this page just type ViewFile.aspx?FileID=3

// you can use any other way to determine which FileID you want


command.Parameters.Add(new SqlParameter("@FileID", Convert.ToInt32(Request.QueryString["FileID"])));
SqlDataReader sqlDataReader = command.ExecuteReader();


while (sqlDataReader.Read())
{
pContentType = sqlDataReader.GetString(2);
pFileContent = (byte[])sqlDataReader[4]; ;
pFileLength = sqlDataReader.GetInt32(3);
pFileName = sqlDataReader.GetString(1);

}
}
}
}



After runuing and calling this page, the following message will appear:

now you can save this file or open it directly

Thanks