如何将对象(ObjectProxy)从Flex传递回.NET WebService?

时间:2011-08-01 16:08:19

标签: asp.net flex web-services dataset

因此,有大量关于如何处理返回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 Typed DataSet,如果我可以将一个对象或一组对象从Flex传递到Web服务,填充我的Typed DataTable并执行更新,那将是非常好的()通过相应的类型化TableAdapter。我的梦想是[WebMethod]之类的东西:

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

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

2 个答案:

答案 0 :(得分: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>

结果和故障处理程序是可选的。

答案 1 :(得分:0)

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

为了示例/讨论,假设我正在使用数据库中的Person表,并且有一个名为PeopleDataSet的类型化DataSet,其PersonTableAdapterPersonDataTable } 用它。

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

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

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

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

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

创建/更新 - 这是我必须弄清楚的部分,以及为什么我问这个问题。 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方法的参数上找出正确的Type。如果你只使用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;", "&");
            }
        }
    }