How to provide custom mediatype formats for OData Api

后端 未结 1 1968
暖寄归人
暖寄归人 2021-01-19 05:37

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 abilit

相关标签:
1条回答
  • 2021-01-19 06:02

    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.

    0 讨论(0)
提交回复
热议问题