2012-03-29 4 views
1

메서드 Final()에 문제가 있습니다. 그것은 IWeather의 목록을 반환해야하지만 내가 그것을 호출하면 null을 반환합니다. 디버그에서 나는WCF 서비스의 메서드는 아무 것도 반환하지 않습니다.

return this.returner; 

에서 중지하지만, 항상 null이고 MainMethod는() "마무리"와 목록 "기 returner"를 반환하기 때문에 널 (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

서비스는 두 개의 개별 작업으로 구성되며 서비스 클래스의 멤버 변수를 사용하여 호출간에 상태를 저장하려고 시도합니다. 또한 서비스 클래스에 명시적인 ServiceBehaviorAttribute을 지정하지 않으므로 기본값 InstanceContextModePerSession이됩니다. 그러나 실제로 세션을 사용하지 않는 것 같아서 기본적으로 PerCall 동작으로 끝납니다.

그럼, 무슨 일이 일어나고은 전화, 그것은 실행의 returner 필드를 채우고,하지만 지금은 그 예를 수행하고 GC'd 할 준비가되어있는 AllInOne 서비스 클래스의 새 인스턴스를 가져옵니다 그, MainMethod위한에서 온다. Final에 대한 다음 호출은 AllInOne 클래스의 완전히 새로운 인스턴스를 가져 오므로 returner 필드는 절대로 설정되지 않으므로 null입니다.

당신이 중 하나는 모든 클라이언트 (어쩌면 당신은, 하나가 모르는) 가 또는 당신이 실제로 당신의 고객 서비스에 대한 세션을 사용하고 있는지 확인해야합니다에 대한 하나 개의 인스턴스를 원하는 경우 SingleInstanceContextMode를 사용할 필요가 또한 세션을 올바르게 사용하고 있습니다. 세션 사용 방법에 대한 자세한 내용은 here을 참조하십시오.

+0

예, 클라이언트가 하나뿐입니다. –

+1

좋습니다. 일단 호스트가 종료 될 때까지 (IIS 응용 프로그램 풀, Windows 서비스, 당신이 무엇을 실행하든) 호스트가 종료 할 때까지 그 값을 유지할 것입니다. 따라서 값을 강제 업데이트하려고 할 때 클라이언트가 항상 MainMethod를 호출하는지 확인해야합니다. 솔직히 API 디자인을 변경하고 "finished"를 반환하거나 오류 메시지는 웹 서비스가 작동하지 않는 방법입니다. 오류가있는 경우 오류 메시지와 함께 FaultException을 던져야합니다. 이 경우 MainMethod 자체에서 List 을 반환 할 수 있으며 이러한 문제는 없습니다. –

+0

문제는 연결 오류 또는 도시 또는 언어가 올바르지 않은지 알고 싶기 때문에 정식 버전에서는 반환하지 않습니다! 연결 오류! 그러나 또한!잘못된 도시 또는 잘못된 언어! –

1

지역 변수는 WCF 서비스를 호출 사이에 지속되지 않습니다. 모든 요청은 서로 독립적이어야하며 그렇지 않으면 데이터베이스와 같은 영구 저장소가 필요합니다. 또는 @DrewMarsh으로 표시된 세션을 사용해야합니다.

+0

'returner'는'null' 대신 빈'List <>'가 아니겠습니까? 나는 당신의 대답과 똑같은 것을 생각했지만, 나는 전체 클래스가 각 호출마다 다시 인스턴스화 될 것이라고 생각했다. –

+0

나는 OP가 "null"이란 단어를 잘못 사용했다고 가정하고 있습니다. 데이터가 없다는 것을 의미합니다. 반드시 실제로는 "null"이 아닐 수도 있습니다. – mellamokb

+0

좋은 지적입니다. OP가 가정 할 수 있습니다. –

1

코드를 조사 할 때 WCF에 대해 다소 혼란스러워 보입니다. 우선, WCF에서 클라이언트와의 작업 계약을 호출하지 않으면 자체적으로 작동하지 않습니다. 예를 들어 final 메서드를 호출하면 목록 만 반환됩니다. 또한 mainmethod에서 문자열을 반환했습니다. 이것은 마무리입니다. "Finish"는 메서드 호출이 아니라 문자열입니다.

관련 문제