asp.net-mvc - 构建与数据格式分离的 ASP.NET MVC REST API 代码的最佳方法?

标签 asp.net-mvc xml json rest loose-coupling

我正在 ASP.NET MVC 中创建一个 REST API。我希望请求和响应的格式为 JSON 或 XML,但是我也想让添加其他数据格式变得容易,并且可以轻松地先创建 XML,然后再添加 JSON。

基本上,我想指定我的 API GET/POST/PUT/DELETE 请求的所有内部工作方式,而不必考虑数据以何种格式传入或将以何种格式保留,我可以稍后轻松指定格式或根据客户更改它。所以一个人可以使用 JSON,一个人可以使用 XML,一个人可以使用 XHTML。然后我也可以添加另一种格式,而无需重写大量代码。

我不想在所有 Action 的末尾添加一堆 if/then 语句来确定数据格式,我猜我可以使用接口(interface)或继承或之类的,只是不确定最好的方法。

最佳答案

序列化

ASP.NET 管道就是为此而设计的。您的 Controller 操作不会将结果返回给客户端,而是将结果对象 ( ActionResult ) 返回给 ASP.NET 管道中的后续步骤。您可以覆盖 ActionResult类(class)。注意 FileResult, JsonResult, ContentResultFileContentResult从 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>基 Controller 类上的方法。请注意,此代码未准备好生产,因为读取整个响应可能会使您的服务器溢出:

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!");
    }
}

关于asp.net-mvc - 构建与数据格式分离的 ASP.NET MVC REST API 代码的最佳方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6280418/

相关文章:

asp.net-mvc - URL 重写和 IIS Express : some rules work, 有些没有

PHP5 : Iterating through a list of child nodes (equivalent of child_nodes())?

C# XML 查找第一个元素后代

python - 将 xml 解析为 python 中的 pandas 数据框

asp.net-mvc - 日期格式不正确的 MVC DateTime 绑定(bind)

jquery - 使用 JQuery 编写时,变音符号在 Web 应用程序中无法正确呈现

java - 这个日期的格式是什么

java - 如何断言 JSON 对象中不存在某个字段

c# - MVC 4 : Create new Razor View from string not from file path

javascript - 从 API 读取和解析 JSON 响应