How to provide custom mediatype formats for OData Api

情到浓时终转凉″ 提交于 2019-12-20 02:08:32

问题


I am developing an ASP.NET application that uses ODataApiController. The application shows users a grid by querying data and showing it in a table. I would like the ability to export to a number of different formats, including CSV and a custom XML format. Ideally, I would just take the same OData query the grid uses, set the Accepts header, and get back CSV or XML.

I've created MediaTypeFormatters to do what I need, but they only work with "regular" ApiController, not ODataApiController. Looking at the code in github, I see that OData has it's own MediaTypeFormatter scheme to handle various cases, and built in XML and JSON formatters. But I can't see how to hook into this to provide custom formats. I've attempted inheriting ODataMediaTypeFormatter, but a breakpoint set on it never hits.

I am only really interested in output formats here. How can I extend OdataApi to output different formats?


回答1:


You can use MediaTypeFormatter on OData queries as well. Just add a new class to your project that inherit MediaTypeFormatter. Then add this to your WebApiConfig file on Register:

config.Formatters.Add(new JSONPFormatter(new QueryStringMapping("$format","jsonp","application/javascript")));

If you then query your entity with the $format=jsonp it will return the entity as JSONP. You can also request it with the contenttype application/javascript to get a JSONP return.

Here is a full example for a MediaFormatter for JSONP return. You could easily change it for your need:

using MyProject.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.ServiceModel.Syndication;
using System.Threading.Tasks;
using System.Web;
using System.Xml;
using Newtonsoft.Json;


namespace SMSIdent.Modules.Formatter
{
    /// <summary>
    /// Adds a $format=jsop to all odata query
    /// </summary>
    public class JSONPFormatter : MediaTypeFormatter
    {
        private readonly string jsMIME = "application/javascript";

        public JSONPFormatter()
        {
            SupportedMediaTypes.Add(new MediaTypeHeaderValue(jsMIME));
        }

        public JSONPFormatter(MediaTypeMapping mediaTypeMapping) : this() 
        {

            MediaTypeMappings.Add(mediaTypeMapping);
        }

        //THis checks if you can POST or PUT to this media-formater
        public override bool CanReadType(Type type)
        {
            return false;
        }

        //this checks if you can GET this media. You can exclude or include your Resources by checking for their types
        public override bool CanWriteType(Type type)
        {
            return true;
        }

        //This actually takes the data and writes it to the response 
        public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, System.Net.Http.HttpContent content, System.Net.TransportContext transportContext)
        {
            //you can cast your entity
            //MyType entity=(MyType) value;
            var callback=HttpContext.Current.Request.Params["callback"];
            return Task.Factory.StartNew(() =>
            {
                using (StreamWriter sw = new StreamWriter(writeStream))
                {
                    if (string.IsNullOrEmpty(callback))
                    {
                        callback = "values";
                    }
                    sw.Write(callback + "(" + JsonConvert.SerializeObject(value, Newtonsoft.Json.Formatting.None,
                        new JsonSerializerSettings
                        {
                            ReferenceLoopHandling = ReferenceLoopHandling.Ignore
                        }) + ")");
                }

            });
        }
    }
}

Note: I'am using Web API 2. I don't know exactly if it also works in Web Api 1.



来源:https://stackoverflow.com/questions/28291547/how-to-provide-custom-mediatype-formats-for-odata-api

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!