使用C#.net 2.0 WebService的复杂类型编码输入参数的正确方法是什么?

时间:2022-07-28 16:09:10

I am currently building a new version of webservice that my company already provides. The current webservice has an input parameter of type string. In that string an entire xml doc is passed. We then validate that string against an xsd (the same xsd given to the consumer). It looks something like this:

我目前正在构建我公司已经提供的新版web服务。当前的webservice有一个string类型的输入参数。在该字符串中,传递整个xml doc。然后,我们针对xsd验证该字符串(与消费者相同的xsd)。它看起来像这样:

[WebMethod]
public bool Upload(string xml)
{
    if (ValidateXML(xml))
    {
        //Do something
    }
}

I am building the next version of this service. I was under the impression that passing an XML doc as a string is not the correct way to do this. I was thinking that my service would look something like this:

我正在构建此服务的下一个版本。我的印象是将XML文档作为字符串传递并不是正确的方法。我以为我的服务看起来像这样:

[WebMethod]
public bool Upload(int referenceID, string referenceName, //etc...)
{
    //Do something
}

This issue that I am having is that in actuality there are a large amount of input parameters and some of them are complex types. For example, the Upload Method needs to take in a complex object called an Allocation. This object is actually made up of several integers, decimal values, strings, and other complex objects. Should I build the webservice like so:

我遇到的这个问题是,实际上有大量的输入参数,其中一些是复杂的类型。例如,Upload Method需要接受一个名为Allocation的复杂对象。该对象实际上由几个整数,十进制值,字符串和其他复杂对象组成。我应该像这样构建web服务:

[WebMethod]
public bool Upload(int referenceID, string referenceName, Allocation referenceAllocation)
{
    //Do something
}

Or is there a different way to do this?

或者有不同的方法来做到这一点?

Note: this Allocation object has a hierarchy in the xsd that was provided for the old service.

注意:此Allocation对象在xsd中具有为旧服务提供的层次结构。

Could it be that the original service only took in xml to combat this problem? Is there a better way to take in complex types to a webservice?

难道原来的服务只用xml来解决这个问题吗?是否有更好的方法将复杂类型引入Web服务?

Note: This is a C# 2.0 webservice.

注意:这是一个C#2.0 Web服务。

3 个解决方案

#1


I would probably use the XSD with "xsd.exe" tool to create a XML Serializable object. Then you can deal with objects instead of string parameters. It also gives you the ability to not change the signatures of the WebService.

我可能会使用XSD和“xsd.exe”工具来创建XML Serializable对象。然后你可以处理对象而不是字符串参数。它还使您能够不更改WebService的签名。

If you change the XSD to add another parameter all you will need to do is recreate the class again using XSD.exe tool. Make good use of partial classes here. Separate your auto generated class from your business logic. This way you can recreate the the class definition if the XSD changes as many times as you want, but not touch your business logic.

如果您更改XSD以添加另一个参数,您需要做的是使用XSD.exe工具再次重新创建该类。在这里充分利用部分课程。将自动生成的类与业务逻辑分开。这样,如果XSD根据需要更改次数,则可以重新创建类定义,但不能触及业务逻辑。

XML Serialization in the .NET Framework

.NET Framework中的XML序列化

If you were using 3.5, you could also use LINQ to XML to quickly parse out your XML parameters.

如果您使用的是3.5,那么您还可以使用LINQ to XML快速解析XML参数。

#2


Jon, to answer your follow-up question first: If your clients are on multiple platforms (or at least, not all on .NET), the best approach is the so-called "WSDL-first". Define the service interface in WSDL - that's where services and methods will be defined - WSDL will reference a set of XSDs defining the data-holding objects passed to and returned from those methods. You can generate C# or Java code from WSDL/XSDs.

Jon,首先回答你的后续问题:如果你的客户在多个平台上(或者至少在.NET上不是全部),那么最好的方法就是所谓的“WSDL-first”。在WSDL中定义服务接口 - 即定义服务和方法的位置 - WSDL将引用一组XSD,这些XSD定义传递给这些方法并从这些方法返回的数据保持对象。您可以从WSDL / XSD生成C#或Java代码。

Back to your original question. For the same of maintainability, the best practice is to defined Request and Response classes for each web methods and never pass strings, bools, integers directly. For example,

回到原来的问题。对于可维护性,最佳实践是为每个Web方法定义Request和Response类,而不是直接传递字符串,bool,整数。例如,

// in your Web service class
[WebMethod]
public UploadResponse Upload( UploadRequest request ) {
    ...
}
...

[Serializable]
public class UploadResponse {
  public bool IsSuccessful {
    get { ... }
    set { ... }
  }
}

[Serializable]
public class UploadRequest {
  public Allocation ReferenceAllocation {
    get { ... }
    set { ... }
  }
  // define other request properties
  // ...
}

If you defined SOAP bindings in your WSDL file, UploadRequest object is extracted from the SOAP message and deserialized. By the time the control reaches your WebMethod implementation, you have a deserialized UploadRequest object in memory with all of its properties set.

如果在WSDL文件中定义了SOAP绑定,则从SOAP消息中提取UploadRequest对象并进行反序列化。到控件到达WebMethod实现时,您在内存中有一个反序列化的UploadRequest对象,并设置了所有属性。

To have a method like this: public bool Upload(string xml) in a [WebService] class and parse XML inside the method implementation is definitely something you should consider moving away from.

要有一个像这样的方法:public bool在[WebService]类中上传(string xml)并在方法实现中解析XML绝对是你应该考虑转移的东西。

#3


As long as your complex types are in some way XmlSerializable, then you shouldn't have any problems just using those complex types. Let the framework do the heavy lifting for you. It will generate an appropriate WSDL and the data will get serialized all by itself rather than you having to worry about validation and serialization.

只要你的复杂类型以某种方式使用XmlSerializable,那么使用这些复杂类型就不会有任何问题。让框架为您做繁重的工作。它将生成一个适当的WSDL,数据将自行序列化,而不必担心验证和序列化。

[Serializable] is your friend.

[Serializable]是你的朋友。

#1


I would probably use the XSD with "xsd.exe" tool to create a XML Serializable object. Then you can deal with objects instead of string parameters. It also gives you the ability to not change the signatures of the WebService.

我可能会使用XSD和“xsd.exe”工具来创建XML Serializable对象。然后你可以处理对象而不是字符串参数。它还使您能够不更改WebService的签名。

If you change the XSD to add another parameter all you will need to do is recreate the class again using XSD.exe tool. Make good use of partial classes here. Separate your auto generated class from your business logic. This way you can recreate the the class definition if the XSD changes as many times as you want, but not touch your business logic.

如果您更改XSD以添加另一个参数,您需要做的是使用XSD.exe工具再次重新创建该类。在这里充分利用部分课程。将自动生成的类与业务逻辑分开。这样,如果XSD根据需要更改次数,则可以重新创建类定义,但不能触及业务逻辑。

XML Serialization in the .NET Framework

.NET Framework中的XML序列化

If you were using 3.5, you could also use LINQ to XML to quickly parse out your XML parameters.

如果您使用的是3.5,那么您还可以使用LINQ to XML快速解析XML参数。

#2


Jon, to answer your follow-up question first: If your clients are on multiple platforms (or at least, not all on .NET), the best approach is the so-called "WSDL-first". Define the service interface in WSDL - that's where services and methods will be defined - WSDL will reference a set of XSDs defining the data-holding objects passed to and returned from those methods. You can generate C# or Java code from WSDL/XSDs.

Jon,首先回答你的后续问题:如果你的客户在多个平台上(或者至少在.NET上不是全部),那么最好的方法就是所谓的“WSDL-first”。在WSDL中定义服务接口 - 即定义服务和方法的位置 - WSDL将引用一组XSD,这些XSD定义传递给这些方法并从这些方法返回的数据保持对象。您可以从WSDL / XSD生成C#或Java代码。

Back to your original question. For the same of maintainability, the best practice is to defined Request and Response classes for each web methods and never pass strings, bools, integers directly. For example,

回到原来的问题。对于可维护性,最佳实践是为每个Web方法定义Request和Response类,而不是直接传递字符串,bool,整数。例如,

// in your Web service class
[WebMethod]
public UploadResponse Upload( UploadRequest request ) {
    ...
}
...

[Serializable]
public class UploadResponse {
  public bool IsSuccessful {
    get { ... }
    set { ... }
  }
}

[Serializable]
public class UploadRequest {
  public Allocation ReferenceAllocation {
    get { ... }
    set { ... }
  }
  // define other request properties
  // ...
}

If you defined SOAP bindings in your WSDL file, UploadRequest object is extracted from the SOAP message and deserialized. By the time the control reaches your WebMethod implementation, you have a deserialized UploadRequest object in memory with all of its properties set.

如果在WSDL文件中定义了SOAP绑定,则从SOAP消息中提取UploadRequest对象并进行反序列化。到控件到达WebMethod实现时,您在内存中有一个反序列化的UploadRequest对象,并设置了所有属性。

To have a method like this: public bool Upload(string xml) in a [WebService] class and parse XML inside the method implementation is definitely something you should consider moving away from.

要有一个像这样的方法:public bool在[WebService]类中上传(string xml)并在方法实现中解析XML绝对是你应该考虑转移的东西。

#3


As long as your complex types are in some way XmlSerializable, then you shouldn't have any problems just using those complex types. Let the framework do the heavy lifting for you. It will generate an appropriate WSDL and the data will get serialized all by itself rather than you having to worry about validation and serialization.

只要你的复杂类型以某种方式使用XmlSerializable,那么使用这些复杂类型就不会有任何问题。让框架为您做繁重的工作。它将生成一个适当的WSDL,数据将自行序列化,而不必担心验证和序列化。

[Serializable] is your friend.

[Serializable]是你的朋友。