Добрый день! Я провел половину своего дня, пытаясь понять это; надеюсь, один из вас сможет помочь.
Я написал ограниченную 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?
Я использую 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>
Если вы позвоните в службу, например, SoapUI - это возвращает строку в ожидаемом формате? Или, может быть, некоторые теги и / или специальные символы могут быть искажены?
В SoapUI он также не может правильно отображаться, возникает та же ошибка, что и в WCF.