【问题标题】:How do I pass object (ObjectProxy) from Flex back to .NET WebService?如何将对象 (ObjectProxy) 从 Flex 传递回 .NET WebService?
【发布时间】:2011-08-10 23:12:56
【问题描述】:

因此,网上有大量关于如何处理返回DataSetDataTable 的.NET WebMethod 的Flex 文章。这是一个例子:

Handling web service results that contain .NET DataSets or DataTables

所以,我知道如何使用result.Tables.<tablename>.Rows 等。但我似乎无法弄清楚或在网上找到的是如何走向另一个方向 - 一种将对象或表从 Flex 传递回 .NET Web 服务的方法,不会弯腰将 XML 作为字符串传递,或者使Web 服务方法为要存储的对象的每个属性/列都有一个参数。 肯定有其他人,比我更聪明,已经解决了这个问题。

我正在使用 ASP.NET 2.0 类型化数据集,如果我可以将一个对象或对象数组从 Flex 传递到 Web 服务,填充我的类型化 DataTable,然后执行 Update(),那就太好了通过相应的类型化 TableAdapter。我的梦想是[WebMethod] 类似于以下之一:

public void SaveObject(TypedDataTable objToSave) { ... } 
public void SaveObject(TypedDataSet objToSave) { ... }

我已经将类型化的数据表保存到数据库中,我知道如何做这部分,甚至知道一些技巧,但我们有XML being passed back-and-forth as a string - eww。我正在尝试采用更基于对象的方法。

【问题讨论】:

    标签: asp.net apache-flex web-services dataset


    【解决方案1】:

    最好的基于对象的方法是AMF。我认为在您的开发周期中更改集成层可能有点晚了,但否则我不知道有一种方法可以将您的对象编组回 XML 或将它们分离成原始组件。

    对于 AMF 的 .NET 实现,请查看:

    令人惊讶的是,一旦使用 AMF,事情就变得如此简单,例如使用 Mate MVC 框架和将复杂对象传递给服务器的 AMF 调用看起来像这样:

    <mate:RemoteObjectInvoker instance="yourWebservice"  method="saveComplexObject" showBusyCursor="true" >
        <mate:resultHandlers>
            <mate:CallBack method="saveComplexObjectSuccess" arguments="{[resultObject]}" />
        </mate:resultHandlers>
        <mate:faultHandlers>
            <mate:MethodInvoker generator="{DataManager}" method="presentFault" arguments="{fault}" />
        </mate:faultHandlers>
    </mate:RemoteObjectInvoker>
    

    结果和错误处理程序是可选的。

    【讨论】:

    • 嗯...很有趣,尽管粗略浏览一下网络(在 FlourineFX 上),与网络服务相比,设置起来看起来很复杂。但也许这些例子只是过于复杂的设置。它可以与 WebService 方法一起使用吗? .NET 类型的数据集/数据表呢?
    • 设置有点复杂(来自 Java 人,所以 YMMV)但是一旦设置好,添加服务时就没有额外的配置了。至于 .Net 类型的对象,只需在 ActionScript 中创建相同的对象,使用 RemoteClass 注释对其进行注释:[RemoteClass(alias="com.stackoverflow.somepackage.SomeObject")] 和 viola,就完成了。随着代码的增长,技术的扩展性非常好,因为远程类注册本质上是唯一的配置。
    • 我实际上想知道它们是如何专门处理类型化数据集/表的,但我想如果我想更纯粹地基于对象,迁移到 LinqToSQL 或 EF 是明智的。
    • 我确实想出了另一种解决方案,有点麻烦,但我会尽量记住有时会在这里发布它,因为它可能会对某人有所帮助。不过,使用 LinqToSQL/EF 和/或使用 AMF 听起来是个好主意。我很好奇,您使用哪种工具 - FlourineFX 或 WebORB?
    • 发布它,它会帮助某人。我更喜欢 SpringFlex (springsource.org/spring-flex),但在 .NET 世界中,我目前使用的是 FluorineFX,主要是因为它的 FOSS。
    【解决方案2】:

    我最终走的方向接近我希望的方向,但“hack-ish”足以让我认为 SuperSaiyen 的建议是使用 AMF/ORM 是新项目/新建项目的更好解决方案。

    为了举例/讨论,假设我正在使用数据库中的Person 表,并且有一个名为PeopleDataSet 的类型化数据集,其中包含PersonTableAdapterPersonDataTable

    READ 在 .NET 网络服务中看起来像这样:

    [WebMethod] 
    public PeopleDataSet.PersonDataTable GetAllPeople() {
        var adapter = new PersonTableAdapter();
        return adapter.GetData();
    }
    

    ...在 Flex 中会给你一个 result 对象,你可以像这样使用它:

    // FLEX (AS3)
    something.dataProvider = result.Tables.Person.Rows;
    

    查看我在问题中提供的链接,了解有关 Flex 如何处理该问题的更多详细信息。

    CREATE/UPDATE - 这是我必须弄清楚的部分,也是我问这个问题的原因。这次首先是 Flex:

    // FLEX (AS3)
    var person:Object = { 
        PersonID: -1,                // -1 for CREATE, actual ID for UPDATE
        FirstName: "John", 
        LastName: "Smith", 
        BirthDate: "07/19/1983",
        CreationDate: "1997-07-16T19:20+01:00" // need W3C DTF for Date WITH Time
    };
    _pplWebSvcInstance.SavePerson(person); // do the web method call
    

    (有关处理这些 W3C 日期时间,请参阅 How to parse an ISO formatted date in Flex (AS3)?

    然后,在 .NET Web 服务方面,诀窍是在 Web 方法的参数上找出正确的类型。如果您只使用Object,然后使用调试器进行调用,您将看到.NET 显示它是XmlNode[]。这是我想出的办法:

    [WebMethod]
    public int SavePerson(PeopleDataSet p) {
        // Now 'p' will be a PeopleDataSet with a Table called 'p' that has our data
        // row(s) (just row, in this case) as string columns in random order.
        // It WILL NOT WORK to use PeopleDataSet.PersonDataTable as the type for the
        // parameter, that will always result in an empty table. That is why the 
        // LoadFlexDataTable utility method below is necessary.
    
        var adapter = new PersonTableAdapter();
        var tbl = new PeopleDataSet.PersonDataTable();
        tbl.LoadFlexDataTable(p.Tables[0]); // see below
    
        // the rest of this might be familiar territory for working with DataSets
        PeopleDataSet.PersonRow row = tbl.FirstOrDefault();
        if (row != null) {
            if (row.PersonID > 0) {  // doing UPDATE
                row.AcceptChanges();
                row.SetModified();
            }
            else {  // doing CREATE
                row.CreationDate = DateTime.UtcNow; // set defaults here
                row.IsDeleted = false;
            }
            adapter.Update(row); // database call
            return row.PersonID;
        }
        return -1;
    }
    

    现在,您在上面看到的 kluge 实用程序方法被调用。我是作为扩展方法做的,这是可选的:

        // for getting the Un-Typed datatable Flex gives us into our Typed DataTable
        public static void LoadFlexDataTable(this DataTable tbl, DataTable flexDataTable)
        {            
            tbl.BeginLoadData();
            tbl.Load(flexDataTable.CreateDataReader(), LoadOption.OverwriteChanges);
            tbl.EndLoadData();
    
            // Probably a bug, but all of the ampersand (&) in string columns will be
            // unecessarily escaped (&amp;) - kluge to fix it.
            foreach (DataRow row in tbl.Rows)
            {
                row.SetAdded(); // default to "Added" state for each row
                foreach (DataColumn col in tbl.Columns) // fix &amp; to & on string columns
                {
                    if (col.DataType == typeof(String) && !row.IsNull(col))
                        row[col] = (row[col] as string).Replace("&amp;", "&");
                }
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-17
      • 1970-01-01
      • 2011-08-17
      • 1970-01-01
      • 2011-06-30
      相关资源
      最近更新 更多