我应该直接绑定到从Web服务返回的对象吗?

时间:2022-09-25 12:45:01

Should I bind directly to objects returned from a webservice or should I have client-side objects that I bind to my gridcontrols? For instance if I have a service that returns object Car should I have a client side Car object that I populate with values from the webservice Car object? What is considered best-practice? In C# do I need to mark my classes as serializable or do something special to them?

我应该直接绑定到从Web服务返回的对象,还是应该有我绑定到gridcontrols的客户端对象?例如,如果我有一个返回对象的服务Car应该有一个客户端Car对象,我用webservice Car对象填充值?什么是最佳实践?在C#中,我需要将我的类标记为可序列化还是对它们执行特殊操作?

5 个解决方案

#1


2  

This is a good question, which follows the sames lines as two questions I have asked myself:

这是一个很好的问题,它跟我自己提出的两个问题一样:

  1. Large, Complex Objects as a Web Service Result.
  2. 大型复杂对象作为Web服务结果。

  3. ASP.NET Web Service Results, Proxy Classes and Type Conversion.
  4. ASP.NET Web服务结果,代理类和类型转换。

Both of these may be a worthwhile read for you.

这些都可能是值得一读的。

Heres my two bits:

继承我的两点:

  • Try to keep the return types of your Web Services to primitives where possible. This not only helps reduce the size of the messages, but also reduces complexity at the receiving end.
  • 尽可能将Web服务的返回类型保留为原语。这不仅有助于减小消息的大小,还降低了接收端的复杂性。

  • If you do need to return complex objects, return them as a raw xml string (I'll explain below).
  • 如果确实需要返回复杂对象,请将它们作为原始xml字符串返回(我将在下面解释)。

What I then do is create a seperate class which represents the object and handles it's xml. I ensure the class can be instantiated from and serialized to xml easily. Then both projects (the web service and the client) can reference the DLL with the concrete object in, but there is none of the annoying coupling with the proxy class. This coupling causes issues if you have shared code.

然后我做的是创建一个单独的类来表示对象并处理它的xml。我确保可以轻松地将类实例化并序列化为xml。然后,两个项目(Web服务和客户端)都可以使用具体对象引用DLL,但是没有与代理类的恼人耦合。如果您有共享代码,这种耦合会导致问题。

For example (using your Car class):

例如(使用您的Car类):

  • Web Service (CarFactory) method BuyCar(string make, string model) is a factory method that returns a car.
  • Web Service(CarFactory)方法BuyCar(字符串生成,字符串模型)是一种返回汽车的工厂方法。

  • You also write a Mechanic class that works on Car objects to repair them, this is developed without knowledge of the Web Service.
  • 您还编写了一个适用于Car对象的Mechanic类来修复它们,这是在不了解Web Service的情况下开发的。

  • You then right a Garage class for your application. You add a web reference to the CarFactory service to get your cars, and then add some Mechanic's to your garage and then crack your knuckles and get ready to get some cars from the factory to get them working on.
  • 然后,右键为您的应用程序使用Garage类。您将CarFactory服务的Web引用添加到您的车中,然后将一些Mechanic添加到您的车库,然后破解您的指关节并准备从工厂获得一些汽车以让他们继续工作。

  • Then it all falls over, when you get the result of CarFactory.BuyCar("Audi", "R8") and then tell your Mechanic.Inspect(myAudi) the compiler moans, because the Car is actually of type CarFactory.Car not the original Car type, yes?
  • 然后它全部落空,当你得到CarFactory.BuyCar(“奥迪”,“R8”)的结果,然后告诉你的Mechanic.Inspect(myAudi)编译器呻吟,因为Car实际上是CarFactory.Car类型而不是原车型,是吗?

So, using the method I suggested:

所以,使用我建议的方法:

  • Create your Car class in its own DLL. Add methods to instantiate it and serialize it from/to XML respectively.
  • 在自己的DLL中创建Car类。添加实例化方法并分别从/将其序列化为XML。

  • Create your CarFactory web service, add a reference to the DLL, build your cars as before, but instead of returning the object, return the XML.
  • 创建您的CarFactory Web服务,添加对DLL的引用,像以前一样构建您的汽车,但不返回该对象,而是返回XML。

  • Create your Garage adding a reference to the Mechanic, Car DLL and the CarFactory web service. Call your BuyCar method and now it returns a string, you then pass this string to the Car class, which re-builds its object model. The Mechanic's can happily work on these Car's too because everything is singing from the same hymn sheet (or DLL?) :)
  • 创建您的Garage,添加对Mechanic,Car DLL和CarFactory Web服务的引用。调用您的BuyCar方法,现在它返回一个字符串,然后将此字符串传递给Car类,后者重新构建其对象模型。机械师也可以愉快地使用这些Car's,因为一切都是从同一个赞美诗片(或DLL?)唱歌:)

  • One major benefit is that if the object changes in its design, all you need to do is update the DLL and the web service and client apps are completely decoupled from the process.
  • 一个主要的好处是,如果对象在其设计中发生变化,您需要做的就是更新DLL,并且Web服务和客户端应用程序与流程完全分离。

Note: Often it can be useful to then create a Facade layer two work with the web services and auto-generate objects from the XML results.

注意:通常,创建Facade层可以使用Web服务并从XML结果中自动生成对象。

I hope that makes sense, if not, then please shout and I will clarify .

我希望这是有道理的,如果没有,那么请大喊,我会澄清。

#2


0  

This really depends on what you are getting from the web service. If they are simple data transfer objects and you are only displaying data, then yes, you can bind. If you plan to edit the objects, it may not be usefull as you will need to track changes.

这实际上取决于您从Web服务获得的内容。如果它们是简单的数据传输对象而您只显示数据,那么是的,您可以绑定。如果您计划编辑对象,则可能无用,因为您需要跟踪更改。

Do your objects and/or collections on the client track changes? If so you can use them.

您的客户跟踪上的对象和/或集合是否发生了变化?如果是这样,你可以使用它们。

If you have no change tracking, then you will need to track changes yourself, so you may need to translate the objects or wrap them in something to track changes.

如果您没有更改跟踪,那么您将需要自己跟踪更改,因此您可能需要翻译对象或将其包装在某些内容中以跟踪更改。

Again, it really depends on what you are getting, what they support, what you are doing with them, as well as what response the server wants back for changes.

同样,它实际上取决于您获得了什么,他们支持什么,您正在使用它们做什么,以及服务器想要更改的响应。

#3


0  

One thing you can do is to create client classes corresponding to the web service data contracts with any additional functionality that you want and set the web service reference to reuse existing types. Then there is no reason to create an additional wrapper class to bind to.

您可以做的一件事是使用您需要的任何其他功能创建与Web服务数据协定相对应的客户端类,并将Web服务引用设置为重用现有类型。然后没有理由创建一个额外的包装类来绑定。

#4


0  

If you bind directly to the Web service types, you're introducing a coupling. Should the Web service change in future, this may have undesired side-effects that mean lots of code changes.

如果直接绑定到Web服务类型,则会引入耦合。如果Web服务将来发生变化,这可能会产生不希望的副作用,这意味着许多代码都会发生变化。

For example, what if you're using .asmx Web services today, then shift to WCF tomorrow? That might mean quite a few changes through your code if you've used types that WCF won't serialize.

例如,如果您今天使用.asmx Web服务,然后明天转移到WCF怎么办?如果你使用了WCF不会序列化的类型,这可能意味着你的代码会发生很多变化。

It's often better in the long run to create specific client-side objects and then translate to and from Web service data contract types. It may seem a lot of work, but this is often repaid greatly when it's time to refactor, as your changes are localised in one place.

从长远来看,创建特定的客户端对象然后在Web服务数据协定类型之间进行转换通常会更好。这可能看起来很多工作,但是当重构时,这通常会得到很大的回报,因为您的更改已在一个地方进行了本地化。

#5


0  

If you are the owner of both the web service and the client.
And you need the parameters of the web service calls to be complex classes which contain not only data but also behavior (actual coded logic) then you are in a bit of a pickle when developing these web services using web service frame works.
As suggested in the answer by Rob Cooper you can use pure xml as web service parameters and xml serialization, but there is a cleaner solution.
If you are using Visual Studio 2005 (probably applies the same for 2008), You can customize the way VS creates you proxy as described in this article: Customizing generated Web Service proxies in Visual Studio 2005

如果您是Web服务和客户端的所有者。并且您需要Web服务调用的参数是复杂的类,它们不仅包含数据,还包含行为(实际编码逻辑),那么在使用Web服务框架工作开发这些Web服务时,您会有点蠢蠢欲动。正如Rob Cooper在回答中所建议的那样,您可以使用纯xml作为Web服务参数和xml序列化,但是有一个更清晰的解决方案。如果您使用的是Visual Studio 2005(可能适用于2008年),您可以自定义VS创建代理的方式,如本文所述:在Visual Studio 2005中自定义生成的Web服务代理

This way you can tell VS to use your own classes instead of generating a proxy class.

这样,您可以告诉VS使用您自己的类而不是生成代理类。

Well when I think of it, it's pretty much same solution as proposed by Rob Cooper, with the little twist, that you wont be writing a Facade layer your self but will be using VS itself as this layer.

好吧,当我想起它时,它与Rob Cooper提出的解决方案几乎完全相同,只是一点点扭曲,你不会自己写一个Facade层,而是将VS本身用作这个层。

#1


2  

This is a good question, which follows the sames lines as two questions I have asked myself:

这是一个很好的问题,它跟我自己提出的两个问题一样:

  1. Large, Complex Objects as a Web Service Result.
  2. 大型复杂对象作为Web服务结果。

  3. ASP.NET Web Service Results, Proxy Classes and Type Conversion.
  4. ASP.NET Web服务结果,代理类和类型转换。

Both of these may be a worthwhile read for you.

这些都可能是值得一读的。

Heres my two bits:

继承我的两点:

  • Try to keep the return types of your Web Services to primitives where possible. This not only helps reduce the size of the messages, but also reduces complexity at the receiving end.
  • 尽可能将Web服务的返回类型保留为原语。这不仅有助于减小消息的大小,还降低了接收端的复杂性。

  • If you do need to return complex objects, return them as a raw xml string (I'll explain below).
  • 如果确实需要返回复杂对象,请将它们作为原始xml字符串返回(我将在下面解释)。

What I then do is create a seperate class which represents the object and handles it's xml. I ensure the class can be instantiated from and serialized to xml easily. Then both projects (the web service and the client) can reference the DLL with the concrete object in, but there is none of the annoying coupling with the proxy class. This coupling causes issues if you have shared code.

然后我做的是创建一个单独的类来表示对象并处理它的xml。我确保可以轻松地将类实例化并序列化为xml。然后,两个项目(Web服务和客户端)都可以使用具体对象引用DLL,但是没有与代理类的恼人耦合。如果您有共享代码,这种耦合会导致问题。

For example (using your Car class):

例如(使用您的Car类):

  • Web Service (CarFactory) method BuyCar(string make, string model) is a factory method that returns a car.
  • Web Service(CarFactory)方法BuyCar(字符串生成,字符串模型)是一种返回汽车的工厂方法。

  • You also write a Mechanic class that works on Car objects to repair them, this is developed without knowledge of the Web Service.
  • 您还编写了一个适用于Car对象的Mechanic类来修复它们,这是在不了解Web Service的情况下开发的。

  • You then right a Garage class for your application. You add a web reference to the CarFactory service to get your cars, and then add some Mechanic's to your garage and then crack your knuckles and get ready to get some cars from the factory to get them working on.
  • 然后,右键为您的应用程序使用Garage类。您将CarFactory服务的Web引用添加到您的车中,然后将一些Mechanic添加到您的车库,然后破解您的指关节并准备从工厂获得一些汽车以让他们继续工作。

  • Then it all falls over, when you get the result of CarFactory.BuyCar("Audi", "R8") and then tell your Mechanic.Inspect(myAudi) the compiler moans, because the Car is actually of type CarFactory.Car not the original Car type, yes?
  • 然后它全部落空,当你得到CarFactory.BuyCar(“奥迪”,“R8”)的结果,然后告诉你的Mechanic.Inspect(myAudi)编译器呻吟,因为Car实际上是CarFactory.Car类型而不是原车型,是吗?

So, using the method I suggested:

所以,使用我建议的方法:

  • Create your Car class in its own DLL. Add methods to instantiate it and serialize it from/to XML respectively.
  • 在自己的DLL中创建Car类。添加实例化方法并分别从/将其序列化为XML。

  • Create your CarFactory web service, add a reference to the DLL, build your cars as before, but instead of returning the object, return the XML.
  • 创建您的CarFactory Web服务,添加对DLL的引用,像以前一样构建您的汽车,但不返回该对象,而是返回XML。

  • Create your Garage adding a reference to the Mechanic, Car DLL and the CarFactory web service. Call your BuyCar method and now it returns a string, you then pass this string to the Car class, which re-builds its object model. The Mechanic's can happily work on these Car's too because everything is singing from the same hymn sheet (or DLL?) :)
  • 创建您的Garage,添加对Mechanic,Car DLL和CarFactory Web服务的引用。调用您的BuyCar方法,现在它返回一个字符串,然后将此字符串传递给Car类,后者重新构建其对象模型。机械师也可以愉快地使用这些Car's,因为一切都是从同一个赞美诗片(或DLL?)唱歌:)

  • One major benefit is that if the object changes in its design, all you need to do is update the DLL and the web service and client apps are completely decoupled from the process.
  • 一个主要的好处是,如果对象在其设计中发生变化,您需要做的就是更新DLL,并且Web服务和客户端应用程序与流程完全分离。

Note: Often it can be useful to then create a Facade layer two work with the web services and auto-generate objects from the XML results.

注意:通常,创建Facade层可以使用Web服务并从XML结果中自动生成对象。

I hope that makes sense, if not, then please shout and I will clarify .

我希望这是有道理的,如果没有,那么请大喊,我会澄清。

#2


0  

This really depends on what you are getting from the web service. If they are simple data transfer objects and you are only displaying data, then yes, you can bind. If you plan to edit the objects, it may not be usefull as you will need to track changes.

这实际上取决于您从Web服务获得的内容。如果它们是简单的数据传输对象而您只显示数据,那么是的,您可以绑定。如果您计划编辑对象,则可能无用,因为您需要跟踪更改。

Do your objects and/or collections on the client track changes? If so you can use them.

您的客户跟踪上的对象和/或集合是否发生了变化?如果是这样,你可以使用它们。

If you have no change tracking, then you will need to track changes yourself, so you may need to translate the objects or wrap them in something to track changes.

如果您没有更改跟踪,那么您将需要自己跟踪更改,因此您可能需要翻译对象或将其包装在某些内容中以跟踪更改。

Again, it really depends on what you are getting, what they support, what you are doing with them, as well as what response the server wants back for changes.

同样,它实际上取决于您获得了什么,他们支持什么,您正在使用它们做什么,以及服务器想要更改的响应。

#3


0  

One thing you can do is to create client classes corresponding to the web service data contracts with any additional functionality that you want and set the web service reference to reuse existing types. Then there is no reason to create an additional wrapper class to bind to.

您可以做的一件事是使用您需要的任何其他功能创建与Web服务数据协定相对应的客户端类,并将Web服务引用设置为重用现有类型。然后没有理由创建一个额外的包装类来绑定。

#4


0  

If you bind directly to the Web service types, you're introducing a coupling. Should the Web service change in future, this may have undesired side-effects that mean lots of code changes.

如果直接绑定到Web服务类型,则会引入耦合。如果Web服务将来发生变化,这可能会产生不希望的副作用,这意味着许多代码都会发生变化。

For example, what if you're using .asmx Web services today, then shift to WCF tomorrow? That might mean quite a few changes through your code if you've used types that WCF won't serialize.

例如,如果您今天使用.asmx Web服务,然后明天转移到WCF怎么办?如果你使用了WCF不会序列化的类型,这可能意味着你的代码会发生很多变化。

It's often better in the long run to create specific client-side objects and then translate to and from Web service data contract types. It may seem a lot of work, but this is often repaid greatly when it's time to refactor, as your changes are localised in one place.

从长远来看,创建特定的客户端对象然后在Web服务数据协定类型之间进行转换通常会更好。这可能看起来很多工作,但是当重构时,这通常会得到很大的回报,因为您的更改已在一个地方进行了本地化。

#5


0  

If you are the owner of both the web service and the client.
And you need the parameters of the web service calls to be complex classes which contain not only data but also behavior (actual coded logic) then you are in a bit of a pickle when developing these web services using web service frame works.
As suggested in the answer by Rob Cooper you can use pure xml as web service parameters and xml serialization, but there is a cleaner solution.
If you are using Visual Studio 2005 (probably applies the same for 2008), You can customize the way VS creates you proxy as described in this article: Customizing generated Web Service proxies in Visual Studio 2005

如果您是Web服务和客户端的所有者。并且您需要Web服务调用的参数是复杂的类,它们不仅包含数据,还包含行为(实际编码逻辑),那么在使用Web服务框架工作开发这些Web服务时,您会有点蠢蠢欲动。正如Rob Cooper在回答中所建议的那样,您可以使用纯xml作为Web服务参数和xml序列化,但是有一个更清晰的解决方案。如果您使用的是Visual Studio 2005(可能适用于2008年),您可以自定义VS创建代理的方式,如本文所述:在Visual Studio 2005中自定义生成的Web服务代理

This way you can tell VS to use your own classes instead of generating a proxy class.

这样,您可以告诉VS使用您自己的类而不是生成代理类。

Well when I think of it, it's pretty much same solution as proposed by Rob Cooper, with the little twist, that you wont be writing a Facade layer your self but will be using VS itself as this layer.

好吧,当我想起它时,它与Rob Cooper提出的解决方案几乎完全相同,只是一点点扭曲,你不会自己写一个Facade层,而是将VS本身用作这个层。