自定义TypeConverter把基础类型转换为复杂类型

时间:2023-03-08 21:05:18

原文(http://tech.it168.com/d/2008-06-30/200806300953554_all.shtml)

TypeConverter对于编写ASP.NET Server Control的朋友可谓是再熟悉不过了。我们通过示例,一步一步地来查看如何在Atlas中使用自定义TypeConverter。

首先,定义一个复杂类型Employee:

 [TypeConverter(typeof(EmployeeConverter))]
public class Employee
{
public string Name; public int Age;
}

可以看到,我们使用了TypeConverterAttribute将稍后会讲解的EmployeeConverter关联到Employee上。

接着,和上一个例子一样,我们写一个支持HTTP GET访问的Web Services方法,只是参数使用了复杂类型。

 [WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class HttpGetEmployeeService : System.Web.Services.WebService { [WebMethod]
[WebOperation(true, ResponseFormatMode.Xml)]
public XmlDocument SubmitEmployee(Employee employee)
{
XmlDocument responseDoc = new XmlDocument();
responseDoc.LoadXml(
"<?xml-stylesheet type=\"text/xsl\" href=\"Employee.xsl\"?>" +
"<Employee><Name></Name><Age></Age></Employee>");
responseDoc.SelectSingleNode("//Name").InnerText = employee.Name;
responseDoc.SelectSingleNode("//Age").InnerText = employee.Age.ToString();
return responseDoc;
}
}

然后是所需的Xslt文件:

 <?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/Employee">
<html>
<head>
<title>Thanks for your participation</title>
</head>
<body style="font-family:Verdana; font-size:13px;">
<h4>Here's the employee you submitted:</h4>
<div>
<xsl:text>Name: </xsl:text>
<xsl:value-of select="Name" />
</div>
<div>
<xsl:text>Age: </xsl:text>
<xsl:value-of select="Age" />
</div>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

上面这些对于看过之前一片文章的朋友们来说应该很熟悉。接下来,我们就进入正题,定义一个EmployeeConverter。代码如下:

 public class EmployeeConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof(String))
{
return true;
} return false;
} public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
IDictionary<string, object> dictObj =
JavaScriptObjectDeserializer.DeserializeDictionary(value.ToString()); Employee emp = new Employee();
emp.Name = dictObj["Name"].ToString();
emp.Age = (int)dictObj["Age"]; return emp;
}
}

EmployeeConverter继承了TypeConverter,首先覆盖CanConvertFrom方法表明使用EmployeeConverter可以将一个String转换成另一个对象。接着在覆盖ConvertFrom方法,将传入的value值转换为一个复杂对象Employee。这里为了方便,我们把Employee对象在客户端JOSN序列化,然后在服务器端再序列化回来,事实上,这种基础类型到复杂类型的转换,完全可以使用任何方式。

代码都非常简单,也容易理解,因此我们直接看一下使用代码。由于代码很少,就将Javascript和HTML一并贴出了:

 <html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Convert Primitive Object using Customized TypeConverter</title>
<script language="javascript">
function submitEmployee()
{
var emp = new Object();
emp.Name = $("txtName").value;
emp.Age = parseInt($("txtAge").value, ); var serializedEmp = Sys.Serialization.JSON.serialize(emp);
var url = "HttpGetEmployeeService.asmx?mn=SubmitEmployee&employee=" + encodeURI(serializedEmp);
window.open(url);
}
</script>
</head>
<body style="font-family:Verdana; font-size:13px;">
<form runat="server">
<atlas:ScriptManager ID="ScriptManager1" runat="server" /> <div>Name:<input type="text" id="txtName" /></div>
<div>Age:<input type="text" id="txtAge" /></div>
<input type="button" value="Submit" onclick="submitEmployee();" />
</form>
</body>
</html>

在奠基“Submit”按钮之后,会调用submitEmployee函数,这个函数根据用户的输入构造一个Employee对象,然后再使用和上一篇文章相同的办法拼接URL,最后使用window.open打开。

相关文章