Сериализация
Для этого предназначен конвейер ASP.NET. Действия вашего контроллера не возвращают результат клиенту, а скорее объект результата (ActionResult
), который затем обрабатывается на последующих этапах в конвейере ASP.NET. Вы можете переопределить класс ActionResult
. Обратите внимание, что FileResult, JsonResult, ContentResult
и FileContentResult
встроены в MVC3.
В вашем случае , вероятно, лучше вернуть что-то вроде RestResult
объекта. Этот объект теперь отвечает за форматирование данных в соответствии с запросом пользователя (или какими-либо дополнительными правилами, которые у вас могут быть):
public class RestResult<T> : ActionResult
{
public override void ExecuteResult(ControllerContext context)
{
string resultString = string.Empty;
string resultContentType = string.Empty;
var acceptTypes = context.RequestContext.HttpContext.Request.AcceptTypes;
if (acceptTypes == null)
{
resultString = SerializeToJsonFormatted();
resultContentType = "application/json";
}
else if (acceptTypes.Contains("application/xml") || acceptTypes.Contains("text/xml"))
{
resultString = SerializeToXml();
resultContentType = "text/xml";
}
context.RequestContext.HttpContext.Response.Write(resultString);
context.RequestContext.HttpContext.Response.ContentType = resultContentType;
}
}
Десериализация
Это немного сложнее. Мы используем метод Deserialize<T>
в базовом классе контроллера. Обратите внимание, что этот код не готов к работе , поскольку чтение всего ответа может привести к переполнению вашего сервера:
protected T Deserialize<T>()
{
Request.InputStream.Seek(0, SeekOrigin.Begin);
StreamReader sr = new StreamReader(Request.InputStream);
var rawData = sr.ReadToEnd(); // DON'T DO THIS IN PROD!
string contentType = Request.ContentType;
// Content-Type can have the format: application/json; charset=utf-8
// Hence, we need to do some substringing:
int index = contentType.IndexOf(';');
if(index > 0)
contentType = contentType.Substring(0, index);
contentType = contentType.Trim();
// Now you can call your custom deserializers.
if (contentType == "application/json")
{
T result = ServiceStack.Text.JsonSerializer.DeserializeFromString<T>(rawData);
return result;
}
else if (contentType == "text/xml" || contentType == "application/xml")
{
throw new HttpException(501, "XML is not yet implemented!");
}
}