カスタム モデル バインダーを作成できます。例を見てみましょう。次のコントローラーがあるとします。
public class HomeController : Controller
{
// Serve the view initially
public ActionResult Index()
{
return View();
}
// This will be called using AJAX and return an XML document to the
// client that will be manipulated using javascript
public ActionResult GetXml()
{
return Content("<foo><bar id=\"1\">the bar</bar></foo>", "text/xml");
}
// This will be called using AJAX and passed the new XML to persist
[HttpPost]
public ActionResult Save(XDocument xml)
{
// TODO: save the XML or something
return Json(new { success = true });
}
}
クライアントでは、次の JavaScript を使用できます。
<script type="text/javascript">
// send an AJAX request to retrieve the XML initially
$.ajax({
url: '@Url.Action("getxml")',
type: 'GET',
cache: false,
success: function (data) {
// The data variable will contain the initial xml
// Now let's manipulate it:
$(data).find('bar').attr('id', '7');
var xmlString = data.xml ? data.xml : (new XMLSerializer()).serializeToString(data);
// Let's send the modified XML back to the server using AJAX:
$.ajax({
url: '@Url.Action("save")',
type: 'POST',
contentType: 'text/xml',
data: xmlString,
success: function (result) {
// ...
}
});
}
});
</script>
そして最後の部分は、コントローラーの保存アクションが XDocument を取得できるように、XDocument タイプのカスタム モデル バインダーを作成することです。
public class XDocumentModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var request = controllerContext.HttpContext.Request;
if (!request.ContentType.StartsWith("text/xml", StringComparison.OrdinalIgnoreCase))
{
return null;
}
return XDocument.Load(request.InputStream);
}
}
これは Application_Start に登録され、XDocument タイプに関連付けられます。
ModelBinders.Binders.Add(typeof(XDocument), new XDocumentModelBinder());