Total Pageviews
Saturday, September 19, 2009
Getting The Real IP Of Your Users(Track IP Address)
The Following code will get the IP Address of visitor/ client.
------------------------------------------------------
C# code to track IP Address
------------------------------------------------------
string ipaddress;
// Look for a proxy address first
ipaddress = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
// If there is no proxy, get the standard remote address
if (ipaddress == "" || ipaddress == null)
ipaddress = Request.ServerVariables["REMOTE_ADDR"];
-----------------------------------------------
VB Code to track IP Address
-----------------------------------------------
' Look for a proxy address first
Dim _ip As String = Request.ServerVariables("HTTP_X_FORWARDED_FOR")
' If there is no proxy, get the standard remote address
If (_ip = "" Or _ip.ToLower = "unknown") Then _
_ip = Request.ServerVariables("REMOTE_ADDR")
-----------------------------------------------------------
Explaination of above Code
-----------------------------------------------------------
The HTTP_X_FORWARDED_FOR variable is to check that there isn't a non-transparent proxy in the way.When users are behind any proxies or routers the REMOTE_ADDR returns the IP Address of the router and not the client user’s machine. Hence first we need to check HTTP_X_FORWARDED_FOR, since when client user is behind a proxy server his machine’s IP Address the Proxy Server’s IP Address is appended to the client machine’s IP Address. If there are multiple proxy servers the IP Addresses of all of them are appended to the client machine IP Address.
Hence we need to first check HTTP_X_FORWARDED_FOR and then REMOTE_ADDR.
Note: While running this application on your machine it will show IP Address 127.0.0.1 since your client and server is the same machine. when you will run this application on live server it will display the right information.
------------------------
Happy Programming
Thursday, September 3, 2009
Open New Tab/Window (Response.Redirect open in new web page)
Tuesday, August 18, 2009
Programming the web.config File Using C#
What Is web.config?
The web.config file is the application’s configuration file. It is typically used to configure an ASP.NET Web application and define the configuration settings for the Web application. It typically contains the application-wide settings, such as database connection string, culture settings, authentication, and authorization information, etc. In ASP.NET 1.x, much effort was required to manipulate the web.config file programmatically. With ASP.NET 2.0 however, this can be done quite easily and efficiently. The following section discusses how this can be achieved.
The Configuration API in ASP.NET 2.0
The configuration API of ASP.NET 2.0 adds a great level of flexibility in that it allows us to add or edit a configuration file seamlessly in ASP.NET. The WebConfigurationManager class in the System.Web.Configuration namespace has the OpenWebConfiguration method that can be used to open the configuration file of the application as a Configuration object for reading from or writing to the configuration file. The virtual path to the configuration file is specified to this method as a parameter. The following code snippet displays all the keys of the appSettings section of the web.config file:
Configuration configuration = WebConfigurationManager.OpenWebConfiguration(”~”); AppSettingsSection appSettingsSection = (AppSettingsSection)configuration.GetSection(”appSettings”); if (appSettingsSection != null) { foreach (string key in appSettingsSection.Settings.AllKeys) { Response.Write(key); } } The following method can be used to modify a specific key — value pair of the web.config file — programmatically using C#:
public void Modify(string key, string value) { Configuration configuration = WebConfigurationManager.OpenWebConfiguration(”~”); AppSettingsSection appSettingsSection = (AppSettingsSection)configuration.GetSection(”appSettings”); if (appSettingsSection != null) { appSettingsSection.Settings[key].Value = value; config.Save(); } }
The following method can be used to delete a specific key in the web.config file programmatically using C#:
public void Remove(string key) { Configuration configuration = WebConfigurationManager.OpenWebConfiguration(”~”); AppSettingsSection appSettingsSection = (AppSettingsSection)configuration.GetSection(”appSettings”); if (appSettingsSection != null) { appSettingsSection.Settings.Remove(key); config.Save(); } }
Conclusion
Even if modifying a web.config file programmatically can be a handy solution in some situations, it is not recommended to do so frequently in a Web application, as any change in the web.config file will restart the Web server and refresh the cache entries.
Friday, August 7, 2009
GridView with Dynamic columns
Monday, August 3, 2009
Call WebService using Javascript
TO call any webservice in javascript use following code... <script> function CallWebService() { PrintService.PrintCode(OnSuccess); // here i m using PrintServer as webservice to print purpose } function OnSuccess(result) { document.getElementId('result').value=result; } </script> ------------------------------------------------------------ Following is my web service public class PrintService : System.Web.Services.WebService { public static string strMyPrintCode = string.Empty; public static string strOfferCode = string.Empty; public PrintService() { //Uncomment the following line if using designed components //InitializeComponent(); } [WebMethod] public string PrintCode() { string strCode = GetRandomUniqueAlphaNumericCode(8, false); strMyPrintCode = strCode; return strCode; // return unique and random alphanumeric code } } --------------------------- Notice where i m calling webservice...i m passing one argument when calling webservice method named PrintCode, when call to webservice succeeded, Javascript function OnSuccess will be call. You can also create one more function named OnFailure to notify failure of webservice
ASP.NET Validation Controls
With ASP.NET, there are six(6) controls included.
They are:
- The RequiredFieldValidation Control
- The CompareValidator Control
- The RangeValidator Control
- The RegularExpressionValidator Control
- The CustomValidator Control
All of the validation controls inherit from the base class BaseValidator so they all have a series of properties and methods that are common to all validation controls. They are:
- ControlToValidate – This value is which control the validator is applied to.
- ErrorMessage – This is the error message that will be displayed in the validation summary.
- IsValid – Boolean value for whether or not the control is valid.
- Validate – Method to validate the input control and update the IsValid property.
- Display – This controls how the error message is shown. Here are the possible options:
o None (The validation message is never displayed.) o Static (Space for the validation message is allocated in the page layout.) o Dynamic (Space for the validation message is dynamically added to the page if validation fails.)
The RequiredFieldValidation Control ———————————–
The first control we have is the RequiredFieldValidation Control. As it’s obvious, it make sure that a user inputs a value. Here is how it’s used:
Required field:
The CompareValidator Control —————————– Next we look at the CompareValidator Control. Usage of this CompareValidator is for confirming new passwords, checking if a departure date is before the arrival date, etc. We’ll start of with a sample:
Textbox 1:
Textbox 2:
Here we have a sample where the two textboxes must be equal. The tags that are unique to this control is the ControlToCompare attribute which is the control that will be compared. The two controls are compared with the type of comparison specified in the Operator attribute. The Operator attribute can contain Equal, GreterThan, LessThanOrEqual, etc. Another usage of the ComapareValidator is to have a control compare to a value. For example:
Field:
The RangeValidator Control ————————–
Range validator control is another validator control which checks to see if a control value is within a valid range. The attributes that are necessary to this control are: MaximumValue, MinimumValue, and Type. Sample:
Enter a date from 1998:
The RegularExpressionValidator Control ————————————–
The regular expression validator is one of the more powerful features of ASP.NET. Everyone loves regular expressions. Especially when you write those really big nasty ones… and then a few days later, look at it and say to yourself. What does this do? Again, the simple usage is:
E-mail:
The CustomValidator Control —————————–
The final control we have included in ASP.NET is one that adds great flexibility to our validation abilities. We have a custom validator where we get to write out own functions and pass the control value to this function.
Field:
We notice that there are two new attributes ClientValidationFunction and OnServerValidate. These are the tell the validation control which functions to pass the controltovalidate value to. ClientValidationFunction is usually a javascript funtion included in the html to the user. OnServerValidate is the function that is server-side to check for validation if client does not support client-side validation.
Client Validation function:
>
Server Validation function:
Sub ServerValidate (objSource As Object, objArgs As ServerValidateEventsArgs) ‘ Code goes here End Sub
Validation Summary ——————-
ASP.NET has provided an additional control that complements the validator controls. This is the validation summary control which is used like:
Saturday, August 1, 2009
User Control Events
Wednesday, July 1, 2009
True Random and Unique AlphaNumeric Number Generator
Thursday, June 25, 2009
Custom Paging in Datalist
Introduction
In this article i will explain a method for providing custom paging for datalist or repeater.
As you know the datalist is a very powerful control with one drawback that it does not have built-in paging capability, a feature the DataGrid offers. to provide paging to datalist or repeater we can either use “PagedDataSource” class, found in the System.Web.UI.WebControls namespace for auto paging like the datagrid or implement custom paging functionality.
So here is the scenario, i have an image gallery with 8 images per page. i need to provide paging so the user can navigate and view all images. The first step is to create the datalist and paging links.
Datalist <asp:DataList runat=”server” id=”dlGallery” RepeatColumns=”4″ RepeatDirection=”Horizontal”> <ItemTemplate> <table border=”0″ cellpadding=”0″ cellspacing=”0″> <tr> <td> <img src=”<%#DataBinder.Eval(Container.DataItem,”Image_URL”)%>” width=”90″ Height=”90″> </td> </tr> </table> </ItemTemplate> </asp:DataList> //Next/Prev Links. <table border=”0″ width=”410″> <tr> <td align=”left”><asp:LinkButton ID=”lbtnPrev” Runat=”server”>Prev</asp:LinkButton></td> <td align=”right”><asp:LinkButton ID=”lbtnNext” Runat=”server”>Next</asp:LinkButton></td> </tr> </table> //The Code Behind Create a public function that will return only the neccessary rows (After paging). For that we need five static variables. Collapse private int imgID; private string imgTitle; private string imgURL; private static int pageSize = 8; //(This one will hold the no of records return //i mean “no. of records per page”). private static int pageIndex = 0; //(This one is for checking the current page). public DataSet GetAllImagesCustom(int pageIndex, out int outPageIndex) { try { int count = 0; DataSet ds = new DataSet(); ds = //retrieve the data from the database. //for paging int page = 0; //checking the whether the pageIndex value is not
Friday, May 29, 2009
Custom Paging in GridView without Object Data Source
All we need to use the Custom paging in grid view without object data source.
Here i am going to explain my code which is used in custom paging of grid view... What you will need to do is used your DataSource SP or query with this paging...
All magic lies in SQL Server 2005 ROWNumber() Function.... Simple SP for this gridview datasource is
Select Row,ID,Name ( Select ROW_Number()OVER(ORDER BY ID) As Row,ID,Name from table1 ) AS A Where Row=>@PageIndex*PageSize and Row<(@PageIndex+1)*PageSize; --here @PageIndex and @PageSize are passed as parameter as gridview1.PageIndex and gridview1.PageSize
if you are not familiar with RowNumber function than create one temp table use Row as primary key with auto increament number and than use insert select statement.... this will work in all database.....
Follow is the C# code for custom gridview...I m creating new grid view control here
using System; using System.Collections.Generic; using System.ComponentModel; using System.Text; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace CustomPagingGridView { [DefaultProperty("Text")] [ToolboxData("<{0}:CustomePagingGrid runat=server>CustomePagingGrid>")] public class CustomePagingGrid : GridView { public CustomePagingGrid(): base() {} #region Custom properties // this property is to use to find the total number of record for grid [Browsable(true), Category("NewDynamic")] [Description("Set the virtual item count for this grid")] public int VirtualItemCount { get { if (ViewState["pgv_vitemcount"] == null) ViewState["pgv_vitemcount"] = -1; return Convert.ToInt32(ViewState["pgv_vitemcount"]); } set { ViewState["pgv_vitemcount"] = value; } } // this is used to sort the gridview columns [Browsable(true), Category("NewDynamic")] [Description("Get the order by string to use for this grid when sorting event is triggered")] public string OrderBy { get { if (ViewState["pgv_orderby"] == null) ViewState["pgv_orderby"] = string.Empty; return ViewState["pgv_orderby"].ToString(); } protected set { ViewState["pgv_orderby"] = value; } } private int Index { get { if (ViewState["pgv_index"] == null) ViewState["pgv_index"] = 0; return Convert.ToInt32(ViewState["pgv_index"]); } set { ViewState["pgv_index"] = value; } } public int CurrentPageIndex { get { if (ViewState["pgv_pageindex"] == null) ViewState["pgv_pageindex"] = 0; return Convert.ToInt32(ViewState["pgv_pageindex"]); } set { ViewState["pgv_pageindex"] = value; } } private int SetCurrentIndex { get { return CurrentPageIndex; } set { CurrentPageIndex = value; } } // if this property is set to greater than zero means custom paging neede private bool CustomPaging { get { return (VirtualItemCount != -1); } } #endregion #region Overriding the parent methods public override object DataSource { get { return base.DataSource; } set { base.DataSource = value; // we store the page index here so we dont lost it in databind CurrentPageIndex = PageIndex; } } protected override void OnSorting(GridViewSortEventArgs e) { // We store the direction for each field so that we can work out whether next sort // should be asc or desc order PageIndex = CurrentPageIndex; SortDirection direction = SortDirection.Ascending; if(ViewState[e.SortExpression]!=null&& (SortDirection)ViewState[e.SortExpression] == SortDirection.Ascending) { direction = SortDirection.Descending; } ViewState[e.SortExpression] = direction; OrderBy = string.Format("{0} {1}", e.SortExpression, (direction == SortDirection.Descending ? "DESC" : "")); base.OnSorting(e); } protected override void InitializePager(GridViewRow row, int columnSpan, PagedDataSource pagedDataSource) { // This method is called to initialise the pager on the grid. We intercepted this and override // the values of pagedDataSource to achieve the custom paging using the default pager supplied if (CustomPaging) { pagedDataSource.AllowCustomPaging = true; pagedDataSource.VirtualCount = VirtualItemCount; pagedDataSource.CurrentPageIndex = CurrentPageIndex; } base.InitializePager(row, columnSpan, pagedDataSource); } // here we do custom paging protected override void OnPageIndexChanging(GridViewPageEventArgs e) { if (CustomPaging) { if (this.PagerSettings.Mode == PagerButtons.NumericFirstLast || this.PagerSettings.Mode == PagerButtons.Numeric) { base.OnPageIndexChanging(e); } else { if (e.NewPageIndex == -1) { Index -= 1; } else if (e.NewPageIndex == 0) { Index = 0; } else if (e.NewPageIndex == ((int)Math.Ceiling((decimal)(VirtualItemCount) / PageSize) - 1)) { Index = ((int)Math.Ceiling((decimal)(VirtualItemCount) / PageSize) - 1); } else { Index += 1; } if (Index < 0) { Index = 0; } CurrentPageIndex = Index; e.NewPageIndex = Index; base.OnPageIndexChanging(e); } } } #endregion } }
if u have any doubt,please feel free to ask me....
Wednesday, May 20, 2009
Dynamic Add Controls in row of Grid View
just use following line to add row control in particular cell or row of gridview......
// here i m adding textbox to gridview TextBox textBox = new TextBox(); textBox.ID = "txt" + columnName; gvGeneratedTemplate2.Rows[0].Cells[i].Controls.Add(textBox); // gvGeneratedTemplate2 this is my gridview id same as u can add more control to grid view depending grid view's indexs.......................
Thursday, May 14, 2009
Generate Unique Name for Uploading File
Use following function to generate unique file name.
===================================== here i m uploading image file....so i have checked image file extension and its size too....
private string Save_InFolder() { if (Validate_Image() == false) { HttpPostedFile hpf = fuBrandImage.PostedFile; string savePath = ConfigurationManager.AppSettings["CategoryImagePath"].ToString(); /* string savePath = ConfigurationManager.AppSettings["CategoryImagePath"].ToString(); * the path is defined in web.config file like defined in appsetting section.. * add follwoing line in your appsetting section of webconfig add key="CategoryImagePath" value="~/Images/Category/" * // this is where u save the file... */ string fileName = GetUniqueKey() + GetFileExtension(hpf.FileName); string saveName = Server.MapPath(savePath) + fileName; //--------------Save Image into Folder--------------- hpf.SaveAs(saveName); //--------------Save Image Path into Database--------- savePath = savePath + fileName; return savePath; } return null; } //check file extension private string GetFileExtension(string FileName) { char saperator = '.'; string[] temp = FileName.Split(saperator); return "." + temp[1].ToString(); } private bool Validate_Image() { bool errorFlag = false; string errorMessage = null; // Get a reference to PostedFile object HttpPostedFile myFile = fuBrandImage.PostedFile; errorMessage = ValidateImage(myFile); if (errorMessage != null) { ShowMessage(errorMessage); errorFlag = true; } return errorFlag; } private string ValidateImage(HttpPostedFile myFile) { string msg = null; //Check Length of File is Valid or Not. int FileMaxSize = Convert.ToInt32(ConfigurationManager.AppSettings["QueryFileAttachmentSize"].ToString()); if (myFile.ContentLength > FileMaxSize) { msg = msg + "File Size is Too Large."; } //Check File Type is Valid or Not. if (!IsValidFile(myFile.FileName)) { //File Type Error msg = msg + "Upload Only (.bmp, .jpg, .png, .gif, .jpeg )Image ."; } return msg; } private bool IsValidFile(string filePath) { bool isValid = false; string[] fileExtensions = { ".bmp", ".jpg", ".png", ".gif", ".jpeg", ".BMP", ".JPG", ".PNG", ".GIF", ".JPEG" }; for (int i = 0; i < fileExtensions.Length; i++) { //get file extensions and check } }
Wednesday, April 22, 2009
Text Box Enter Key in ASP.NET
In HTML or classic ASP pages is not hard to submit forms using the enter key on keyboard. Programmer use a to make a default button. If web site visitor click on that button or press enter key, the form will be submited.
Of course, you can have a more than one form on your page and individual submit button for every form.
You don't want to submit a form with Enter key?
Rarely, you will need to disable an Enter key and avoid to submit form. If you want to prevent it completely, you need to use OnKeyDown handler on tag of your page. The javascript code should be:
if (window.event.keyCode == 13)
{
event.returnValue=false;
event.cancel = true;
}
Common ASP.NET problems with Enter key
If you try to use Enter key in ASP.NET, according to your browser's type, you can get really weird results. For example, try to place one ASP.NET textbox and a button to the web form. Write a code on a OnClick event of a button. That could be something simple, like:
Response.Write("The button was clicked!");
Now start debugging and write something to textbox. If you press enter while focus is on textbox, form will submit, but your code for button's click event will not be executed.
Stop the debuging and place one more simple HTML textbox to the form. You will not write anything in this textbox, so you can even make it invisible. Just place it somewhere inside of your form tag.
Start debugging again. You cannot see the second textbox, and everything looks like before. Try again to write something in first textbox. If you press enter now, form will submit, and your code for button's click event will now be executed. This is extremely different behavior, and you did nothing except you placed one invisible textbox on web form. :)
Maybe it is not best practice, but placing invisible textbox could be simple solution for you if you have only one button on your web form. But, what if you have a different situation? What if you have a few buttons with only one textbox, or more than one text box with only one button, or many text boxes and many buttons with different code for each button, and all that on one form?
Different browsers have a different behavior in these cases. In case that you have more buttons, only first button will be "clicked" every time. So, we need some other approach to get an universal solution.
Enter Key in ASP.NET
One of the common requests in ASP.NET is to submit a form when visitor hits an Enter key. That could be a case if, for example you want to make Login Screen. It is expected that user just hit enter when he insert a user name and password instead to of forcing him to use a mouse to click login button. If you want to make search function on your web site, it is frequently required to give a possibility to hit enter after you insert a search terms instead of mouse click on a Search button.
In HTML or classic ASP pages is not hard to submit forms using the enter key on keyboard. Programmer use a to make a default button. If web site visitor click on that button or press enter key, the form will be submited.
Of course, you can have a more than one form on your page and individual submit button for every form.
You don't want to submit a form with Enter key?
Rarely, you will need to disable an Enter key and avoid to submit form. If you want to prevent it completely, you need to use OnKeyDown handler on tag of your page. The javascript code should be:
if (window.event.keyCode == 13)
{
event.returnValue=false;
event.cancel = true;
}
Common ASP.NET problems with Enter key
If you try to use Enter key in ASP.NET, according to your browser's type, you can get really weird results. For example, try to place one ASP.NET textbox and a button to the web form. Write a code on a OnClick event of a button. That could be something simple, like:
Response.Write("The button was clicked!");
Now start debugging and write something to textbox. If you press enter while focus is on textbox, form will submit, but your code for button's click event will not be executed.
Stop the debuging and place one more simple HTML textbox to the form. You will not write anything in this textbox, so you can even make it invisible. Just place it somewhere inside of your form tag.
Start debugging again. You cannot see the second textbox, and everything looks like before. Try again to write something in first textbox. If you press enter now, form will submit, and your code for button's click event will now be executed. This is extremely different behavior, and you did nothing except you placed one invisible textbox on web form. :)
Maybe it is not best practice, but placing invisible textbox could be simple solution for you if you have only one button on your web form. But, what if you have a different situation? What if you have a few buttons with only one textbox, or more than one text box with only one button, or many text boxes and many buttons with different code for each button, and all that on one form?
Different browsers have a different behavior in these cases. In case that you have more buttons, only first button will be "clicked" every time. So, we need some other approach to get an universal solution.
How to make a default button in ASP.NET
We need to specify exactly which button will be "clicked" when visitor press Enter key, according to which textbox currently has a focus. The solution could be to add onkeydown attribute to textbox control with this code:
TextBox1.Attributes.Add("onkeydown", "if(event.which || event.keyCode){if ((event.which == 13) || (event.keyCode == 13)) {document.getElementById('"+Button1.UniqueID+"').click();return false;}} else {return true}; ");
This line of code will cause that button Button1 will be "clicked" when visitors press Enter key and cursor is placed in TextBox1 textbox. On this way you can "connect" as many text boxes and buttons as you want.
Default buttons in ASP.NET 2.0 and ASP.NET 3.5
ASP.NET 2.0 makes this problems easier and introduce a concept of a "default button". New defaultbutton attribute can be used with
Saturday, April 11, 2009
Export GridView into Excel
/// pass gridveiw into this funtion private void ExportGridView(GridView gv) { string attachment = "attachment; filename=ArchiveOrderList.xls"; //name of excel filename Response.ClearContent(); Response.AddHeader("content-disposition", attachment); Response.ContentType = "application/ms-excel"; StringWriter sw = new StringWriter(); HtmlTextWriter htw = new HtmlTextWriter(sw); // Create a form to contain the grid HtmlForm frm = new HtmlForm(); //gvOrderInfo.Parent.Controls.Add(frm); //gvOrderInfo.Parent.Controls.Add(frm); this.Controls.Add(frm); frm.Attributes["runat"] = "server"; frm.Controls.Add(gv); frm.RenderControl(htw); //GridView1.RenderControl(htw); Response.Write(sw.ToString()); Response.End(); } private void PrepareGridViewForExport(Control gv) { LinkButton lb = new LinkButton(); Literal l = new Literal(); string name = String.Empty; for (int i = 0; i < gv.Controls.Count; i++) { if (gv.Controls[i].GetType() == typeof(LinkButton)) { l.Text = (gv.Controls[i] as LinkButton).Text; gv.Controls.Remove(gv.Controls[i]); gv.Controls.AddAt(i, l); } else if (gv.Controls[i].GetType() == typeof(DropDownList)) { l.Text = (gv.Controls[i] as DropDownList).SelectedItem.Text; gv.Controls.Remove(gv.Controls[i]); gv.Controls.AddAt(i, l); } else if (gv.Controls[i].GetType() == typeof(CheckBox)) { l.Text = (gv.Controls[i] as CheckBox).Checked ? "True" : "False"; gv.Controls.Remove(gv.Controls[i]); gv.Controls.AddAt(i, l); } else if (gv.Controls[i].GetType() == typeof(ImageButton)) { continue; } if (gv.Controls[i].HasControls()) { PrepareGridViewForExport(gv.Controls[i]); } } } public override void VerifyRenderingInServerForm(Control control) { if (control.ID == GridView1.Id) // here GridView1 is the id of gridview of page { //Doing nothing return; } base.VerifyRenderingInServerForm(control); }
Thursday, April 2, 2009
Open New pop window
click or any other window... just add attribute like ...
imgbtn.Attributes.Add("onclick", "javascript:window.open('" + Text.Replace(" ", "_") + "/LargeImage.aspx?data=" + str + "','LargeImage','width=500,height=500,scrollbars=yes'); return false;"); //here imgbtn is my image control name
Blog Archive
Ideal SQL Query For Handling Error & Transcation in MS SQL
BEGIN TRY BEGIN TRAN --put queries here COMMIT; END TRY BEGIN CATCH IF @@TRANCOUNT>0 BEGIN SELECT @@ERROR,ERRO...
-
All we need to use the Custom paging in grid view without object data source. Here i am going to explain my code which is used in custom pa...
-
One of the common requests in ASP.NET is to submit a form when visitor hits an Enter key. That could be a case if, for example you want to m...
-
using System.Data; using System.Data.SqlClient; using System.Text; using System.IO; using iTextSharp.text; using iTextSharp.text.pdf; ...