使用 .NET 远程处理时,为什么我只能从 ASP.NET Web 应用程序读取属性而不能设置属性?
我在尝试设置 Windows 服务中托管的远程对象的属性时遇到问题。我正在尝试更改对象的属性,但由于某种原因它没有保存。
这是服务的相关代码:
private static List<Alert> _alerts = new List<Alert>(); // List of the Alerts
private TcpChannel _tcpChannel;
protected override void OnStart(string[] args)
{
loadAlerts(); // This sets up the List (code not req'd)
// Set up the remotelister so that other processes can access _alerts
// Create the TcpChannel
_tcpChannel = new TcpChannel(65000);
ChannelServices.RegisterChannel(_tcpChannel, false);
// Register the Proxy class for remoting.
RemotingConfiguration.RegisterWellKnownServiceType(
typeof(RemoteLister),
"AlertList.soap",
WellKnownObjectMode.Singleton);
}
[Serializable]
public class RemoteLister : MarshalByRefObject
{
public List<Alert> TheList
{
get { return _alerts; }
set { _alerts = value; }
}
public bool save()
{
EventLog.WriteEntry("AlertService", "Calling saveAlerts...");
return saveAlerts();
}
}
这是 Alert 类的代码(还有很多其他内容):
private string _alertName; // Name of alert
public string AlertName
{
get { return _alertName; }
set { _alertName = value; }
}
现在在我的 ASP.NET Web 应用程序中,这是我初始化所有内容的方法:
AlertService.RemoteLister remoteAlertList;
protected void Page_Load(object sender, EventArgs e)
{
// This is where we create a local object that accesses the remote object in the service
Type requiredType = typeof(AlertService.RemoteLister);
// remoteAlertList is our reference to the List<Alert> in the always running service
remoteAlertList = (AlertService.RemoteLister)Activator.GetObject(requiredType,
"tcp://localhost:65000/AlertList.soap");
}
所以现在以下代码可以工作:
private void fillFields()
{
AlertNameTextBox.Text = remoteAlertList.TheList[AlertDropDownList.SelectedIndex].AlertName;
}
但是当我去更改该属性,如下所示,它不起作用。
protected void AlertSaveButton_Click(object sender, EventArgs e)
{
remoteAlertList.TheList[AlertDropDownList.SelectedIndex].AlertName = AlertNameTextBox.Text;
}
有谁知道为什么它不保存该财产?
提前致谢!
I'm having an issue with attempting to set a property on a remote object hosted in a Windows Service. I'm trying to change a property of an object and it is not saving for some reason.
Here is the pertinent code of the service:
private static List<Alert> _alerts = new List<Alert>(); // List of the Alerts
private TcpChannel _tcpChannel;
protected override void OnStart(string[] args)
{
loadAlerts(); // This sets up the List (code not req'd)
// Set up the remotelister so that other processes can access _alerts
// Create the TcpChannel
_tcpChannel = new TcpChannel(65000);
ChannelServices.RegisterChannel(_tcpChannel, false);
// Register the Proxy class for remoting.
RemotingConfiguration.RegisterWellKnownServiceType(
typeof(RemoteLister),
"AlertList.soap",
WellKnownObjectMode.Singleton);
}
[Serializable]
public class RemoteLister : MarshalByRefObject
{
public List<Alert> TheList
{
get { return _alerts; }
set { _alerts = value; }
}
public bool save()
{
EventLog.WriteEntry("AlertService", "Calling saveAlerts...");
return saveAlerts();
}
}
Here is the code for the Alert class (a lot of other stuff too):
private string _alertName; // Name of alert
public string AlertName
{
get { return _alertName; }
set { _alertName = value; }
}
Now in my ASP.NET web app, here's how I initialize everything:
AlertService.RemoteLister remoteAlertList;
protected void Page_Load(object sender, EventArgs e)
{
// This is where we create a local object that accesses the remote object in the service
Type requiredType = typeof(AlertService.RemoteLister);
// remoteAlertList is our reference to the List<Alert> in the always running service
remoteAlertList = (AlertService.RemoteLister)Activator.GetObject(requiredType,
"tcp://localhost:65000/AlertList.soap");
}
So now the following code works:
private void fillFields()
{
AlertNameTextBox.Text = remoteAlertList.TheList[AlertDropDownList.SelectedIndex].AlertName;
}
But when I go to change that property as in the following, it doesn't work.
protected void AlertSaveButton_Click(object sender, EventArgs e)
{
remoteAlertList.TheList[AlertDropDownList.SelectedIndex].AlertName = AlertNameTextBox.Text;
}
Does anyone have an idea of why it wouldn't save that property?
Thanks in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我猜想,由于
List
不是从MarshalByRefObject
继承的,当您调用属性remoteAlertList.TheList
code> 你得到一个断开连接的对象。也许可以向对象添加一个索引器:实际上,我主要会说放弃远程处理并使用 WCF/SOA。而且
RemoteLister
成为[Serialized]
没有什么意义。您可能还想考虑一下线程安全。澄清;
Alert
实例也是独立的,因此本地更新不会影响服务器;基本上,有两种情况:MarshalByRefObjecf
类型,如果您的索引器具有(例如),
那么这是:(
如果
Alert
是MarshalByRefObject
,这会更新服务器,但是不要这样做)。但是,如果我们将值推回:那么我们已经更新了服务器。
正如您所发现的,以操作为中心的设计可能要简单得多(即
setAlertName
)。但我真的认为远程处理在这里是一个坏主意。I would guess that since
List<T>
doesn't inherit fromMarshalByRefObject
, when you call the propertyremoteAlertList.TheList
you get a disconnected object. Perhaps add an indexer to the object instead:Actually, I would mainly say ditch remoting and use WCF/SOA. And there is little purpose in
RemoteLister
being[Serializable]
. You might also want to put some thought into thread-safety.To clarify; the
Alert
instances will also be standalone, so local updates won't affect the server; basically, you have two scenarios:MarshalByRefObject
, then it only lives at the server; all client operations are remoted to the actual object - but only forMarshalByRefObjecf
typesIf you an indexer with (for example)
then this is:
(if
Alert
wasMarshalByRefObject
, this would update the server, but don't do that). But if we push the value back:then we have updated the server.
As you've discovered, an operation-centric design may be far simpler (i.e.
setAlertName
). But I really think remoting is a bad idea here.尝试了索引器,但没有运气。我尝试了下面显示的另一种方法,它有效,但这似乎是一种解决方法,而不是正确的方法。我所做的就是在 RemoteLister 类中添加此内容:
然后按如下方式更改保存按钮:
我想这暂时可以解决我的问题,但如果有人知道为什么不这样做,我宁愿以“正确”的方式进行操作按照我的第一种方式工作。
Tried the indexer, no luck with that. I tried another way shown below and it worked, but it seems like a workaround and not the proper way of doing it. All I did was add this in the RemoteLister class:
And then changed the save button as follows:
I suppose this will get me by for now, but i'd rather do it the "right" way if anyone knows why it wasn't working the first way I did it.
我查看了您的代码,它似乎是正确的。
但可能导致错误的代码行位于remoteAlertList初始化中:
您已使用初始.net转换方法“(newType)obj”和Activator.GetObject(..)初始化了remoteAlertList类,其中之一没有返回原始 obj 的引用[我认为是 Activator.GetObject(..)]。它返回“AlertService.RemoteLister”类的精确副本,因此当您调用“TheList”时,您调用了它的精确副本,当您调用 Save() 时,它保存在复制的对象中而不是真实的对象中。
在这里我看不到您的完整代码,但从我所看到的我可以告诉您解决方案是找到一种方法来从主机访问 AlertService.RemoteLister 对象的引用。
I have take a look at your code and it seems to be correct.
but the line of code which may caused the error is here in remoteAlertList initializing:
You have initialized a remoteAlertList class with a initial .net convertion method "(newType)obj" and Activator.GetObject(..) which one of them does't return the reference of original obj [I think it's the Activator.GetObject(..)]. It returns an exact copy of "AlertService.RemoteLister" class so when you call "TheList" you called an exact copy of it and when you call Save() it saves in the copied object not in the real object.
Here I can't see your full code but from what I see I can tell you the solution is finding a way to for accessing the referece of AlertService.RemoteLister object from the host.