2012-03-29 110 views
1

我在Final()方法中遇到了一些麻烦。它应该返回IWeather的列表,但在我调用它时返回null。在调试我停在什么都不返回

return this.returner; 

,但它总是空,我不知道为什么,因为MainMethod()返回“完成”,并列出“武者回归”不为空时,调试是MainMethod()。

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 <>'? – 2012-03-29 16:57:26

回答

3

您的服务由两个单独的操作组成,并使用服务类上的成员变量尝试在调用之间存储状态。您也没有在您的服务等级上指定任何明确的ServiceBehaviorAttribute,这意味着默认InstanceContextMode将是PerSession。但是,我猜你现在实际上并没有使用会话,所以你基本上以PerCall行为结束。

那么,发生了什么是电话打进来了MainMethod,是可以获得AllInOne服务类的新实例,它执行,填补了returner领域,但现在情况等做准备GC'd。下一次拨打Final会得到一个AllInOne类的全新实例,因此returner字段永远不会被设置,因此为空。

你要么需要使用SingleInstanceContextMode如果你想要一个实例为所有的客户(也许你只能有一个,不知道)实际上你需要启用该服务会话,并确保你的客户也正确使用会话。有关如何使用会话的详细信息,请参见here

+0

是的,我只有一个客户端。 – 2012-03-29 17:14:40

+1

好吧,一旦你使它成为单例,它会保留这个值,直到主机关闭(IIS应用程序池,windows服务,无论你在运行它)为止。因此,您需要确保客户端在要强制更新值时始终调用MainMethod。老实说,你应该改变你的API设计,返回“完成”或错误消息不是Web服务应该如何工作。如果出现错误,应该在其中引发一个FaultException错误消息。如果你这样做了,你可以从MainMethod本身返回List ,并且没有任何这些问题。 – 2012-03-29 17:32:20

+0

问题是我想知道它是连接错误还是只是城市或语言不正确,所以在完整版本中它不仅返回!完成!或!连接错误!但也 !错误的城市或错误的语言! – 2012-03-29 17:47:55

1

因为每次创建WCF请求时都会创建类的新实例,所以在调用WCF服务之间局部变量不是永久的。您的所有请求都需要彼此独立,否则您需要持久存储容器,如数据库。或者您需要使用会话,如@DrewMarsh所示。

+0

在这种情况下,'returner'不会是'List <>'而不是'null'吗?我认为和你的答案一样,但是我认为整个班级都会为每个电话重新实例化。 – 2012-03-29 16:54:25

+0

我假设OP滥用单词'null'这意味着没有数据,不一定是它实际上是'null'。 – mellamokb 2012-03-29 16:56:02

+0

这是一个很好的观点。 OP可能会有一个假设。 – 2012-03-29 16:56:55

1

当我调查你的代码时,我觉得你对WCF有点困惑。首先,除非您从客户端调用WCF中的操作合同,否则它本身不起作用。例如,当你调用final方法时,它只返回一个列表。 另外,在mainmethod中,你返回了一个字符串,它是完成的。 “完成”不是一个方法调用,只是一个字符串。