1

J'ai déjà écrit un HTTPHandler qui est POSTé à partir d'une page ColdFusion et fonctionne correctement; maintenant, j'essaye d'écrire une application web dans ASP.NET pour pouvoir poster un formulaire au gestionnaire .ashx à partir d'une page .aspx.Pourquoi mon post httpwebrequest sur myhandler.ashx est-il rejeté avec le code d'état 401

Trace (Application trace.axd) montre ce qui suit comme mes dernières 3 entrées:

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 

J'ai un point d'arrêt dans mon fichier .ashx mais il est jamais atteint (je suppose à cause du code d'état 401). Voici l'extrait de code de la default.aspx essayant de POST au gestionnaire:

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); 
     } 
    } 
} 

Voici un extrait de code du fichier UploadHandler.ashx (mais cela ne semble pas être atteint):

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()); 
    } 

default.aspx et UploadHandler.ashx sont à la racine d'un répertoire virtuel sur mon localhost; la sécurité du répertoire est actuellement définie sur "Accès anonyme" CHECKED et "Authentification Windows intégrée" CHECKED. Lorsque je clique sur le lien "Afficher les détails" sur l'affichage de trace.axd, je vois toutes les données de la collection Forms que je m'attends à voir et que j'espère traiter, mais ce 401 semble tout arrêter. Je pourrais poster le code pour ma petite fonction appelée BuildFormData() si utile.

EDIT: gestionnaire révisé comme suit (n'a eu aucun effet, même erreur se produit):

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 }); 
     } 
    } 

Répondre

0

En regardant votre ProcessRequest(), vous effectuez les opérations suivantes:

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

Basé sur la façon dont vous l'appelez avec HttpWebRequest, cette variable sera null. Ensuite, lorsque vous créez votre msgReturn, il ressemblera à quelque chose comme ceci:

?n=XXX%m=YYY 

Lorsque vous redirigez à cette URL, il se trouve probablement pas qui est ce qui est le retour 401.

+0

Merci. Votre point de vue semble valable, mais pouvez-vous en dire plus sur les raisons pour lesquelles je ne m'arrête même pas sur la ligne que vous montrez. C'est pourquoi le 401 se produit et comment je pourrais régler cela. Je vais m'inquiéter du retour au POSTER plus tard. –

+0

Que se passe-t-il lorsque vous supprimez context.Response.Redirect (msgReturn.ToString()) ;? – Keltex

+0

S'il vous plaît voir mon EDIT sur la question où je montre mon ProcessRequest révisé() dans le fichier .ashx ..... trace.axd montre la même erreur 401 survenant cependant si cela ne semble pas d'importance jusqu'à présent. –

1

Avez-vous essayé tourner Désactivé Windows Auth intégré et juste en laissant anonyme vérifié? Est-ce que cela fait une différence?

Votre réponse: « Je pense qu'il a fait empirer les choses parce que maintenant je ne peux pas parcourir même default.aspx je reçois ceci:. HTTP 401.3 - Accès refusé par ACL sur la ressource Internet Information Services »

Mon réponse: C'est en fait une bonne chose. Cela signifie que nous nous rapprochons de ce qui se passe. Si vous obtenez ce message d'erreur et la seule chose que vous avez activée est l'authentification anonyme via IIS, cela signifie que l'utilisateur d'emprunt d'identité ASP.NET n'a pas d'autorisations NTFS sur les fichiers en question. Je ne suis pas sûr si vous êtes sur XP ou Win 2k3, mais maintenant vous voulez vérifier et assurez-vous que les utilisateurs ASPNET (XP) ou Network Service (Win 2k3) ont au moins un accès en lecture sur les fichiers Dans la question. Assurez-vous que l'utilisateur a au moins ce niveau d'accès et laissez-moi savoir comment ça se passe.

Mise à jour: Je ne sais pas pourquoi je n'avais pas pensé à cela avant. Vous devrez peut-être définir des informations d'identification sur votre HttpWebRequest. Pour utiliser les informations d'identification de l'utilisateur actuel, essayez d'ajouter ceci à votre demande.

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

Si vous devez ajouter différentes informations d'identification, vous pouvez essayer Network Credentials

Il y a un good explanation of credentials here.

Espérons que cela aide.

+0

Bien que sceptique (je veux déboguer le fichier .ashx et je pense que le débogueur Vstudio nécessite Int.Win.Auth), j'ai pensé que j'essaierais votre idée. Je pense que ça a empiré les choses parce que maintenant je ne peux même pas naviguer vers default.aspx. Je reçois ceci: HTTP 401.3 - Accès refusé par ACL sur la ressource Internet Information Services –

+0

Merci pour votre temps à ce sujet. Je cours sur mon propre PC de développement appelé JOHNXP qui exécute XP et IIS 5.1. Le répertoire virtuel est appelé HTTPHandleTRIM qui pointe vers le chemin local: C: \ Documents and Settings \ johna \ Mes documents \ Visual Studio 2005 \ Projects \ HandlersTRIM D'abord, j'ai ajouté JOHNXP \ ASPNET au dossier HandlersTRIM ci-dessus et lui ai donné autorisations pour "Lire et exécuter", "Liste des dossiers" et "Lire". Ensuite, avec Anonymous activé ET intégré Windows Auth également vérifié, j'ai obtenu le même résultat (un 401 essayant de POST à ​​UploadHandler.ashx). Ensuite, j'ai décoché "Integrated Windows Auth". (cont'd) –

+0

Avec "IWA" non coché, je n'ai même pas pu naviguer vers ma page default.aspx. Donc, j'ai ajouté IUSR_JOHNXP et donné à l'utilisateur anonyme les mêmes permissions que ci-dessus ("Read & Execute", etc.). Maintenant, au lieu d'un 401, j'obtiens un 302. Est-il possible d'obtenir des codes de raison plus détaillés ou des codes de sous-statut pour ces erreurs? MyRequest.Credentials = CredentialCache.DefaultCredentials; –