开发者

How to have a webmethod POST to an HTTPHandler.ashx file

Summary

How to create an HTTPContext within a webservice? or POST to a Handler.ashx from a webservice?

Background

I have a Cold Fusion web application that uses Forms authentication but somehow achieves Windows authentication with this script:

<cfscript>
    ws = CreateObject("webservice", "#qTrim.webServiceName#");
    ws.setUsername("#qTrim.trimAcct#");
    ws.setPassword("#qTrim.trimpwd#");
    wsString=ws.UploadFileCF("#qTrim.webserviceurl#","#objBinaryData#", "#qFiles.Filename#", "Document", "#MetaData#");
</cfscript>
  • Apparently, the setUsername/setPassword values map to a single Windows domain account and this works in production. (The webservice is written in C# and built with .Net 4.0. and it must be used by this domain account)
  • I developed a DownloadHandler.ashx which works when POSTed to by a process which is running under this domain account (I have a .Net web client with a button that defines PostBackUrl="~/DownloadHandler.ashx"). This HTTPHandler grabs a few items from the HTTPContext and then calls the above webservice method DownloadFile without problems.

My Problem Now this ColdFusion app needs to download a file using this webservice. When the CF code POSTs an HTML form to the DownloadHandler.ashx it works - BUT ONLY IF the CF tester is using this Windows domain account. This won't work in production because the CF app supp开发者_如何转开发orts remote anonymous users through forms authentication.

Question

Not knowing ColdFusion myself, I was thinking of the following changes:

  • Replicate the above CF technique such that user/pswd can be set the same and have CF invoke the ws.DownloadFile method directly

  • I think this would require using most of my current HTTPHandler code in my webservice but I cannot think of how to handle the output. When this handler is POSTed to, it prompts for OPEN or Save and works nicely but I'm confused on how I would stream this back from the webservice itself.

  • The current DownloadFile webmethod communicates with a database product and returns output to this (the current) handler:

Code

namespace WebClient
{
    public class DownloadHandler : IHttpHandler
    {
    ASMXproxy.FileService brokerService;
    public void ProcessRequest(HttpContext context)
    {
         brokerService = new ASMXproxy.FileService();
         string recNumber = context.Request.Form["txtRecordNumber"];
         brokerService.Url = context.Request.Form["txtURL"];
         string trimURL = context.Request.Form["txtFakeURLParm"];  // not a real URL but parms to connect to TRIM
         brokerService.Timeout = 9999999;
         brokerService.Credentials = System.Net.CredentialCache.DefaultCredentials;
         byte[] docContent;
         string fileType;
         string fileName;
         string msgInfo = brokerService.DownloadFile(trimURL, recNumber, out docContent, out fileType, out fileName);
         string ContentType = MIMEType.MimeType(fileType);
         context.Response.AppendHeader("Content-Length", docContent.Length.ToString());
         context.Response.AppendHeader("content-disposition", "attachment; filename=\"" + fileName + "\"");
         context.Response.ContentType = ContentType;
         context.Response.OutputStream.Write(docContent, 0, docContent.Length);
         context.Response.OutputStream.Flush();
     }
     public bool IsReusable
     {
         get
        {
             return false;
        }
     }
     }
}


Assuming your CF site is running on IIS and not Apache or some other web server, this might work:

Put your .cfm file that calls the webservice into its own subfolder on your site. Set the Authentication properties of that folder to use Anonymous Authentication, but set the user identity to the Windows Domain account that successfully calls the webservice (click the Set... button on the dialog shown below and enter the appropriate credentials).

How to have a webmethod POST to an HTTPHandler.ashx file

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜