How to force ASP.NET Web API to return JSON or XML

2020-02-02 04:17发布

I try to get the output XML or JSON data based on my input. I used the below WEB API code but not able to exact output.

public string Get(int id)
{
    if (GlobalConfiguration.Configuration.Formatters.XmlFormatter == null)
    {
        GlobalConfiguration.Configuration.Formatters.Add(GlobalConfiguration.Configuration.Formatters.XmlFormatter);
    }
    if (GlobalConfiguration.Configuration.Formatters.JsonFormatter == null)
    {
        GlobalConfiguration.Configuration.Formatters.Add(GlobalConfiguration.Configuration.Formatters.JsonFormatter);
    }
    if (id == 1)
    {
        GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.JsonFormatter);                
        GlobalConfiguration.Configuration.Formatters.XmlFormatter.UseXmlSerializer = true;                
    }
    else
    {
        GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);
        GlobalConfiguration.Configuration.Formatters.JsonFormatter.UseDataContractJsonSerializer = true;
    }
    return "value";
}

7条回答
聊天终结者
2楼-- · 2020-02-02 04:35

Add the below code app_start event in global.asax file. In API Url add the query string:

GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings.Add(
    new QueryStringMapping("type", "json", new MediaTypeHeaderValue("application/json")));

GlobalConfiguration.Configuration.Formatters.XmlFormatter.MediaTypeMappings.Add(
    new QueryStringMapping("type", "xml", new MediaTypeHeaderValue("application/xml")));

e.g.:

for xml : http://localhost:49533/api/?type=xml

for json: http://localhost:49533/api/?type=json
查看更多
小情绪 Triste *
3楼-- · 2020-02-02 04:35

If your request specifies the mime type, for example application/json, then web api will format the response appropriately.

If you are attempting to debug your web api manually, use a tool like Fiddler 2 to specify the type.

This article describes the concept.

查看更多
Evening l夕情丶
4楼-- · 2020-02-02 04:35

While the accepted answer by vijayjan15 seems the best way to go for your specific situation (that is, using the MediaTypeMappings), you could alternatively have two different methods, one that returns XML and one that returns JSON. To do that, you can instantiate a controller-specific HttpConfiguration (to avoid modifying the one in GlobalConfiguration.Configuration):

public MyReturnType GetMyTypeAsXml() {
    Configuration = new HttpConfiguration();
    Configuration.Formatters.Clear();
    Configuration.Formatters.Add(new XmlMediaTypeFormatter());

    return new MyReturnType();
}

public MyReturnType GetMyTypeAsJson() {
    Configuration = new HttpConfiguration();
    Configuration.Formatters.Clear();
    Configuration.Formatters.Add(new JsonMediaTypeFormatter());

    return new MyReturnType();
}

I'm not sure how much overhead there is in spinning up a new instance of HttpConfiguration (I suspect not a lot), but the new instance comes with the Formatters collection filled by default, which is why you have to clear it right after instantiating it. Note that it if you don't use Configuration = new HttpConfiguration(), and instead modify Configuration directly, it modifies the GlobalConfiguration.Configuration property (so, it would impact all your other WebApi methods - bad!).

查看更多
不美不萌又怎样
5楼-- · 2020-02-02 04:35

QueryStringMapping` is nice solution but I need a default value for type.

for xml : localhost:49533/api/?type=xml

for json: localhost:49533/api/

I solve that situation like that:

GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
var jSettings = new JsonSerializerSettings();

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings = jSettings;
GlobalConfiguration.Configuration.Formatters.XmlFormatter.MediaTypeMappings.Add(new QueryStringMapping("xml", "true", new MediaTypeHeaderValue("application/xml")));
查看更多
乱世女痞
6楼-- · 2020-02-02 04:37

What you are trying to do will not work in a multi-threaded environment. You cannot add to and remove from the formatters collection on a per-request basis. Here is a better way of accomplishing what you want.

public HttpResponseMessage Get(int id)
{
    Foo foo = new Foo();
    var content = new ObjectContent<Foo>(foo,
                    ((id == 1) ? Configuration.Formatters.XmlFormatter :
                                Configuration.Formatters.JsonFormatter));
    return new HttpResponseMessage()
    {
         Content = content
    };
}
查看更多
不美不萌又怎样
7楼-- · 2020-02-02 05:00

Looked into this a bit more, and found your answer in another post:

public HttpResponseMessage Get(int id)
{
    string content = "value";

    if (id == 1)
    {
        return Request.CreateResponse<string>(HttpStatusCode.OK, content, Configuration.Formatters.JsonFormatter);
    }

    return Request.CreateResponse<string>(HttpStatusCode.OK, content, Configuration.Formatters.XmlFormatter);
}
查看更多
登录 后发表回答