views:

1725

answers:

3

I've already written an HTTPHandler that gets POSTed from a ColdFusion page and it works successfully; now, I am trying to write a web application in ASP.NET so I can post a form to the .ashx handler from an .aspx page.

Application Trace (trace.axd) shows the following as my last 3 entries:

2 8/14/2009 1:53:56 PM /Default.aspx       200 GET View Details 
3 8/14/2009 1:54:04 PM /Default.aspx       200 POST View Details 
4 8/14/2009 1:54:13 PM /UploadHandler.ashx 401 POST View Details

I have a breakpoint in my .ashx file but it is never reached (I guess because of the 401 status code). Here is the snippet of code from the default.aspx trying to POST to the handler:

protected void UploadHandlerButton_Click(object sender, EventArgs e)
{
    if (FileUpload1.HasFile)
    {
        try
        {
            ASCIIEncoding encoding = new ASCIIEncoding();
            byte[] data = encoding.GetBytes(BuildFormData());
            string baseAddress = "http://" + Environment.MachineName;
            string pathInfo = Page.ResolveUrl("UploadHandler.ashx");
            string URI = baseAddress + pathInfo;
            HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(URI);
            myRequest.Method = "POST";
            myRequest.ContentType = "application/x-www-form-urlencoded";
            myRequest.ContentLength = data.Length;
            Stream newStream = myRequest.GetRequestStream();
            newStream.Write(data, 0, data.Length);
            newStream.Close();
        }
        catch (Exception someError)
        {
            LogText("FAILURE: " + someError.Message);
        }
    }
}

Here is a snippet of code from the UploadHandler.ashx file (but this doesn't appear to be reached):

public void ProcessRequest(HttpContext context)
    {
        string returnURL = context.Request.ServerVariables["HTTP_REFERER"];
        string message;
        message = UploadFile(context);
        StringBuilder msgReturn = new StringBuilder(returnURL);
        msgReturn.Append("?n=");
        msgReturn.Append(HttpUtility.UrlEncode(TRIMrecNumAssigned));
        msgReturn.Append("&m=");
        msgReturn.Append(HttpUtility.UrlEncode(message));
        context.Response.Redirect(msgReturn.ToString());
    }

Both default.aspx and UploadHandler.ashx are in the root of a virtual directory on my localhost; the directory security is currently set to "Anonymous access" CHECKED and "Integrated Windows authentication" CHECKED.

When I click the "View Details" link on the trace.axd display, I see all the data in the Forms collection that I expect to see and hope to process but this 401 seems to be stopping everything. I could post the code for my little function called BuildFormData() if useful.

EDIT: Revised handler as follows (has had no effect; same error occurs):

public void ProcessRequest(HttpContext context)
    {
        //-----------------------------------------------------------------------------------------
        // the remainder of this block is alternative to the .Redirect and is useful for debugging.
        context.Response.ContentType = "text/html";
        //context.Response.Write(TRIMrecNumAssigned);
        //context.Response.Write("<p>");
        //context.Response.Write(msgReturn);
        context.Response.Write("<H1>Trim - Kerberos Prototype for ColdFusion consuming pages</h1>");
        HttpContext.Current.Trace.IsEnabled = true;
        HttpContext.Current.Trace.Write(null);
        HttpContext.Current.Trace.Write("-------");
        HttpContext.Current.Trace.Write(context.Request.Form["txtTrimRecordType"]);
        HttpContext.Current.Trace.Write(GetUserInfo());
        HttpContext.Current.Trace.Write("-------");
        HttpContext.Current.Trace.Write(null);
        using (Html32TextWriter htw = new Html32TextWriter(context.Response.Output))
        {
            typeof(TraceContext)
                .GetMethod("Render", BindingFlags.NonPublic | BindingFlags.Instance)
               .Invoke(HttpContext.Current.Trace, new object[] { htw });
        }
    }
A: 

Looking at your ProcessRequest(), you do the following:

string returnURL = context.Request.ServerVariables["HTTP_REFERER"];

Based on how you are calling it with HttpWebRequest, this variable will be null. Then when you create your msgReturn, it will look something like this:

?n=XXX%m=YYY

When you redirect to this URL, it will probably not be found which is what is returning the 401.

Keltex
Thanks. Your point seems valid but can you comment more about why I am not even stopping on the line you show. That is, why the 401 occurs and how I could fix that. I will worry about the return to the POSTer later.
John Galt
What happens when you remove context.Response.Redirect(msgReturn.ToString());?
Keltex
Please see my EDIT on the question where I show my revised ProcessRequest() in the .ashx file.....trace.axd shows the same 401 error occurring however so this does not seem to matter so far.
John Galt
A: 

Have you tried turning off Integrated Windows Auth and just leaving anonymous checked? Does it make a difference?

Your answer: "I think it made things worse because now I cannot even browse to default.aspx. I get this: HTTP 401.3 - Access denied by ACL on resource Internet Information Services"

My response: This is actually a good thing. This means we're getting closer to what is going on. If you're getting that error message and the only thing you have enabled is anonymous authentication via IIS, that means that the ASP.NET impersonation user doesn't have NTFS permissions on the files in question.

I'm not sure if you are on XP or Win 2k3, but now you want to check and make sure that either the ASPNET (XP) or Network Service (Win 2k3) users have at least read access on the files in question. Make sure that user has at least that level of access and then let me know how it goes.

Update: I don't know why I didn't think of this before. You may need to set credentials on your HttpWebRequest. To use the credentials of the current user, try adding this to your request.

HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(URI);
myRequest.Credentials = CredentialCache.DefaultCredentials;

If you need to add different credentials you can try Network Credentials

There's a good explanation of credentials here.

Hope this helps.

thinkzig
Although skeptical (I want to debug the .ashx file and I think the Vstudio debugger requires Int.Win.Auth), I thought I'd try your idea. I think it made things worse because now I cannot even browse to default.aspx. I get this: HTTP 401.3 - Access denied by ACL on resource Internet Information Services
John Galt
John Galt
John Galt
A: 

Hi, I have a similar issue: I cannot access the .ashx file for the first time. When I press the link (which is good) I got the error: File Not Found. … at System.Web.HttpApplication.ExecuteStep System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute. Any idea what happened, and how to fix it?

grig