2009-07-29 4 views
1

Bon après-midi! J'ai passé la moitié de ma journée à essayer de comprendre cela; J'espère que l'un d'entre vous peut aider.RenderControl à partir du service WCF échoue; ASMX fonctionne

J'ai écrit un CMS limité et je travaille pour permettre l'affichage du contenu du CMS sous forme de pages interstitielles dans des sites externes. Pour ce faire, je voulais créer un service WCF qui rendrait le contenu approprié et le renvoyer sous la forme d'une chaîne à placer dans la page du client.

Cependant, j'ai rencontré un comportement étrange. Les contrôles RadioButtonList et CheckBoxList finissent par lancer un NullReferenceException pendant RenderControlInternal (évidemment pas ma contribution). Tous les autres contrôles (zones de texte, zones de liste, listes déroulantes, contrôles composites personnalisés) s'affichent correctement.

J'ai créé un service ASMX à côté du service WCF, et couper/coller le code directement à partir du service WCF. Il rend les contrôles parfaitement.

Des indices indiquant pourquoi le service WCF provoque sélectivement des bombes?

Voici le code de la méthode de service:

public string RenderPageContents(int pageId) 
    { 
     string output = string.Empty; 

     SiteBuilder.Page p = new SiteBuilder.Page(); 
     if (p.Load(pageId)) 
     { 
      foreach (SiteBuilder.PageItem pi in p.Items) 
      { 
       if (pi.LoadItemDetails(true)) 
       { 
        // Calls LoadControl from \Bin 
        Web.Controls.Base.BuilderControlBase bcb = 
          Web.Controls.ControlHelper.CreateSiteBuilderControl(
           @"C:\Development\SitebuilderService\", 
          pi.ItemDetails); 

        if (bcb != null) 
        { 
         bcb.Configure(pi); 
         output += ControlHelper.RenderControl(ref bcb); 
        } 
       } 
      } 
     } 

     return output; 
    } 

Voici le code pour ControlHelper.RenderControl (oui, il est en VB Il vit dans un autre projet.).

Public Shared Function RenderControl(ByRef ctrl As Controls.Base.BuilderControlBase) _ 
     As String 
    Dim sb As New StringBuilder() 
    Dim tw As New StringWriter(sb) 
    Dim hw As New HtmlTextWriter(tw) 

    ctrl.RenderControl(hw) 

    Return sb.ToString() 
End Function 

Le message d'exception est "Référence d'objet non définie sur une instance d'un objet".

Voici une stacktrace de l'exception levée lorsque WCF est utilisé:

at System.Web.UI.WebControls.RadioButtonList.Render(HtmlTextWriter writer) 
at System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) 
at System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) 
at System.Web.UI.Control.RenderControl(HtmlTextWriter writer) 
at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) 
at System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) 
at System.Web.UI.WebControls.TableCell.RenderContents(HtmlTextWriter writer) 
at System.Web.UI.WebControls.WebControl.Render(HtmlTextWriter writer) 
at System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) 
at System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) 
at System.Web.UI.Control.RenderControl(HtmlTextWriter writer) 
at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) 
at System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) 
at System.Web.UI.WebControls.WebControl.RenderContents(HtmlTextWriter writer) 
at System.Web.UI.WebControls.WebControl.Render(HtmlTextWriter writer) 
at System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) 
at System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) 
at System.Web.UI.Control.RenderControl(HtmlTextWriter writer) 
at System.Web.UI.WebControls.Table.RenderContents(HtmlTextWriter writer) 
at System.Web.UI.WebControls.WebControl.Render(HtmlTextWriter writer) 
at System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) 
at System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) 
at System.Web.UI.Control.RenderControl(HtmlTextWriter writer) 
at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) 
at System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) 
at System.Web.UI.WebControls.TableCell.RenderContents(HtmlTextWriter writer) 
at System.Web.UI.WebControls.WebControl.Render(HtmlTextWriter writer) 
at System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) 
at System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) 
at System.Web.UI.Control.RenderControl(HtmlTextWriter writer) 
at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) 
at System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) 
at System.Web.UI.WebControls.WebControl.RenderContents(HtmlTextWriter writer) 
at System.Web.UI.WebControls.WebControl.Render(HtmlTextWriter writer) 
at System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) 
at System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) 
at System.Web.UI.Control.RenderControl(HtmlTextWriter writer) 
at XXX.ControlHelper.RenderControl(BuilderControlBase& ctrl) 
    in C:\TFS\XXX\Development\XXX\Web\Controls\Builder\Helpers\ControlHelper.vb:line 81 
at XXX.Services.SiteBuilderService.RenderPageContents(Int32 pageId) 
    in C:\TFS\Development\XXX.Web.Services\XXX.Web.Services\SiteBuilderService.svc.cs:line 61 

Est-ce que le service WCF retourne la chaîne correcte lorsqu'il est appelé séparément?

Je ne suis pas sûr de comprendre votre sens exact. Séparément de quoi? Si j'appelle la classe business qui effectue le traitement depuis un harnais de test, oui cela fonctionne correctement. Quand je l'appelle depuis un service ASMX, cela fonctionne correctement. De WCF, les ruptures de rendu de radiobutton. Quel type de liaison et de sécurité utilisez-vous pour le service WCF?

J'utilise basicHttpBinding.

<binding name="BasicHttpBinding_ISiteBuilderService" closeTimeout="00:01:00" 
       openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" 
       allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" 
       maxBufferSize="1024000" maxBufferPoolSize="524288" maxReceivedMessageSize="1024000" 
       messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" 
       useDefaultWebProxy="true"> 
     <readerQuotas maxDepth="32" maxStringContentLength="1024000" maxArrayLength="16384" 
      maxBytesPerRead="4096" maxNameTableCharCount="16384" /> 
     <security mode="None"> 
     <transport clientCredentialType="None" proxyCredentialType="None" 
      realm="" /> 
     <message clientCredentialType="UserName" algorithmSuite="Default" /> 
     </security> 
    </binding> 


<endpoint address="" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ISiteBuilderService" contract="SiteBuilder.ISiteBuilderService" name="BasicHttpBinding_ISiteBuilderService" /> 

<service behaviorConfiguration="Xxx.SiteBuilderServiceBehavior" 
    name="Xxx.Services.SiteBuilderService"> 
    <endpoint address="" binding="basicHttpBinding" contract="Kaplan.OEC.Services.ISiteBuilderService"> 
     <identity> 
     <dns value="localhost" /> 
     </identity> 
    </endpoint> 
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
    </service> 

<behavior name="Xxx.Services.SiteBuilderServiceBehavior"> 
     <serviceMetadata httpGetEnabled="true" /> 
     <serviceDebug includeExceptionDetailInFaults="true" /> 
    </behavior> 

Si vous appelez le service par exemple SoapUI - renvoie-t-il la chaîne dans le format attendu? Ou peut-être que certaines étiquettes et/ou caractères spéciaux pourraient être endommagés? À partir de SoapUI, il échoue également à afficher correctement, la même erreur se produit à partir de WCF.

Répondre

0

Le service WCF renvoie-t-il la chaîne correcte lorsqu'il est appelé séparément? Quel type de liaison et de sécurité utilisez-vous pour le service WCF? Pouvez-vous poster quelques configs (côté serveur, et éventuellement côté client)?

La liaison qui serait la plus proche du service ASMX hérité serait basicHttpBinding avec essentiellement toutes les sécurité désactivées. Utilisez-vous cela?

Si vous appelez le service par ex. SoapUI - renvoie-t-il la chaîne dans le format attendu? Ou peut-être que certaines étiquettes et/ou caractères spéciaux pourraient être endommagés?

2

Avez-vous essayé d'activer ASP.NET compatibility mode dans votre configuration WCF? L'erreur est probablement liée au fait que HttpContext n'est pas disponible (même si je peux le dire, votre approche actuelle, bien que probablement réalisable, est plutôt moche :-))

+0

Je suppose que cela pourrait être le problème. J'ai ouvert System.Web.UI.WebControls.RadioButtonList.Render en utilisant .NET Reflector et trouvé ce code: "If (Not MyBase.DesignMode AndAlso Not Me.Context.Request.Browser.Tables) Puis". Si vous regardez dans Context, si page.Context est null, elle renvoie HttpContext.Current. –

+0

Ou puisque la plupart des questions ont été postées en C#: if (! Base.DesignMode &&! This.Context.Request.Browser.Tables) –

Questions connexes