我最终走的方向接近我希望的方向,但“hack-ish”足以让我认为 SuperSaiyen 的建议是使用 AMF/ORM 是新项目/新建项目的更好解决方案。
为了举例/讨论,假设我正在使用数据库中的Person 表,并且有一个名为PeopleDataSet 的类型化数据集,其中包含PersonTableAdapter 和PersonDataTable。
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 (&) - 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 & to & on string columns
{
if (col.DataType == typeof(String) && !row.IsNull(col))
row[col] = (row[col] as string).Replace("&", "&");
}
}
}