1

For reasons beyond this question, I cannot have a form on this page with a runat="server" attribute.

How do I go about accessing an uploaded file uploaded using a regular <input type="file"...?

This question touches on the issue, (using an <input type="file" rather than an <asp:FileUpload), however they still both runat=server.

The types of things I would like to be able to acheive (server side, after the form has been posted), include:

  • if (MyInput.HasFile) ...
  • var fileName = MyInput.FileName;
  • var fullPathAndFile = MyInput.PostedFile.FileName;
  • var mimeType = MyInput.PostedFile.ContentType;

I'm sure all of this stuff can be done, I'm just used to .NET taking care of all of this for me!

Update: after the insightful comments below, I seem to be doing things in an odd manner...

I was originally looking for something along the lines of:

HttpPostedFile file = Request.Files["myFile"];
//accessing the file without having the element itself being runat="server", e.g. manually through the Request.
//(I know this doesn't work without runat="server", just an example to clarify my question)

//if(MyFile.HasFile) ...
if (file != null && file.ContentLength) ...

//var fName = MyFile.FileName
var fName = Path.GetFileName(file.FileName);

But it seems that even that requires runat="server"

Community
  • 1
  • 1
elwyn
  • 10,360
  • 11
  • 42
  • 52
  • I've provided an answer below, but why you would want to do this is beyond me. Even if you use a Html control, the only way you can provide server-side logic for it is by adding runat="server" anyway... – IrishChieftain Apr 29 '11 at 00:59

2 Answers2

2

Create a custom HtmlForm and toggle it on and off as follows:

Custom HtmlForm:

using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;


namespace CustomForm
{
    public class GhostForm : System.Web.UI.HtmlControls.HtmlForm
    {
        protected bool _render;

        public bool RenderFormTag
        {
            get { return _render; }
            set { _render = value; }
        }

        public GhostForm()
        {
            //By default, show the form tag
            _render = true;
        }

        protected override void RenderBeginTag(HtmlTextWriter writer)
        {
            //Only render the tag when _render is set to true
            if (_render)
                base.RenderBeginTag(writer);
        }     

        protected override void RenderEndTag(HtmlTextWriter writer)
        {
            //Only render the tag when _render is set to true
            if (_render)
                base.RenderEndTag(writer);
        }
    }
}

Usage:

public partial class MyClass : System.Web.UI.Page
  {
      protected void Page_Load(object sender, EventArgs e)
      {
          GhostForm mainForm = new GhostForm();
          mainForm.RenderFormTag = false;
            .....    
      }
          // Upload your file, etc.
      .....
  }
IrishChieftain
  • 15,108
  • 7
  • 50
  • 91
  • Could you please explain what this does? As I understand, it creates an overridden form which you can opt to not render `
    ` tags, correct? How do I do my upload then? I would end up with a bunch of elements not wrapped in form tags?
    – elwyn Apr 29 '11 at 00:57
  • Correct. I'm having a hard time understanding the question; how would you end up with "another form" in the first place? – IrishChieftain Apr 29 '11 at 01:02
  • Thanks - I have clarified my 'issue' a bit more in the comments on Jonathan Wood's answer, which has helped me understand things a bit better! – elwyn Apr 29 '11 at 01:29
  • No prob. ASP.NET Web Forms use a single form and this often causes problems for example when someone is trying to use PayPal - that's what I use the above code for :-) – IrishChieftain Apr 29 '11 at 02:40
1

This question seems a little confused.

First off, what do you mean about having another form on a page? ASP.NET pages should have exactly one form (with or without runat="server").

This wording makes me think you have another issue that should be addressed first. It's extremely unusual to have a valid reason for more than one form on an ASP.NET page.

But if this is what you really need, then remove the ASP.NET tags to your question and replace them with HTML as this would have nothing to do with ASP.NET.

Jonathan Wood
  • 65,341
  • 71
  • 269
  • 466
  • I guess I emphasised the uploading part of the issue too much - I am more interested in how to process a file in the backend, less interested in the HTML side of things. – elwyn Apr 29 '11 at 00:36
  • And as for when you would have multiple forms on a page: a search form+login form(+hidden register form) in the main page layout, then another form in the page content itself. + maybe a filter form to refine your search/some content. Am I missing something about not having multiple forms on a page? I mean, I know you can only have one form with runat="server" (unless you wrap them in ` – elwyn Apr 29 '11 at 00:41
  • @elwyn: I'm concerned you *are* missing something, yes. ASP.NET has a postback mechanism that gives you individual callback methods for any number of buttons on your page. It was designed such that these would all be placed within a single form. As far as the reason, the problem you are having is the perfect example of why a single form is best. Multiple forms also impose limitations on where you can place controls because you need to ensure they are in the right form. – Jonathan Wood Apr 29 '11 at 01:03
  • I see, so best practice would be to wrap every form input in a single form, and then use server side logic to determine the action? It seems, uh, "unsemantic" to (for example) post a Register form to the same action as my search form. And how do you then handle a single form that needs to POST & GET? (e.g. a page that has a global Search in the top corner (GET) and a Register form in the content (POST)? Edit: Would I have a 'man in the middle' to receive my form submissions, which then makes the correct POST/GET request to the correct action? – elwyn Apr 29 '11 at 01:12
  • @elwyn: Correct. I guess you could say ASP.NET is somewhat "unsemantic". But if you use ASP.NET, may as well take advantage of it. To handle a GET, either redirect from your postback handler, or turn your button to a regular hyper link (with any needed arguments) or put javascript in the `onclick` attribute. – Jonathan Wood Apr 29 '11 at 01:16
  • A couple of other thoughts if you want to make your page behave as though it has multiple forms. First, if you have any validation controls on your page, you'll need to make sure they aren't firing for unrelated buttons. Second, if you want to be able to hit your submit button by pressing enter when focus is in a related control, use a panel. – Jonathan Wood Apr 29 '11 at 01:24
  • OK. I still don't totally understand why I would use a single form, dividing up each semantic section with Panels, with a middle service for receiving and interpreting requests/making new requests, instead of using multiple forms on a page (inside Panels so each runat="server" works), each using its OWN validation, own submit button, own action, and own request type. Other than "it isn't the asp.net way of doing things". It seems much cleaner, simpler, and more semantic. – elwyn Apr 29 '11 at 01:28
  • 1
    Panels are only needed where you want a default submit button. For GET, just use javascript in an HTML button to set the current HREF. The reason is so you don't run into problems like you are. This is the approach I use in ASP.NET pages, and I have the freedom to place any button at any location. I don't need to worry about keeping it in this or that form, or which forms will have the `runat="server"` attribute. And if you really don't like that (which I can understand), maybe you'll like MVC better. – Jonathan Wood Apr 29 '11 at 01:31
  • I see. I generally build my sites to have basic functionality (meaning, form submissions), work without JS, so not really an acceptable solution. I do understand the issue a lot more now, thanks, I'll just continue avoiding non MVC asp.net in the future :p And I do like MVC much much more :) – elwyn Apr 29 '11 at 02:41