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

我在ASP.NET MVC中创建REST API.我希望请求和响应的格式是 JSON或XML,但是我也想让它更容易添加另一种数据格式,并且很容易先创建XML并稍后添加JSON.

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

我不想在我的所有操作结束时添加一堆if / then语句并确定数据格式,我猜我有一些方法可以使用接口或继承等来做到这一点,只是不确定最好的方法.

解决方法

序列化

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

相关文章

### 创建一个gRPC服务项目(grpc服务端)和一个 webapi项目(...
一、SiganlR 使用的协议类型 1.websocket即时通讯协议 2.Ser...
.Net 6 WebApi 项目 在Linux系统上 打包成Docker镜像,发布为...
一、 PD简介PowerDesigner 是一个集所有现代建模技术于一身的...
一、存储过程 存储过程就像数据库中运行的方法(函数) 优点:...
一、Ueditor的下载 1、百度编辑器下载地址:http://ueditor....