Monday, 23 September 2013

ASP.NET MVC Uploading and Downloading Files

ASP.NET MVC Uploading and Downloading Files

If you come to ASP.NET MVC from a purely ASP.NET Web Forms background, one of the first things you are likely to notice is that all those nice easy Server Controls have disappeared. One of those is the FileUpload, and its absence seems to cause a few problems. This article looks at how to upload files to the server in an MVC world, and how to get them back from the server to the user again.

In Web Forms, when you drag a FileUpload control on to the designer, something happens when the page is rendered which you probably don't notice. The resulting html form that wraps the entire page is decorated with an extra attribute: enctype="multipart/form-data". The FileUpload itself is rendered as an html input type=file. Within an MVC View, there are a number of ways to set this up. The first is with HTML:

<form action="/" method="post" enctype="multipart/form-data">
  <input type="file" name="FileUpload1" /><br />
  <input type="submit" name="Submit" id="Submit" value="Upload" />
</form>

Notice that the <form> tag includes the enctype attribute, and method attribute of post. This is needed because the form by default will be submitted via the HTTP get method.  The following approach, using the Html.BeginForm() extension method renders the exact same html when the page is requested:

@using (Html.BeginForm("", "home", FormMethod.Post, new {enctype="multipart/form-data"})){

     <input type="file" name="FileUpload1" /><br />
     <input type="submit" name="Submit" id="Submit" value="Upload" />
}

Notice the name attribute of the <input type="file"> element. We'll come back to that shortly. In the meantime, the resulting page should look rather blandly like this:
http://www.mikesdotnetting.com/images/mvcfiles1.gif
OK. So we can now browse to a local file and click the submit button to upload it to the web server. What is needed next is some way to manage the file on the server. When using a FileUpload control, you generally see code that checks to see if a file actually has been uploaded, using the FileUpload.HasFile() method.  There isn't the same convenience when you are working with MVC, as you are much closer to the raw HTTP.  However, a quick extension method can take care of that:

public static bool HasFile(this HttpPostedFileBase file)
{
  return (file != null && file.ContentLength > 0) ? true : false;
}

When you look at Controller class, you see that it has a Request object as a property, which is of type HttpRequestBase. This is a wrapper for an HTTP request, and exposes many properties, including a Files collection (actually a collection of type HttpFileCollectionBase). Each item within the collection is of type HttpPostedFileBase. The extension method checks the item to make sure there's one there, and that it has some content. Essentially, this is identical to the way that the FileUpload.HasFile() method works.
Putting that into use within the Controller Action is quite simple:

public class HomeController : Controller
{
  public ActionResult Index()
  {
    foreach (string upload in Request.Files)
    {
      if (!Request.Files[upload].HasFile()) continue;
      string path = AppDomain.CurrentDomain.BaseDirectory + "uploads/";
      string filename = Path.GetFileName(Request.Files[upload].FileName);
      Request.Files[upload].SaveAs(Path.Combine(path, filename));
    }
    return View();
  }
}

Multiple File Uploading
You might already be ahead of me at this point, and wondering how you might make use of the fact that Request.Files is a collection. That suggests that it can accommodate more than one file, and indeed, it can. If you change the original View to this:

@using (Html.BeginForm("", "home", FormMethod.Post, new {enctype="multipart/form-data"})){
     <input type="file" name="FileUpload1" /><br />
     <input type="file" name="FileUpload2" /><br />
     <input type="file" name="FileUpload3" /><br />
     <input type="file" name="FileUpload4" /><br />
     <input type="file" name="FileUpload5" /><br />
     <input type="submit" name="Submit" id="Submit" value="Upload" />
}

you will end up with this:
http://www.mikesdotnetting.com/images/mvcfiles2.gif
The code in the controller Action already checks all file uploads, so no changes are needed for it to work with multiple file uploads. Notice that each input has a different name attribute. If you need to reference them individually, that is what you use. For example, to reference the third one, you would get at it using Request.Files["FileUpload3"].
Saving to a Database
Before you scream "Separation of Concerns!" at me, the next piece of code is purely illustrative. It features ADO.NET within a controller action. As we all know, this is simply not done. Database access code belongs to your data access layer somewhere inside the Model. However, the code should give people a starting point if they want to save uploaded files to a database. First of all, I have created a database (FileTest) and added a table: FileStore:


CREATE TABLE [dbo].[FileStore](
[ID] [int] IDENTITY(1,1) NOT NULL,
[FileContent] [image] NOT NULL,
[MimeType] [nvarchar](50) NOT NULL,
[FileName] [nvarchar](50) NOT NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

The FileContent field is an image datatype, and is where the binary data that forms the file will be stored. The Index Action is changed to the following:

public ActionResult Index()
{
  foreach (string upload in Request.Files)
  {
    if (!Request.Files[upload].HasFile()) continue;

    string mimeType = Request.Files[upload].ContentType;
    Stream fileStream = Request.Files[upload].InputStream;
    string fileName = Path.GetFileName(Request.Files[upload].FileName);
    int fileLength = Request.Files[upload].ContentLength;
    byte[] fileData = new byte[fileLength];
    fileStream.Read(fileData, 0, fileLength);

    const string connect = @"Server=.\SQLExpress;Database=FileTest;Trusted_Connection=True;";
    using (var conn = new SqlConnection(connect))
    {
      var qry = "INSERT INTO FileStore (FileContent, MimeType, FileName) VALUES (@FileContent, @MimeType, @FileName)";
      cmd.Parameters.AddWithValue("@MimeType", mimeType);
      cmd.Parameters.AddWithValue("@FileName", fileName);
      conn.Open();
      cmd.ExecuteNonQuery();
    }
  }
  return View();
}

The revised code still loops through as many uploads as are on the web page, and checks each one to see if it has file. From there, it extracts 3 pieces of information: the file name, the mime type (what type of file it is) and the actual binary data that is streamed as part of the HTTP Request. The binary data is transferred to a byte array, which is what is stored in the image datatype field in the database. The mime type and name are important for when the file is returned to a user. We shall look at that part next.
Serving Files to the User
How you deliver files back to users will depend on how you have stored them primarily. If you have them stored in a database, you will usually stream the file back to the user. If they are stored on a disk, you can either simply provide a hyperlink to them, or again, stream them. Whenever you need to stream a file to the browser, you will use one of the overloads of the File() method (instead of the View() method that has been used so far in the preceding examples). There are 3 different return types of the File() method: a FilePathResult, FileContentResult and a FileStreamResult. The first streams a file directly from disk; the second sends a byte array back to the client, while the third sends the contents of a Stream object which has been generated and opened.
If you remember, when saving the uploaded files into a database, we sent a byte array to the FileContent field. When we need to get that back, it will be as a byte array again. If you have been keeping up, this means that we can use one of the two overloads of File() that return a FileContentResult. If you want the name of the file to be meaningful, you will use the overload that takes 3 arguments - the byte array, the mime type and the file name:

public FileContentResult GetFile(int id)
{
  SqlDataReader rdr; byte[] fileContent = null;
  string mimeType = "";string fileName = "";
  const string connect = @"Server=.\SQLExpress;Database=FileTest;Trusted_Connection=True;";

  using (var conn = new SqlConnection(connect))
  {
    var qry = "SELECT FileContent, MimeType, FileName FROM FileStore WHERE ID = @ID";
    var cmd = new SqlCommand(qry, conn);
    cmd.Parameters.AddWithValue("@ID", id);
    conn.Open();
    rdr = cmd.ExecuteReader();
    if (rdr.HasRows)
    {
      rdr.Read();
      fileContent = (byte[])rdr["FileContent"];
      mimeType = rdr["MimeType"].ToString();
      fileName = rdr["FileName"].ToString();
    }
  }
  return File(fileContent, mimeType, fileName);
}

The easiest way to invoke this method is to provide a hyperlink:

<a href="/GetFile/1">Click to get file</a>

If the files in the database are images, instead of a hyperlink, you just point to the controller action within the src attribute of an <img> element:

<img src="/GetFile/1" alt="My Image" />

We'll have a look at how to simply use the FilePathResult now. This is used to stream files directly from disk:

public FilePathResult GetFileFromDisk()
{
  string path = AppDomain.CurrentDomain.BaseDirectory + "uploads/";
  string fileName = "test.txt";
  return File(path + fileName, "text/plain", "test.txt");
}

And this is also invoked via a simple hyperlink:

<a href="/GetFileFromDisk">Click to get file</a>

The final option - FileStreamResult can be used to serve files from disk too:

public FileStreamResult StreamFileFromDisk()
{
  string path = AppDomain.CurrentDomain.BaseDirectory + "uploads/";
  string fileName = "test.txt";
  return File(new FileStream(path + fileName, FileMode.Open), "text/plain", fileName);
}

So what's the difference between FilePathResult and FileStreamResult and which one should you use? The main difference is that FilePathResult uses HttpResponse.TransmitFile to write the file to the http output. This method doesn't buffer the file in memory on the server, so it should be a better option for sending larger files. It's very much like the difference between using a DataReader or a DataSet. On the other hand, you might need to check the server you are hosting your site on, as a bug in TransmitFile may lead to partial delivery of files, or even complete failure. FileStreamResult is a great way of, for example, returning Chart images generated in memory by the ASP.NET Chart Controls without having to save them to disk.
Chinese translation by CareySon: 利用Asp.net MVC处理文件的上传下载



define form name or form id in mvc 4, how to give form id in mvc4

@using (Html.BeginForm(null, null, FormMethod.Post, new { name = "form1", id = "form1" }))



linq query with multiple search options




/// <summary>
   2:  /// Gets a LINQ to SQL Query according the provided parameters
   3:  /// </summary>
   4:  /// <param name="postsQuery"></param>
   5:  /// <param name="title"></param>
   6:  /// <param name="tags"></param>
   7:  /// <param name="createdOn"></param>
   8:  /// <param name="bodyText"></param>
   9:  /// <returns></returns>
  10:  private IQueryable<Post> GetPostsQuery(IQueryable<Post> postsQuery,
  11:                                         string title,
  12:                                         string tags,
  13:                                         string bodyText,
  14:                                         DateTime? createdOn)
  15:  {
  16:      if (!string.IsNullOrEmpty(title))
  17:          postsQuery = postsQuery.Where(p => p.Title.Contains(title));
  18:   
  19:      if (!string.IsNullOrEmpty(tags))
  20:          postsQuery = postsQuery.Where(p => p.Tags.Contains(tags));
  21:   
  22:      if (!string.IsNullOrEmpty(bodyText))
  23:          postsQuery = postsQuery.Where(p => p.Body.Contains(bodyText));
  24:   
  25:      if (createdOn.HasValue && createdOn.Value > DateTime.MinValue)
  26:          postsQuery = postsQuery.Where(p => p.CreatedOn.Value.Date == createdOn.Value.Date);
  27:   
  28:      return postsQuery;
  29:  }
Listing 4: IQueryable<Post> GetPostsQuery, extends and returns the IQueryable<Post> query
Listing 5 contains the method GetpostsPagingQuery. This method also extends and returns the query. LINQ to SQL provides paging with the Skip (skip all rows untill) and Take (take n number of rows) methods. And this method uses these methods to extends the query with paging capabilities.
   1:  private IQueryable<Post> GetPostsPagingQuery(IQueryable<Post> postsQuery,
   2:                                         int? startRow,
   3:                                         int? rowCount)
   4:  {
   5:      if ((startRow.HasValue) && (rowCount.HasValue && rowCount.Value > 0))
   6:          postsQuery = postsQuery.Skip((int)startRow).Take((int)rowCount);
   7:   
   8:      return postsQuery;
   9:  }
Listing 5: Adds paging to query, using Skip and Take methods


execute sql query in linq, execute sql syntax query from linq syntax, sql query with linq

  IEnumerable<vwsearchleader> leader = obj.ExecuteQuery<vwsearchleader>("  select * from vwsearchleaders where    Name like '%" + Request.QueryString["keyword"].ToString() + "%'");

            DataList1.DataSource = leader;
            DataList1.DataBind();


C# - Retrieve Email from Gmail Account, fetch email from gmail , how to access gmail inbox, get mail from inbox of gmail in c#

Gmail POP3 server address is "pop.gmail.com". It requires SSL connection on 995 port, and you should use your Gmail email address as the user name for user authentication. For example: your email is "gmailid@gmail.com", and then the user name should be "gmailid@gmail.com".
Gmail IMAP4 server address is "imap.gmail.com". It requires SSL connection on 993 port, and you should use your Gmail email address as the user name for user authentication. For example: your email is "gmailid@gmail.com", and then the user name should be "gmailid@gmail.com".
To retrieve email from Gmail account, you need to enable POP3 or IMAP4 access in your gmail account settings.
Because Gmail POP3 server doesn't work like normal POP3 server, it hides old emails automatically even the email was not deleted, so we suggest that you use IMAP4 protocol.
The following example codes demonstrate how to retrieve email from Gmail IMAP4 server.
InstallationBefore you can use the following sample codes, you should download the EAGetMail Installer and install it on your machine at first.
Add Reference of EAGetMail to Visual Stuido C#.NET ProjectTo use EAGetMail POP3 & IMAP Component in your project, the first step is "Add reference of EAGetMail to your project". Please create/open your project with Visual Studio.NET, then choose menu->"Project"->"Add Reference"->".NET"->"Browse...", and choose the EAGetMail{version}.dll from your disk, click "Open"->"OK", the reference of EAGetMail will be added to your project, and you can start to use EAGetMail to retrieve email and parse email in your project.add reference in c#

Because EAGetMail has separate builds for .Net Framework, please refer to the following table and choose the correct dll.
Separate builds of run-time assembly for .Net Framework 1.1, 2.0, 3.5, 4.0 and .Net Compact Framework 2.0, 3.5.
File.NET Framework Version
EAGetMail.dllBuilt with .NET Framework 1.1
It requires .NET Framework 1.1, 2.0, 3.5 or later version.
EAGetMail20.dllBuilt with .NET Framework 2.0
It requires .NET Framework 2.0, 3.5 or later version.
EAGetMail35.dllBuilt with .NET Framework 3.5
It requires .NET Framework 3.5 or later version.
EAGetMail40.dllBuilt with .NET Framework 4.0
It requires .NET Framework 4.0 or later version.
EAGetMailCF20.dllBuilt with .NET Compact Framework 2.0
It requires .NET Compact Framework 2.0, 3.5 or later version.
EAGetMailCF35.dllBuilt with .NET Compact Framework 3.5
It requires .NET Compact Framework 3.5 or later version.


// The following example codes demonstrate retrieving email from Gmail IMAP4 server
// To get full sample projects, please download and install EAGetMail on your machine.
// To run it correctly, please change email server, user, password, folder, file name value to yours

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

// Add EAGetMail namespace
using EAGetMail;

namespace receiveemail
{
    class Program
    {
        static void Main(string[] args)
        {
            // Create a folder named "inbox" under current directory
            // to save the email retrieved.
            string curpath = Directory.GetCurrentDirectory();
            string mailbox = String.Format("{0}\\inbox", curpath);

            // If the folder is not existed, create it.
            if (!Directory.Exists(mailbox))
            {
                Directory.CreateDirectory(mailbox);
            }

            // Gmail IMAP4 server is "imap.gmail.com"
            MailServer oServer = new MailServer("imap.gmail.com",
                        "gmailid@gmail.com""yourpassword", ServerProtocol.Imap4 );
            MailClient oClient = new MailClient("TryIt");

            // Set SSL connection,
            oServer.SSLConnection = true;

            // Set 993 IMAP4 port
            oServer.Port = 993;

            try
            {
                oClient.Connect(oServer);
                MailInfo[] infos = oClient.GetMailInfos();
                for (int i = 0; i < infos.Length; i++)
                {
                    MailInfo info = infos[i];
                    Console.WriteLine("Index: {0}; Size: {1}; UIDL: {2}",
                        info.Index, info.Size, info.UIDL);

                    // Receive email from GMail IMAP4 server
                    Mail oMail = oClient.GetMail(info);

                    Console.WriteLine("From: {0}", oMail.From.ToString());
                    Console.WriteLine("Subject: {0}\r\n", oMail.Subject);

                    // Generate an email file name based on date time.
                    System.DateTime d = System.DateTime.Now;
                    System.Globalization.CultureInfo cur = new
                        System.Globalization.CultureInfo("en-US");
                    string sdate = d.ToString("yyyyMMddHHmmss", cur);
                    string fileName = String.Format("{0}\\{1}{2}{3}.eml",
                        mailbox, sdate, d.Millisecond.ToString("d3"), i);

                    // Save email to local disk
                    oMail.SaveAs(fileName, true);

                    // Mark email as deleted in GMail account.
                    oClient.Delete(info);
                }

                // Quit and pure emails marked as deleted from Gmail IMAP4 server.
                oClient.Quit();
            }
            catch (Exception ep)
            {
                Console.WriteLine(ep.Message);
            }

        }
    }