使用 DataContracts 在 WCF 和 ASMX 之间传递对象时出现问题

发布于 2024-10-23 18:36:03 字数 1772 浏览 1 评论 0原文

我正在尝试使用 ASMX/WCF 在站点(公共/私有)之间传递对象。我可以将序列化对象从私有 ASMX 服务获取到公共 WCF 服务,但无法反序列化该对象。下面的代码后面有错误。

调用私有 ASMX 服务的 WCF 服务。

[WebGet(UriTemplate = "{part}")]
public Distributor GetDistributorInventory(string part)
{
    const string url = "http://www.site.com/service/lookup.asmx/StockCheck?part=" + part;
    //This is a wrapper for a HttpWebRequest that returns a string
    string results = WebHelper.HttpRequest("GET", "text/xml", null, url, new CookieContainer());  
    byte[] byteArray = Encoding.ASCII.GetBytes(results);
    MemoryStream stream = new MemoryStream(byteArray);
    DataContractSerializer deserialize = new DataContractSerializer(typeof(Distributor));
    return (Distributor)deserialize.ReadObject(stream);
}

公共/私人服务中使用的合同

[DataContract(Namespace = "http://www.site.com/Services/", Name = "Inventory")]
public class Inventory
{
    [DataMember(Order = 1)]
    public string MPN{ get; set; }
    [DataMember(Order = 2)]
    public string DataSheetURL { get; set; }
    [DataMember(Order = 3)]
    public List<Distributor> Stock { get; set; }
}

[DataContract(Namespace = "http://www.site.com/Services/", Name = "Distributor")]
public class Distributor
{
    [DataMember(Order = 1)]
    public string Name { get; set; }
    [DataMember(Order = 2)]
    public string Part { get; set; }
    [DataMember(Order = 3)]
    public int Quantity { get; set; }
    [DataMember(Order = 4)]
    public string URL { get; set; }
}

错误消息:

第 1 行位置 166 中出现错误。期望名称空间“http://www.site.com/Services/”中的元素“Distributor”..遇到名称为“Inventory”的“元素” ,命名空间“http://www.site.com/Services/”。

我可能会以完全错误的方式来解决这个问题,所以关于更好的方法(带有示例)的建议将不胜感激。我的最终目标是在 WCF 和 WCF 之间传递对象。使用自定义对象和数据契约的 WCF 或 ASMX 服务。

I'm trying to use ASMX/WCF to pass objects between sites (public / private). I can get the serialized object from my private ASMX service to my public WCF service, but I can't deserialize the object. Code below followed by error.

WCF service that calls a private ASMX service.

[WebGet(UriTemplate = "{part}")]
public Distributor GetDistributorInventory(string part)
{
    const string url = "http://www.site.com/service/lookup.asmx/StockCheck?part=" + part;
    //This is a wrapper for a HttpWebRequest that returns a string
    string results = WebHelper.HttpRequest("GET", "text/xml", null, url, new CookieContainer());  
    byte[] byteArray = Encoding.ASCII.GetBytes(results);
    MemoryStream stream = new MemoryStream(byteArray);
    DataContractSerializer deserialize = new DataContractSerializer(typeof(Distributor));
    return (Distributor)deserialize.ReadObject(stream);
}

Contract used in both Public/Private Services

[DataContract(Namespace = "http://www.site.com/Services/", Name = "Inventory")]
public class Inventory
{
    [DataMember(Order = 1)]
    public string MPN{ get; set; }
    [DataMember(Order = 2)]
    public string DataSheetURL { get; set; }
    [DataMember(Order = 3)]
    public List<Distributor> Stock { get; set; }
}

[DataContract(Namespace = "http://www.site.com/Services/", Name = "Distributor")]
public class Distributor
{
    [DataMember(Order = 1)]
    public string Name { get; set; }
    [DataMember(Order = 2)]
    public string Part { get; set; }
    [DataMember(Order = 3)]
    public int Quantity { get; set; }
    [DataMember(Order = 4)]
    public string URL { get; set; }
}

Error Message:

Error in line 1 position 166. Expecting element 'Distributor' from namespace 'http://www.site.com/Services/'.. Encountered 'Element' with name 'Inventory', namespace 'http://www.site.com/Services/'.

I might be going about this the entirely wrong way, so suggestions on a better approach (with sample) would greatly appreciate. My end goal is to pass objects between WCF & WCF or ASMX services using custom objects and DataContracts.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

乖乖公主 2024-10-30 18:36:03

看起来它正在尝试反序列化为 Distributor,但 StockCheck 调用的响应正在返回 Inventory

Looks like it's trying to deserialize as Distributor but the response from the StockCheck call is returning a Inventory.

雅心素梦 2024-10-30 18:36:03

asmx 服务可能未使用 DataContractSerialiser。 此处是关于如何在 ASMX 服务中进行自定义序列化的简短视频

或者,您可以使用与 asmx 服务使用的相同序列化程序(XmlSerialiser?)在 WCF 服务中进行反序列化。

另一种选择是使用 Json 序列化程序。这里有一个示例。

The asmx service is probably not using the DataContractSerialiser. Here is short video on on how to do custom serialisation in a the ASMX service.

Or you could deserialise in the WCF service using the same serialiser that the asmx service is using (XmlSerialiser?)

Another option is to use the Json serialiser instead. There is an example here.

小草泠泠 2024-10-30 18:36:03

这是我找到的最终解决方案,以尽可能少的工作量完成这项工作。

  1. 我从将我的对象作为 XML 传递到 JSON(这是我的最终目标,尽管我从 XML 开始)

  2. 收到 JSON 对象后,我注意到它有一个包装器“d:”,并且有一个正在添加的属性“__type:”。知道需要删除这些元素后,我决定找到一种通用方法来删除这些元素。

  3. 我的通用解决方案是在 Codeplex 具有使用 Reg Ex 进行清理的扩展方法。非常简单。

这是我生成的代码:

[WebGet(UriTemplate = "{part}")]
public Distributor GetDistributorInventory(string part)
{
  const string url = "http://www.site.com/service/lookup.asmx/StockCheck";
  string results = WebHelper.HttpRequest("POST", "application/json; charset=utf-8", "{part: " + part + "}", url, new CookieContainer());

  Inventory inventory = new JavaScriptSerializer().CleanAndDeserialize<Inventory>(results);

  return inventory;
}

该解决方案的另一个好处是能够转换对象,而不管命名空间如何。这使得能够在我的源 ASMX 服务中使用对象“sender.Inventory”,并在我要使用该对象的 WCF 服务中使用对象“receiver.Inventory”。

Here is the final solution I found for making this work, with the least amount of work possible.

  1. I switched from passing my object as XML to JSON (was my final goal, tho I started with XML)

  2. After getting my JSON object received, I noticed it had a wrapper "d:" and had a property "__type:" that was being added. Knowing these needed to be removed, I decided to find a generic way to remove the elements.

  3. My generic solution was to use this code/article on Codeplex that had extension methods that did the clean-up using Reg Ex. Very simple.

Here is my resulting code:

[WebGet(UriTemplate = "{part}")]
public Distributor GetDistributorInventory(string part)
{
  const string url = "http://www.site.com/service/lookup.asmx/StockCheck";
  string results = WebHelper.HttpRequest("POST", "application/json; charset=utf-8", "{part: " + part + "}", url, new CookieContainer());

  Inventory inventory = new JavaScriptSerializer().CleanAndDeserialize<Inventory>(results);

  return inventory;
}

Another perk to this solution, is the ability to convert the object regardless of namespace. This results in being able to use the object "sender.Inventory" in my source ASMX service and the object "receiver.Inventory" in my WCF service where I'm going to consume the object.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文