2012-03-29 10 views
1

メソッドFinal()にいくつか問題があります。それはIWeatherのリストを返すはずですが、私はそれを呼び出すとnullを返します。デバッグでは、私はWCFサービスのメソッドは何も返しません。

return this.returner; 

に停止しますが、それは常にnullだったとMainMethod()は、「仕上げ」とリスト「戻し」を返すので、nullでない理由をデバッグ()MainMethodにあるとき、私は知りません。あなたのクラスの新しいインスタンスがWCFの要求が行われるたびに作成されるため、

using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using System.Net; 
using System.Net.NetworkInformation; 
using System.Runtime.Serialization; 
using System.ServiceModel; 
using System.ServiceModel.Activation; 
using System.Text; 
using System.Xml; 
using System.Xml.Linq; 
using LibW; 

[ServiceContract(Namespace = "")] 
[SilverlightFaultBehavior] 
[AspNetCompatibilityRequirements(RequirementsMode =  AspNetCompatibilityRequirementsMode.Allowed)] 
public class AllInOne 
{ 
[OperationContract] 
public void DoWork() 
{ 
    // Add your operation implementation here 
    return; 
} 
[DataMember] 
private List<LibW.IWeather> returner = new List<LibW.IWeather>(); 
/// <summary> 
/// method set connection to google and get xml document weather for there 
/// </summary> 
/// <param name="city">city for which find weather</param> 
/// <param name="lang">lang of text</param> 
/// <returns>return either "finish if all successful or Exception msg or errors with city finding and error with connection</returns> 
[OperationContract] 
public string MainMethod(string city, string lang) 
{ 
    //check connection 
    Ping p = new Ping(); 
    PingReply pr = p.Send(@"google.com"); 
    IPStatus status = pr.Status; 
    if (status != IPStatus.Success) 
     return "Error with Connection"; 
    //try tp get xml weather 
    try 
    { 
     XElement el; 
     HttpWebRequest req = 
      (HttpWebRequest) WebRequest.Create("http://www.google.com/ig/api?weather=" + city + "&hl=" + lang); 
     HttpWebResponse resp = (HttpWebResponse) req.GetResponse(); 
     StringBuilder sb = new StringBuilder(); 
     using (StreamReader streamreader = new StreamReader(resp.GetResponseStream(), Encoding.GetEncoding(1251))) 
     { 
      el = XElement.Load(streamreader); 
     } 
     int addv = 0; 
     var v = from c in el.Elements() 
       select c; 

        //I get here data from XML(condition,temperature and etc.) 

     return "finish"; 
    } 
    catch (Exception exc) 
    { 
     return exc.Message; 
    } 
} 

/// <summary> 
/// return list of weather fot 4 days 
/// </summary> 
/// <returns>list</returns> 
[OperationContract] 
public List<IWeather> Final() 
{ 
    return this.returner; 
} 
} 
+0

'returner'が' null'であると言うとき、あなたは本当に 'null'を意味しますか、それとも空の' List <> 'ですか? –

答えて

3

サービスは2つの別々の操作で構成され、サービスクラスのメンバ変数を使用して呼び出し間に状態を保存しようとします。サービスクラスにServiceBehaviorAttributeが明示的に指定されていないため、デフォルトのInstanceContextModePerSessionになります。しかし、私はあなたが今実際にセッションを使用していないと推測しているので、基本的にはPerCallの動作に終わっています。

だから、何が起こっていることは、通話がMainMethodのために来ているAllInOneサービスクラスの新しいインスタンスを取得すること、それが実行し、returnerフィールドを記入し、今そのインスタンスが行われ、GC'dする準備ができています。 Finalの次の呼び出しでは、AllInOneクラスの全く新しいインスタンスが取得されるため、returnerフィールドは決して設定されず、したがってnullになります。

あなたはどちらかは、あなたが実際にサービスのためのセッションを有効にして、クライアントを確認する必要があり(多分あなただけ知らない、1を持っている)すべてのあなたのクライアントのためのインスタンスをしたい場合はSingleInstanceContextModeを使用する必要がありますかセッションも適切に使用しています。セッションの使用方法の詳細についてはhereをご覧ください。

+0

はい、私は1つのクライアントしか持っていません。 –

+1

また、ホストがシャットダウンするまで(IISアプリケーションプール、Windowsサービス、実行中のもの)、その値を保持することになります。したがって、値を強制的に更新したいときにクライアントが常にMainMethodを呼び出すようにする必要があります。正直なところ、あなたはあなたのAPIデザインを変更して、 "finished"を返すべきです、あるいは、エラーメッセージは、Webサービスの動作方法ではありません。エラーが発生した場合は、エラーメッセージとともにFaultExceptionをスローする必要があります。これを行った場合は、MainMethod自体からリストを返すだけで、これらの問題は発生しません。 –

+0

問題は、接続のエラーか都市だけか、言語が間違っているかどうかを知りたいので、フルバージョンではそれだけではありません!または!接続エラー!だけでなく !間違った都市または間違った言語! –

1

ローカル変数は、WCFサービスの呼び出しの間で永続的ではありません。すべてのリクエストは互いに独立している必要があります。そうでない場合は、データベースなどの永続的なストレージコンテナが必要です。または、@DrewMarshのようにセッションを使用する必要があります。

+0

'returner'は' null'の代わりに空の 'List <>'ではないでしょうか?私はあなたの答えと同じことを考えていましたが、クラス全体が各呼び出しごとに再インスタンス化されると考えました。 –

+0

私は、OPがデータがないことを意味する「ヌル」という言葉を誤って使用していると想定しています。 – mellamokb

+0

それは良い点です。そこにOPの前提があるかもしれません。 –

1

あなたのコードを調べたところ、WCFについて少し混乱しているように感じます。まず、WCFでクライアントから操作契約を呼び出さない限り、それ自体では機能しません。たとえば、メソッドfinalを呼び出すと、リストが返されます。 また、mainmethodでは、文字列が返されました。これはfinishです。 "Finish"はメソッド呼び出しではなく、単なる文字列です。

関連する問題