ฉันจะรับ ASP.NET Web API เพื่อส่งคืน JSON แทนที่จะเป็น XML โดยใช้ Chrome ได้อย่างไร


1220

การใช้ASP.NET Web API ที่ใหม่กว่าในChromeฉันเห็น XML - ฉันจะเปลี่ยนเป็นขอJSONเพื่อให้สามารถดูได้ในเบราว์เซอร์ได้อย่างไร ฉันเชื่อว่ามันเป็นเพียงส่วนหนึ่งของส่วนหัวของคำขอฉันจะแก้ไขให้ถูกต้องหรือไม่


8
มีการสนทนาที่นี่เพื่อให้การส่งคืน JSON เฉพาะพฤติกรรมเริ่มต้น: github.com/aspnet/Mvc/issues/1765
Natan

คำตอบ:


1737

ฉันเพิ่งเพิ่มสิ่งต่อไปนี้ในApp_Start / WebApiConfig.csชั้นเรียนในโครงการMVC Web APIของฉัน

config.Formatters.JsonFormatter.SupportedMediaTypes
    .Add(new MediaTypeHeaderValue("text/html") );

ทำให้แน่ใจว่าคุณได้ JSON แบบสอบถามมากที่สุด แต่คุณจะได้รับเมื่อคุณส่งXMLtext/xml

หากคุณต้องการที่จะมีการตอบสนองContent-Typeเป็นapplication/jsonโปรดตรวจสอบคำตอบของทอดด์ด้านล่าง

NameSpaceSystem.Net.Http.Headersใช้


115
นี่เป็นคำตอบที่ถูกมองข้ามอย่างน่าประหลาดใจและถึงแม้ว่าคำถามดั้งเดิมจะไม่ชัดเจนทั้งหมดนี้ทำให้ JSON เป็นคำตอบเริ่มต้นสำหรับเว็บเบราว์เซอร์โดยตรง (ซึ่งส่ง Accept: text / html) ทำได้ดีมาก
gregmac

16
+1 ไกลคำตอบที่ดีที่สุด ฉันคิดว่ามีคนจำนวนมากที่เลือกที่จะลบ XML อย่างสมบูรณ์เพราะพวกเขาไม่เห็น JSON ในเบราว์เซอร์
Derek Hunziker

3
ฉันพบเมื่อฉันทำสิ่งนี้ข้อมูลที่บุคคลที่สามให้มาพร้อมกับแท็กตัวแบ่ง HTML ในนั้นจะจบลงด้วยการคืนค่าขนส่ง JSON นั้นไม่ถูกต้อง ดีกว่าที่จะใช้คำตอบที่ยอมรับถ้าสิ่งนี้มีผลกับคุณ
Stonetip

23
โปรดทราบว่าการตอบสนองของส่วนหัวจะยังคงเป็นContent-Type text/html
Mrchief

78
นี่มันช่างน่ากลัว ส่วนหัวชนิดเนื้อหาการตอบสนองควรเป็น application / json "โซลูชัน" นี้ทำให้ข้อความ / html
meffect

501

หากคุณทำสิ่งนี้ในที่WebApiConfigคุณจะได้รับ JSON โดยค่าเริ่มต้น แต่มันจะยังช่วยให้คุณกลับ XML ถ้าคุณผ่านtext/xmlเป็นAcceptส่วนหัวของคำขอ

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        var appXmlType = config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml");
        config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);
    }
}

หากคุณไม่ได้ใช้ประเภทโครงการ MVC ดังนั้นจึงไม่มีคลาสนี้ให้เริ่มด้วยดูคำตอบนี้สำหรับรายละเอียดเกี่ยวกับวิธีรวมเข้าด้วยกัน


51
เพียงสังเกตพฤติกรรมเดิมนั้นถูกต้อง Chrome ร้องขอที่application/xmlมีระดับความสำคัญ 0.9 และที่*/*มีความสำคัญ 0.8 ด้วยการลบapplication/xmlคุณจะลบความสามารถสำหรับ Web API เพื่อส่งคืน XML หากไคลเอ็นต์ร้องขอเฉพาะ เช่นถ้าคุณส่ง "ยอมรับ: application / xml" คุณจะยังคงได้รับ JSON
porges

11
เป็นฉันหรือประโยคแรกไม่ถูกต้อง? รหัสดูเหมือนจะลบ XML ทั้งหมดไม่ใช่เพียงแค่เปลี่ยนค่าเริ่มต้น
NickG

6
@NickG: วิธีแก้ปัญหาที่ถูกมองข้ามที่นี่และ IMHO เป็นตัวเลือกที่ดีกว่ามาก (รักษาการใช้งาน / xml) เป็นวิธีแก้ปัญหาที่เสนอโดย Felipe Leusin ที่ต่ำกว่าในหน้านี้ ใช้ config.Formatters.XmlFormatter.SupportedMediaTypes.Add (MediaTypeHeaderValue ใหม่ ("ข้อความ / html"));
โคเฮน

1
ดังนั้นเราจะทำมันผ่านทางเว็บการตั้งค่าเพื่อให้เราได้รับ json โดยค่าเริ่มต้นและ XML หากมีการร้องขอ?
Kyle

4
@Felipse คำตอบของ Leusin ด้านล่างนี้สั้นลงและใช้งานได้ดีกว่า
Ken Smith

313

การใช้ RequestHeaderMapping ทำงานได้ดียิ่งขึ้นเพราะมันตั้งค่าContent-Type = application/jsonในส่วนหัวการตอบสนองซึ่งช่วยให้ Firefox (ด้วย JSONView add-on) เพื่อจัดรูปแบบการตอบสนองเป็น JSON

GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings
.Add(new System.Net.Http.Formatting.RequestHeaderMapping("Accept", 
                              "text/html",
                              StringComparison.InvariantCultureIgnoreCase,
                              true, 
                              "application/json"));

6
นี่เป็นวิธีการแก้ปัญหาแบบลีนและง่ายที่สุดและ Fiddler ตรวจจับประเภทเนื้อหาที่ส่งคืนเป็น josn
Steve Johnson

4
ดี! คุณจะแนะนำให้ใส่รหัสนี้ไว้ที่ใด?
Tim Abell

9
มันควรจะอยู่ใน WebApiConfig.cs
Animesh

9
ทำงานให้ฉัน ฉันต้องการเพิ่มการใช้ System.Net.Http.Formatting;
bbsimonbb

1
การเชื่อมโยงเพื่อความสะดวกของตัวเอง: คำตอบนี้เล่นอย่างกับขั้นตอนการติดตั้งอีกฉันมักจะดำเนินการ: stackoverflow.com/a/28337589/398630
BrainSlugs83

308

ฉันชอบแนวทางของ Felipe Leusinดีที่สุด - ตรวจสอบให้แน่ใจว่าเบราว์เซอร์รับ JSON โดยไม่กระทบการเจรจาต่อรองเนื้อหาจากลูกค้าที่ต้องการ XML จริง ๆ สิ่งเดียวที่ขาดหายไปสำหรับฉันคือส่วนหัวการตอบสนองยังคงมีประเภทเนื้อหา: text / html เหตุใดจึงเป็นปัญหา เนื่องจากฉันใช้ส่วนขยาย JSON Formatter Chromeซึ่งตรวจสอบประเภทเนื้อหาและฉันไม่ได้รับการจัดรูปแบบที่สวยงามที่ฉันคุ้นเคย ฉันแก้ไขด้วยตัวจัดรูปแบบกำหนดเองแบบง่ายที่ยอมรับการร้องขอ text / html และส่งคืนการตอบกลับของแอปพลิเคชัน / json:

public class BrowserJsonFormatter : JsonMediaTypeFormatter
{
    public BrowserJsonFormatter() {
        this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
        this.SerializerSettings.Formatting = Formatting.Indented;
    }

    public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType) {
        base.SetDefaultContentHeaders(type, headers, mediaType);
        headers.ContentType = new MediaTypeHeaderValue("application/json");
    }
}

ลงทะเบียนเช่นนั้น:

config.Formatters.Add(new BrowserJsonFormatter());

24
ในนวกรรมิกเพิ่มthis.SerializerSettings.Formatting = Formatting.Indented;ถ้าคุณต้องการพิมพ์สวยโดยไม่มีส่วนขยายเบราว์เซอร์
Alastair Maw

10
ทำไมคุณต้องการพิมพ์ให้สวยกว่าสาย?
meffect

8
คำตอบของ @dmit77 ไม่ดีกว่า (สั้นกระชับกว่า) ใช่ไหม
H.Wolper

8
@ rediegroves คุณไม่ต้องการพิมพ์สวยผ่านลวด คุณต้องการให้เซิร์ฟเวอร์ส่งจำนวนบิตน้อยที่สุดผ่านสาย (เช่น: ไม่มีช่องว่าง) จากนั้นคุณต้องการให้เบราว์เซอร์จัดรูปแบบเป็นอย่างดีพร้อมด้วย addons และอื่น ๆ Javascript ต้องแยกวิเคราะห์ JSON โดยปกติแล้วทำไมทำให้ช้าลงโดยแนะนำการจัดรูปแบบที่ไม่จำเป็น
meffect

13
สำหรับชาว Google ที่กำลังมองหา: อย่าลืมเพิ่มusing System.Net.Http.Formattingและusing Newtonsoft.Json
Berriel

186

เคล็ดลับฉบับย่อ MVC4 # 3 - การลบฟอร์แมต XML จาก ASP.Net Web API

ในการGlobal.asaxเพิ่มบรรทัด:

GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();

ชอบมาก:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);

    BundleTable.Bundles.RegisterTemplateBundles();
    GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
}

9
ใช้งานได้ดีกว่ามากหากมี JSON เป็นค่าเริ่มต้นแทนที่จะเป็น XML
whitneyland

5
แต่คุณสามารถคืนค่า xml ได้หรือไม่
Thomas Stock

99
ฉันทดสอบแล้วและคุณทำไม่ได้ ดังนั้นนี่คือการลบการสนับสนุน XML .. ถูกเตือนคนที่รักของ Google
Thomas Stock

3
หากคุณได้ดูคำตอบของฉันด้านล่างนี้จะให้ xml ยังคงกลับมาถ้าคุณต้องการ แต่ช่วยให้เว็บไซต์ตอบสนองกับ JSON ไปยังเบราว์เซอร์
Glenn Slaven

3
@ GlennSlaven ใช่คำตอบของคุณควรเป็นคำตอบที่ถูกต้อง
radu florescu

114

ในWebApiConfig.csเพิ่มไปยังจุดสิ้นสุดของฟังก์ชันRegister :

// Remove the XML formatter
config.Formatters.Remove(config.Formatters.XmlFormatter);

แหล่ง


XmlFormatter ใหม่ใน MVC4 หรือไม่
Glenn Slaven

1
ใน MVC5 สามารถทำได้โดยแทนที่การกำหนดค่าด้วย GlobalConfiguration การกำหนดค่า
Steven

4
สำหรับโปรเจ็กต์ที่ต้องสนับสนุน JSON เท่านั้นและไม่อนุญาตให้ปล่อย XML นี่เป็นตัวเลือกที่ดีที่สุด
Luc C

1
config.Formatters.Add (config.Formatters.JsonFormatter);
Cas Bloem

3
มันแย่มาก - สิ่งนี้จะส่งคืน JSON เสมอไม่ว่าจะเกิดอะไรขึ้นแม้ว่าลูกค้าจะขอ XML โดยเฉพาะในส่วนหัวของประเภทเนื้อหา
BrainSlugs83

94

ในGlobal.asaxฉันใช้รหัสด้านล่าง URI ของฉันเพื่อรับ JSON คือhttp://www.digantakumar.com/api/values?json=true

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);

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

2
เยี่ยมมาก วิธีการของคุณคาดหวังว่าพารามิเตอร์คืออะไร? ชอบlocalhost: 61044 / api / values ​​/ getdate? json = true, date = 2012-08-01
LT.Nolo

รูปแบบของข้อมูลเว็บ api ที่ส่งคืนโดยค่าเริ่มต้น มันคือ json หรือ webapi? ขอบคุณ
โทมัส

54

ดูการเจรจาต่อรองเนื้อหาใน WebAPI โพสต์บล็อกเหล่านี้ ( ตอนที่ 1และส่วนที่ 2 ) มีรายละเอียดที่ยอดเยี่ยมและละเอียดถี่ถ้วนอธิบายวิธีการทำงานของบล็อก

กล่าวโดยย่อคือคุณพูดถูกและจำเป็นต้องตั้งค่าAcceptหรือContent-Typeขอส่วนหัว ป.ร. Accept: application/jsonให้การดำเนินการของคุณไม่ได้รหัสที่จะกลับมาในรูปแบบที่เฉพาะเจาะจงคุณสามารถตั้งค่า


6
"ดังนั้นฉันสามารถดูได้ในเบราว์เซอร์"
Spongman

1
@ Spongman ใช่คุณทำได้ แต่ใช้ส่วนขยายเช่นไคลเอ็นต์ REST - เบราว์เซอร์ส่วนใหญ่จะมีส่วนขยายดังกล่าว การพิมพ์ URL โดยตรงในเบราว์เซอร์คือ 1 จำกัด มากเกินไป (ไม่สามารถควบคุมส่วนหัวไม่สามารถโพสต์ข้อมูลและอื่น ๆ ); 2. ไม่ถูกต้อง - เบราว์เซอร์ไม่ได้ใช้เว็บ API ตามที่ตั้งใจไว้ - คุณไม่สามารถเชื่อถือได้ว่าทำการทดสอบอย่างถูกต้อง ดังนั้นอีกครั้งไคลเอนต์ REST ที่ดีจะแก้ไขปัญหานั้น
Ivaylo Slavov

45

เนื่องจากคำถามคือเฉพาะ Chrome คุณสามารถรับส่วนขยายบุรุษไปรษณีย์ซึ่งช่วยให้คุณกำหนดประเภทเนื้อหาคำขอ

บุรุษไปรษณีย์


ใน Firefox เพียงแค่ไปที่เกี่ยวกับ config ค้นหา accept.default และเปลี่ยนแปลงเนื้อหาของการกำหนดค่าnetwork.http.accept.default text/html,application/xhtml+xml,application/json;q=0.9,application/xml;q=0.8,*/*;q=0.7
Bjartur Thorlacius

หรือดีกว่าเพียงtext/html,application/xhtml+xml;q=1.0,*/*;q=0.7เพื่อหลีกเลี่ยงโฮสต์ที่มีบั๊กเช่น Bitbucket จากการให้บริการ JSON เบราว์เซอร์ของคุณโดยไม่ได้ตั้งใจแทน HTML
Bjartur Thorlacius

URL เสียชีวิต ใหม่คือchrome.google.com/webstore/detail/postman/… .
Falcon Momot

35

ทางเลือกหนึ่งที่รวดเร็วคือการใช้ความเชี่ยวชาญ MediaTypeMapping นี่คือตัวอย่างของการใช้ QueryStringMapping ในเหตุการณ์ Application_Start:

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

ตอนนี้เมื่อใดก็ตามที่ URL มีการสอบถาม? a = b ในกรณีนี้การตอบสนองของ Json จะปรากฏในเบราว์เซอร์


2
มันมีประโยชน์มาก นอกจากนี้คุณยังสามารถใช้ UriPathExtensionMapping แทน QueryStringMapping ถ้าคุณต้องการใช้ path.to/item.json
nuzzolilo

32

รหัสนี้ทำให้ json เป็นค่าเริ่มต้นและอนุญาตให้ฉันใช้รูปแบบ XML ได้เช่นกัน xml=trueฉันเพิ่งจะผนวก

GlobalConfiguration.Configuration.Formatters.XmlFormatter.MediaTypeMappings.Add(new QueryStringMapping("xml", "true", "application/xml"));
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));

ขอบคุณทุกคน!


1
นี่เป็นคำตอบที่ยืดหยุ่นที่สุด (และควรเป็นค่าเริ่มต้นที่กำหนดไว้ในปัจจุบัน) เพื่อเพิ่มคำตอบนี้ JSON เป็นค่าเริ่มต้นรวมถึงจากเบราว์เซอร์ หากต้องการดู XML ให้เพิ่มสตริงข้อความค้นหา:? xml = true
raider33

พยายามใช้กลยุทธ์จำนวนหนึ่ง มีการทดสอบอย่างง่าย ๆ สำหรับทั้ง XML และ JSON และสิ่งนี้ใช้ได้นอกกรอบ
pat capozzi

23

อย่าใช้เบราว์เซอร์ของคุณเพื่อทดสอบ API ของคุณ

ให้ลองใช้ไคลเอ็นต์ HTTP ที่ให้คุณระบุคำขอเช่น CURL หรือแม้แต่พู้ทำเล่นแทน

ปัญหาเกี่ยวกับปัญหานี้อยู่ในไคลเอนต์ไม่ใช่ใน API API ของเว็บทำงานอย่างถูกต้องตามคำขอของเบราว์เซอร์


30
ทำไมไม่ใช้เบราว์เซอร์? มันเป็นเครื่องมือที่ชัดเจนสำหรับมัน
Anders Lindén

4
ฉันคิดว่าจุดนี้ถูกต้องและสำคัญ - เราไม่ควรแก้ไขส่วนที่ใช้งานได้ของแอปพลิเคชัน (โครงสร้างพื้นฐาน MVC WebAPI) หากเกิดปัญหาจากไคลเอนต์ กรณีการใช้งานจริงสำหรับ Api จะต้องใช้อย่างเหมาะสม (โดยการจัดหาส่วนหัวที่ถูกต้อง) ซึ่งเป็นความรับผิดชอบของแอปพลิเคชัน ฉันไม่เห็นด้วยกับการยกเลิกเบราว์เซอร์อย่างสมบูรณ์ แต่ - สำหรับการทดสอบมีเครื่องมือมากมายสำหรับเกือบทุกเบราว์เซอร์ (ส่วนขยายที่เหมือนลูกค้าเริ่มต้นด้วย)
Ivaylo Slavov

6
นี่น่าจะเป็นความเห็น
bonh

17

คำตอบข้างต้นส่วนใหญ่มีเหตุผลสมบูรณ์แบบ เนื่องจากคุณเห็นข้อมูลที่ถูกจัดรูปแบบในรูปแบบ XML นั่นหมายถึงมีการใช้ตัวจัดรูปแบบ XML ดังนั้นคุณสามารถดูรูปแบบ JSON ได้โดยการลบ XMLFormatter ออกจากพารามิเตอร์ HttpConfiguration เช่น

public static void Register(HttpConfiguration config)
        {
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );                
            config.Formatters.Remove(config.Formatters.XmlFormatter);                
            config.EnableSystemDiagnosticsTracing();
        }

เนื่องจาก JSON เป็นรูปแบบเริ่มต้น


12

ฉันใช้ตัวกรองการกระทำทั่วโลกเพื่อลบAccept: application/xmlเมื่อUser-Agentส่วนหัวมี "Chrome":

internal class RemoveXmlForGoogleChromeFilter : IActionFilter
{
    public bool AllowMultiple
    {
        get { return false; }
    }

    public async Task<HttpResponseMessage> ExecuteActionFilterAsync(
        HttpActionContext actionContext,
        CancellationToken cancellationToken,
        Func<Task<HttpResponseMessage>> continuation)
    {
        var userAgent = actionContext.Request.Headers.UserAgent.ToString();
        if (userAgent.Contains("Chrome"))
        {
            var acceptHeaders = actionContext.Request.Headers.Accept;
            var header =
                acceptHeaders.SingleOrDefault(
                    x => x.MediaType.Contains("application/xml"));
            acceptHeaders.Remove(header);
        }

        return await continuation();
    }
}

ดูเหมือนว่าจะทำงาน



10

การส่งคืนรูปแบบที่ถูกต้องนั้นทำได้โดยฟอร์แมตเตอร์ชนิดสื่อ ตามที่คนอื่นพูดถึงคุณสามารถทำได้ในWebApiConfigชั้นเรียน:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        ...

        // Configure Web API to return JSON
        config.Formatters.JsonFormatter
        .SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("text/html"));

        ...
    }
}

สำหรับข้อมูลเพิ่มเติมตรวจสอบ:

ในกรณีที่การกระทำของคุณส่งคืน XML (ซึ่งเป็นกรณีโดยค่าเริ่มต้น) และคุณต้องการเพียงวิธีการเฉพาะเพื่อส่งคืน JSON จากนั้นคุณสามารถใช้ActionFilterAttributeและนำไปใช้กับการกระทำที่เฉพาะเจาะจงนั้นได้

คุณลักษณะตัวกรอง:

public class JsonOutputAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        ObjectContent content = actionExecutedContext.Response.Content as ObjectContent;
        var value = content.Value;
        Type targetType = actionExecutedContext.Response.Content.GetType().GetGenericArguments()[0];

        var httpResponseMsg = new HttpResponseMessage
        {
            StatusCode = HttpStatusCode.OK,
            RequestMessage = actionExecutedContext.Request,
            Content = new ObjectContent(targetType, value, new JsonMediaTypeFormatter(), (string)null)
        };

        actionExecutedContext.Response = httpResponseMsg;
        base.OnActionExecuted(actionExecutedContext);
    }
}

นำไปใช้กับการกระทำ:

[JsonOutput]
public IEnumerable<Person> GetPersons()
{
    return _repository.AllPersons(); // the returned output will be in JSON
}

โปรดทราบว่าคุณสามารถละเว้นคำAttributeในการตกแต่งการดำเนินการและใช้เพียงแทน[JsonOutput][JsonOutputAttribute]


7
        config.Formatters.Remove(config.Formatters.XmlFormatter);

3
ในขณะที่รหัสนี้อาจตอบคำถามให้บริบทเพิ่มเติมเกี่ยวกับวิธีการและ / หรือทำไมมันแก้ปัญหาจะปรับปรุงค่าระยะยาวของคำตอบ โปรดอ่านstackoverflow.com/help/how-to-answer
SR

6

ตาม ASP.net WebApi 2 รุ่นล่าสุด

ภายใต้WebApiConfig.csสิ่งนี้จะทำงาน

config.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);
config.Formatters.Add(GlobalConfiguration.Configuration.Formatters.JsonFormatter);

6

มันไม่ชัดเจนสำหรับฉันว่าทำไมความซับซ้อนทั้งหมดนี้ในคำตอบ แน่นอนว่ามีหลายวิธีที่คุณสามารถทำได้ด้วย QueryStrings ส่วนหัวและตัวเลือก ... แต่สิ่งที่ฉันเชื่อว่าเป็นแนวปฏิบัติที่ดีที่สุดนั้นง่าย คุณขอ URL ธรรมดา (เช่น:) http://yourstartup.com/api/carsและในทางกลับกันคุณจะได้รับ JSON คุณได้รับ JSON พร้อมส่วนหัวการตอบสนองที่เหมาะสม:

Content-Type: application/json

ในการค้นหาคำตอบสำหรับคำถามเดียวกันนี้ฉันพบกระทู้นี้และต้องดำเนินการต่อไปเพราะคำตอบที่ยอมรับนี้ใช้ไม่ได้ผล ฉันพบคำตอบที่ฉันรู้สึกว่าง่ายเกินไปที่จะไม่ใช่คำตอบที่ดีที่สุด:

ตั้งค่าฟอร์แมตเตอร์ WebAPI เริ่มต้น

ฉันจะเพิ่มเคล็ดลับของฉันที่นี่เช่นกัน

WebApiConfig.cs

namespace com.yourstartup
{
  using ...;
  using System.Net.Http.Formatting;
  ...
  config.Formatters.Clear(); //because there are defaults of XML..
  config.Formatters.Add(new JsonMediaTypeFormatter());
}

ฉันมีคำถามว่าค่าเริ่มต้น (อย่างน้อยที่ฉันเห็น) มาจากไหน พวกเขาเป็น. NET เป็นค่าเริ่มต้นหรืออาจสร้างที่อื่น (โดยคนอื่นในโครงการของฉัน) ยังหวังว่านี่จะช่วยได้


5

นี่คือวิธีการแก้ปัญหาที่คล้ายกับของ jayson.centenoและคำตอบอื่น ๆ System.Net.Http.Formattingแต่การใช้จากในตัวส่วนขยาย

public static void Register(HttpConfiguration config)
{
    // add support for the 'format' query param
    // cref: http://blogs.msdn.com/b/hongyes/archive/2012/09/02/support-format-in-asp-net-web-api.aspx
    config.Formatters.JsonFormatter.AddQueryStringMapping("$format", "json", "application/json");
    config.Formatters.XmlFormatter.AddQueryStringMapping("$format", "xml", "application/xml");

    // ... additional configuration
 }

โซลูชันนี้มุ่งเน้นไปที่การสนับสนุนรูปแบบ $ สำหรับ OData ในการเผยแพร่ WebApi รุ่นแรก แต่ยังใช้กับการใช้งานที่ไม่ใช่ OData และส่งคืน Content-Type: application/json; charset=utf-8ส่วนหัวในการตอบกลับ

ช่วยให้คุณสามารถกลัด&$format=jsonหรือ&$format=xmlสิ้นสุด uri ของคุณเมื่อทดสอบกับเบราว์เซอร์ มันไม่รบกวนการทำงานที่คาดหวังอื่น ๆ เมื่อใช้ไคลเอ็นต์ที่ไม่ใช่เบราว์เซอร์ซึ่งคุณสามารถตั้งค่าส่วนหัวของคุณเอง


5

คุณสามารถใช้ดังต่อไปนี้:

GlobalConfiguration.Configuration.Formatters.Clear();
GlobalConfiguration.Configuration.Formatters.Add(new JsonMediaTypeFormatter());

หากคุณกำลังสร้างแอป WebAPI เพียงแค่ส่งข้อความ JSON ลองพิจารณาคำตอบนี้
อัลเลน 1

4

เพียงเพิ่มโค้ดสองบรรทัดลงในคลาส WebApiConfigของคุณ

public static class WebApiConfig
{
     public static void Register(HttpConfiguration config)
     {
          //add this two line 
          config.Formatters.Clear();
          config.Formatters.Add(new JsonMediaTypeFormatter());


          ............................
      }
}

3

คุณเพิ่งเปลี่ยนสิ่งApp_Start/WebApiConfig.csนี้:

public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services

        // Web API routes
        config.MapHttpAttributeRoutes();
        //Below formatter is used for returning the Json result.
        var appXmlType = config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml");
        config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);
        //Default route
        config.Routes.MapHttpRoute(
           name: "ApiControllerOnly",
           routeTemplate: "api/{controller}"
       );
    }

การลบฟอร์แมตเตอร์โดยทั่วไปไม่ใช่ความคิดที่ดีคุณกำลังลบฟังก์ชันการทำงาน
naspinski

ที่จริงในกรณีนี้มันใช้งานได้ดีสำหรับฉันและคนอื่น ๆ ก็แนะนำแบบนี้ ฉันได้เรียนรู้จาก หนังสือmyview.rahulnivi.net/building-spa-angular-mvc-5 !
vaheeds

2

จากMSDN การ สร้างแอปพลิเคชันหน้าเดียวด้วย ASP.NET และ AngularJS (ประมาณ 41 นาที)

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // ... possible routing etc.

        // Setup to return json and camelcase it!
        var formatter = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
        formatter.SerializerSettings.ContractResolver =
            new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver();
    }

ควรเป็นปัจจุบันฉันลองแล้วใช้งานได้


2

บางเวลาผ่านไปตั้งแต่คำถามนี้ถูกถาม (และตอบแล้ว) แต่ตัวเลือกอื่นคือแทนที่ส่วนหัว Accept บนเซิร์ฟเวอร์ระหว่างการประมวลผลคำขอโดยใช้ MessageHandler ดังนี้

public class ForceableContentTypeDelegationHandler : DelegatingHandler
{
    protected async override Task<HttpResponseMessage> SendAsync(
                HttpRequestMessage request,
                CancellationToken cancellationToken)
    {
        var someOtherCondition = false;
        var accHeader = request.Headers.GetValues("Accept").FirstOrDefault();
        if (someOtherCondition && accHeader.Contains("application/xml"))
        {
            request.Headers.Remove("Accept");
            request.Headers.Add("Accept", "application/json");
        }
        return await base.SendAsync(request, cancellationToken);
    }
}

ที่ไหน someOtherConditionสามารถเป็นอะไรก็ได้รวมทั้งชนิดของเบราว์เซอร์อื่น ๆ นี้จะเป็นเงื่อนไขสำหรับกรณีที่มีเพียงบางครั้งเราต้องการแทนที่การเจรจาต่อรองเนื้อหาเริ่มต้น มิฉะนั้นตามคำตอบอื่น ๆ คุณเพียงแค่ลบฟอร์แมตเตอร์ที่ไม่จำเป็นออกจากการกำหนดค่า

คุณจะต้องลงทะเบียนแน่นอน คุณสามารถทำสิ่งนี้ได้ทั่วโลก:

  public static void Register(HttpConfiguration config) {
      config.MessageHandlers.Add(new ForceableContentTypeDelegationHandler());
  }

หรือบนเส้นทางตามพื้นฐานของเส้นทาง:

config.Routes.MapHttpRoute(
   name: "SpecialContentRoute",
   routeTemplate: "api/someUrlThatNeedsSpecialTreatment/{id}",
   defaults: new { controller = "SpecialTreatment" id = RouteParameter.Optional },
   constraints: null,
   handler: new ForceableContentTypeDelegationHandler()
);

HttpModuleและตั้งแต่นี้เป็นตัวจัดการข้อความมันจะทำงานได้ทั้งบนคำขอและการตอบสนองที่ปลายของท่อเหมือนต์ ดังนั้นคุณสามารถยอมรับการแทนที่ด้วยส่วนหัวที่กำหนดเองได้อย่างง่ายดาย:

public class ForceableContentTypeDelegationHandler : DelegatingHandler
{
    protected async override Task<HttpResponseMessage> SendAsync(
                HttpRequestMessage request,
                CancellationToken cancellationToken)
    {
        var wasForced = false;
        var someOtherCondition = false;
        var accHeader = request.Headers.GetValues("Accept").FirstOrDefault();
        if (someOtherCondition && accHeader.Contains("application/xml"))
        {
            request.Headers.Remove("Accept");
            request.Headers.Add("Accept", "application/json");
            wasForced = true;
        }

        var response =  await base.SendAsync(request, cancellationToken);
        if (wasForced){
          response.Headers.Add("X-ForcedContent", "We overrode your content prefs, sorry");
        }
        return response;
    }
}

2

นี่เป็นวิธีที่ง่ายที่สุดที่ฉันใช้ในแอปพลิเคชันของฉัน เพิ่มให้ต่ำกว่า 3 บรรทัดของรหัสApp_Start\\WebApiConfig.csในRegisterฟังก์ชั่น

    var formatters = GlobalConfiguration.Configuration.Formatters;

    formatters.Remove(formatters.XmlFormatter);

    config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));

Asp.net web API จะทำให้วัตถุที่ส่งคืนของคุณเป็น JSON โดยอัตโนมัติและapplication/jsonจะถูกเพิ่มเข้าไปในส่วนหัวดังนั้นเบราว์เซอร์หรือผู้รับจะเข้าใจว่าคุณกำลังส่งคืนผลลัพธ์ JSON


1

WebApiConfig เป็นสถานที่ที่คุณสามารถกำหนดค่าว่าคุณต้องการส่งออกเป็น json หรือ xml โดยค่าเริ่มต้นมันคือ xml ในฟังก์ชั่นการลงทะเบียนเราสามารถใช้ฟอร์แมต HttpConfiguration เพื่อจัดรูปแบบเอาต์พุต System.Net.Http.Headers => MediaTypeHeaderValue ("text / html") จำเป็นต้องได้รับเอาต์พุตในรูปแบบ json ป้อนคำอธิบายรูปภาพที่นี่


1

ด้วยการใช้คำตอบของFelipe Leusinเป็นเวลาหลายปีหลังจากที่มีการอัพเดทไลบรารีหลักและ Json.Net เมื่อเร็ว ๆ นี้ฉันก็พบกับSystem.MissingMethodException: สื่อสนับสนุน วิธีการแก้ปัญหาในกรณีของฉันหวังว่าเป็นประโยชน์กับคนอื่น ๆ System.Net.Httpประสบข้อยกเว้นที่ไม่คาดคิดเดียวกันคือการติดตั้ง เห็นได้ชัดว่า NuGet จะลบออกในบางสถานการณ์ หลังจากติดตั้งด้วยตนเองปัญหาได้รับการแก้ไข


-3

ฉันประหลาดใจที่เห็นการตอบกลับจำนวนมากที่ต้องการการเข้ารหัสเพื่อเปลี่ยนเคสการใช้งานครั้งเดียว (GET) ในAPI เดียวแทนที่จะใช้เครื่องมือที่เหมาะสมซึ่งจะต้องติดตั้งครั้งเดียวและสามารถใช้กับAPI ใด ๆ (ของตัวเองหรือของบุคคลที่สาม) และทั้งหมด ใช้กรณี

ดังนั้นคำตอบที่ดีคือ:

  1. หากคุณต้องการขอ json หรือติดตั้งประเภทเนื้อหาอื่นRequestlyหรือเครื่องมือที่คล้ายกันและแก้ไขส่วนหัวยอมรับ
  2. หากคุณต้องการที่จะใช้ POST เกินไปและมีการจัดรูปแบบ JSON อย่าง, XML, ฯลฯ ใช้ส่วนขยายการทดสอบ API ที่เหมาะสมเหมือนบุรุษไปรษณีย์หรือARC

บางคนชอบทำสิ่งต่าง ๆ โดยไม่ต้องเพิ่ม bloat ในรูปแบบของเครื่องมือและไลบรารีพิเศษ
tno2007

ยังคงผิดที่จะทำการเปลี่ยนแปลงกับ API เท่านั้นเนื่องจากมีผู้ใช้เครื่องมือที่ไม่ถูกต้องสำหรับงาน เว็บเบราว์เซอร์ไม่ได้ออกแบบมาเพื่อทดสอบ API ไม่แม้แต่จะดูผลลัพธ์ของ API แต่เพื่อดูเอกสาร มันยิ่งแย่กว่านี้ถ้ามีคนคิดว่าเครื่องมือทดสอบ API เป็นส่วนขยายแทนที่จะเป็นส่วนหนึ่งของชุดเครื่องมือบังคับสำหรับนักพัฒนา API และผมก็จะเพิ่มนักพัฒนาส่วนหน้าด้วยเช่นกันเพราะพวกเขาจำเป็นต้องมีปฏิสัมพันธ์และทดลองกับ API ด้วยเช่นกัน อาจเป็นเพราะการเบราว์เซอร์ที่ไม่มี addins ไม่อนุญาตให้ตั้งค่าส่วนหัวโพสต์ไปยัง API หรือแม้แต่ตรวจสอบส่วนหัวการตอบสนอง
user3285954

ฉันเข้าใจสิ่งที่คุณพูดและคุณไม่ผิด แต่นอกหัวข้อเหตุผลที่คุณได้รับการลงคะแนนคือน้ำเสียงที่คุณตอบคำถาม คุณฟังดูต่อสู้และเข้าหาในฐานะผู้พัฒนาที่คิดว่าพวกเขารู้ทุกอย่างและมันช่างน่ารังเกียจมาก ฉันแน่ใจว่าคุณเป็นนักพัฒนาที่ยอดเยี่ยมตัดสินโดยคำตอบของคุณ แต่คุณต้องเรียนรู้โดยเฉพาะอย่างยิ่งในสภาพแวดล้อมการควบคุมคุณภาพแบบมืออาชีพเช่นนี้เพื่อพูดคุยและโน้มน้าวผู้คนด้วยวิธีที่เป็นมิตรและเป็นมนุษย์มากกว่า บางทีก่อนอื่นให้คำตอบที่พวกเขาต้องการจากนั้นอธิบายวิธีที่ดีกว่าและกระตุ้นให้ทำไมมันถึงดีกว่า
tno2007
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.