我使用委託來允許我的服務獲取存儲在表單中的字符串。 當我運行代碼,我的服務日誌規定如下:對象引用未設置爲對象的實例 - WCF服務和委託(實例化委託之前託管的WCF)
System.NullReferenceException: Object reference not set to an instance of an object.
對diData.DIDataCompressed = GetDIData();
我想在我的窗體的構造在DataServer = new ModelDataService();
設置斷點指點。並注意到我的WCF服務在我的窗體的構造函數的代碼運行之前已經啓動(我從托盤中的WcfSvcHost彈出,並且在WCF服務主機窗口中它已經啓動了ModelDataService),所以委託顯然未被實例化。 更新:在我的Program.cs中的Main()方法被調用(啓動表單的方法)之前,服務正在啓動。另外,我的解決方案的唯一啓動項目就是我的表單!
如何讓我的WCF服務只在我的表單加載時啓動(這樣我才能正確設置代理)?
這裏是我的WCF服務代碼:
[ServiceBehavior(UseSynchronizationContext = false, InstanceContextMode = InstanceContextMode.Single)]
public class ModelDataService : IModelData
{
public delegate string GetData();
public GetData GetDIData { get; set; }
public ModelDataService()
{
}
public DIData GetDData()
{
DIData diData = new DIData();
diData.DIDataCompressed = GetDIData(); // **** error points here
return diData;
}
}
[DataContract]
public class DIData
{
[DataMember]
public string DIDataCompressed;
}
而且我的狀態代碼,應該啓動該服務:
public partial class ScraperForm : Form
{
ServiceHost Host;
ModelDataService DataServer;
string DIData;
public ScraperForm()
{
InitializeComponent();
#region Start Data Server
DataServer = new ModelDataService(); // I set breakpoint here
DataServer.GetDIData = new ModelDataService.GetData(this.GetDIData);
Host = new ServiceHost(DataServer, new Uri[]
{
new Uri("http://localhost:8000")
});
Host.AddServiceEndpoint(typeof(IModelData),
new BasicHttpBinding(),
"ModelData");
Host.Open();
#endregion
DIData = "";
}
public string GetDIData()
{
return DIData; // This is updated on a timer
}
我的App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" />
</system.web>
<!-- When deploying the service library project, the content of the config file must be added to the host's
app.config file. System.Configuration does not support config files for libraries. -->
<system.serviceModel>
<services>
<service name="SoccerModelService.ModelDataService">
<endpoint address="" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding"
contract="SoccerModelService.IModelData"
name ="BasicHttpBinding_IModelData">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8000/ModelData/"/>
<!--//localhost:8733/Design_Time_Addresses/ModelDataService/Service1/" /> -->
</baseAddresses>
</host>
</service>
<!--><service name="SoccerModelService.ModelDataService" behaviorConfiguration="debug">
</service> -->
</services>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="32" maxStringContentLength="8388608" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8000/ModelData/" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding" contract="SoccerModelService.IModelData"
name="EndPoint" behaviorConfiguration="EndpointBehaviour" />
<!--<endpoint address="http://localhost:8000/ModelData" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding" name="EndPoint" behaviorConfiguration="EndpointBehaviour" /> -->
</client>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information,
set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
<!-- To receive exception details in faults for debugging purposes,
set the value below to true. Set to false before deployment
to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
<behavior name="debug">
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="EndpointBehaviour">
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
<!-- Trace-->
<system.diagnostics>
<sources>
<source name="System.ServiceModel" switchValue="Warning" propagateActivity="true" >
<listeners>
<add name="xml"/>
</listeners>
</source>
<source name="myUserTraceSource" switchValue="Warning, ActivityTracing">
<listeners>
<add name="xml"/>
</listeners>
</source>
</sources>
<sharedListeners>
<add name="xml"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="TraceLog.svclog" />
</sharedListeners>
<trace autoflush="true" />
</system.diagnostics>
</configuration>
感謝您的幫助!
UPDATE
我加了負載事件到我的形式。我仍然收到同樣的錯誤。我嘗試在我的表單(啓動表單的方法)的Program.cs中的Main()方法上設置一個斷點,然後在調用Program.cs中的main方法之前啓動服務!
問題是,每次我的客戶端調用服務時都會創建服務的新實例嗎?我已經把它設置成了一個單身人士,但是我做錯了嗎?
更新2
我認爲我可能不小心讓自己的項目中WCF服務應用程序,而不是一個WCF服務庫(我可能擁有一個表單內)。我的項目的bin包含項目名稱中的.dll。我相信這意味着它確實是一個圖書館。如果我錯了,請糾正我。
再次感謝!
你試圖完成什麼目標?有一個WCF服務的原因是什麼?服務通常獨立於應用程序運行,以便多個應用程序可以訪問它。基於這種n:1關係,我不明白爲什麼你希望在應用程序和服務之間有如此緊密的耦合關於啓動和初始化。如果其他用戶啓動應用程序會怎樣?你確定你需要WCF還是一個類庫? – Markus
WCF服務從網站中抓取數據並需要將其發送到多個應用程序。必須將它附加到帶有Web控件的表單才能執行此操作。 – janderson