Добрый день! Я потратил полдня, пытаясь понять это; надеюсь, один из вас может помочь.

Я написал ограниченную CMS и работаю над тем, чтобы контент из CMS отображался в виде промежуточных страниц на внешних сайтах. Для этого я хотел создать службу WCF, которая будет отображать соответствующий контент и возвращать его в виде строки для размещения на странице клиента.

Однако я столкнулся со странным поведением. Элементы управления RadioButtonList и CheckBoxList в конечном итоге выдают NullReferenceException во время RenderControlInternal (очевидно, это не мой вклад). Все остальные элементы управления (текстовые поля, списки, раскрывающиеся списки, настраиваемые составные элементы управления) отображаются нормально.

Я создал службу ASMX вместе со службой WCF и вырезал/вставлял код непосредственно из службы WCF. Он отлично передает элементы управления.

Любые подсказки, почему служба WCF выборочно вызывает бомбы?

Вот код метода обслуживания:

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

Вот код для ControlHelper.RenderControl (да, это в VB. Он живет в другом проекте).

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

Сообщение об исключении: «Ссылка на объект не указывает на экземпляр объекта».

Вот трассировка стека исключения, возникающего при использовании WCF:

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

Возвращает ли служба WCF правильную строку при отдельном вызове?

Я не уверен, что понимаю ваш точный смысл. Отдельно от чего? Если я вызову бизнес-класс, который выполняет обработку из тестового жгута, да, он работает правильно. Когда я вызываю его из службы ASMX, он работает правильно. В WCF рендеринг радиокнопок прерывается.

Какую привязку и безопасность вы используете для службы WCF?

Я использую базовую привязку HttpBinding.

<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>

Если вы позвоните в службу, например, в SoapUI - возвращает ли строка в ожидаемом формате? Или, может быть, некоторые теги и / или специальные символы могут быть искажены?

Из SoapUI он также не отображается должным образом, возникает та же ошибка, что и из WCF.

1
Chris 30 Июл 2009 в 00:32

2 ответа

Вы пытались включить режим совместимости с ASP.NET в конфигурации WCF? ? Ошибка, вероятно, связана с тем, что HttpContext недоступен (хотя, если я могу сказать, ваш текущий подход, хотя, вероятно, и работоспособен, довольно уродлив :-))

2
tomasr 30 Июл 2009 в 01:58
Подозреваю, что дело может быть в этом. Я открыл System.Web.UI.WebControls.RadioButtonList.Render с помощью .NET Reflector и нашел этот код: «Если (не MyBase.DesignMode AndAlso Not Me.Context.Request.Browser.Tables) Then». Глядя в контекст, если page.Context имеет значение null, он возвращает HttpContext.Current.
 – 
Chris Porter
30 Июл 2009 в 02:07
Или, поскольку большая часть вопроса была опубликована на С#: if (!base.DesignMode && !this.Context.Request.Browser.Tables)
 – 
Chris Porter
30 Июл 2009 в 02:08

Возвращает ли служба WCF правильную строку при отдельном вызове? Какую привязку и безопасность вы используете для службы WCF? Можете ли вы опубликовать некоторые конфигурации (на стороне сервера и, возможно, на стороне клиента)?

Привязка, которая будет наиболее близка к устаревшей службе ASMX, будет basicHttpBinding с практически отключенной системой безопасности. Вы используете это?

Если вы позвоните в службу, например, в SoapUI - возвращает ли строка в ожидаемом формате? Или, может быть, некоторые теги и / или специальные символы могут быть искажены?

0
John Saunders 16 Ноя 2013 в 04:33