वेब एपीआई 2: वस्तुओं और उनकी उप-वस्तुओं पर JSON को ऊंटनीकृत संपत्ति के नामों के साथ कैसे लौटाया जाए


104

अपडेट करें

सारे सवालों के जवाब देने के लिए धन्यवाद। मैं एक नई परियोजना पर हूं और ऐसा लग रहा है कि मैं आखिरकार इस की तह तक पहुंच गया हूं: ऐसा लगता है कि निम्नलिखित कोड वास्तव में दोष देने के लिए था:

public static HttpResponseMessage GetHttpSuccessResponse(object response, HttpStatusCode code = HttpStatusCode.OK)
{
    return new HttpResponseMessage()
    {
        StatusCode = code,
        Content = response != null ? new JsonContent(response) : null
    };
}

कहीं और ...

public JsonContent(object obj)
{
    var encoded = JsonConvert.SerializeObject(obj, Newtonsoft.Json.Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore } );
    _value = JObject.Parse(encoded);

    Headers.ContentType = new MediaTypeHeaderValue("application/json");
}

मैं मासूम दिखने वाले JsonContent को यह मानते हुए अनदेखा कर दिया था कि यह वेबएपीआई है लेकिन नहीं।

यह हर जगह उपयोग किया जाता है ... क्या मैं सिर्फ कहने के लिए पहले हो सकता हूं, wtf? या शायद यह होना चाहिए कि "वे ऐसा क्यों कर रहे हैं?"


मूल प्रश्न इस प्रकार है

एक ने सोचा होगा कि यह एक साधारण विन्यास सेटिंग होगी, लेकिन यह मुझे बहुत लंबे समय के लिए हटा दिया गया है।

मैंने विभिन्न समाधानों और उत्तरों को देखा है:

https://gist.github.com/rdingwall/2012642

नवीनतम WebAPI संस्करण पर लागू नहीं होता है ...

निम्नलिखित काम नहीं करता है - संपत्ति के नाम अभी भी पास्कल्ड हैं।

var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;

json.UseDataContractJsonSerializer = true;
json.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;

json.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 

मयंक का जवाब यहां: CamelCase JSON WebAPI उप-ऑब्जेक्ट्स (नेस्टेड ऑब्जेक्ट्स, चाइल्ड ऑब्जेक्ट्स) एक असंतोषजनक लेकिन व्यावहारिक जवाब की तरह लग रहे थे, जब तक मुझे एहसास नहीं हुआ कि इन विशेषताओं को उत्पन्न कोड में जोड़ना होगा क्योंकि हम linqlqql का उपयोग कर रहे हैं ...

किसी भी तरह से यह स्वचालित रूप से करने के लिए? इस 'गंदा' ने मुझे लंबे समय से परेशान किया है।



इसके अलावा एक कारण है कि Linq2SQL आंशिक कक्षाएं क्यों पैदा करता है। इसके अलावा ... Linq2SQL WTF ?!
ऐरन

1
धन्यवाद, लेकिन यह लिंक MVC के लिए है, यह वेब API 2 है जिसका मैं उपयोग कर रहा हूं, और मुझे यकीन नहीं है कि इस तरह की सामग्री-प्रकार सेट करने का कोई तरीका है, और एक स्ट्रिंग लौटाता है, लेकिन यदि ऐसा नहीं है काफी सही समाधान की तरह .. आंशिक वर्गों के बारे में भी टिप के लिए धन्यवाद, लेकिन क्या आंशिक के दूसरे भाग में परिभाषित संपत्ति के लिए एक विशेषता जोड़ना संभव है?
टॉम

इसके अलावा हाँ, linq2sql wtf ... मेरा निर्णय नहीं :)
टॉम

परिणाम समान है, केवल अंतर यह है कि आप कहां इंजेक्ट करते हैं JsonSerializerstackoverflow.com/questions/13274625/…
Aron

जवाबों:


175

यह सब आप एक साथ लाना ...

protected void Application_Start()
{
    HttpConfiguration config = GlobalConfiguration.Configuration;
    config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
    config.Formatters.JsonFormatter.UseDataContractJsonSerializer = false;
}

निश्चित रूप से इसे चालू करने का तरीका, लेकिन मेरी समस्या यह थी कि इस सेटिंग को नजरअंदाज किया जा रहा था (मेरा उत्तर देखें)
टॉम 4

1
@ टॉम erm ... क्या आप जानते हैं कि टॉम क्या json.UseDataContractJsonSerializer = true;करता है? यह WebAPI को Json.Netक्रमांकन के लिए उपयोग नहीं करने के लिए कहता है । > _ <
एरन

हां, अब करता हूं। हालाँकि, एक अतिरिक्त समस्या भी थी। मैंने इसे सत्यापित किया। मेरा जवाब देखिए। इसके अलावा stackoverflow.com/questions/28552567/…
टॉम

1
वास्तव में, करीब निरीक्षण पर यह पता चला है कि मुझे मेरे पहले निष्कर्ष में गलत किया गया था। मेरा अपडेट देखें।
टॉम

28

इसी से मेरा काम बना है:

internal static class ViewHelpers
{
    public static JsonSerializerSettings CamelCase
    {
        get
        {
            return new JsonSerializerSettings {
                ContractResolver = new CamelCasePropertyNamesContractResolver()
            };
        }
    }
}

और तब:

[HttpGet]
[Route("api/campaign/list")]
public IHttpActionResult ListExistingCampaigns()
{
    var domainResults = _campaignService.ListExistingCampaigns();
    return Json(domainResults, ViewHelpers.CamelCase);
}

वर्ग CamelCasePropertyNamesContractResolverसे आता है Newtonsoft.Json.dllमें Json.NET पुस्तकालय।


3
यह दृष्टिकोण बहुत उपयोगी है, जब कोई चाहता है कि केवल कुछ एपीआई के लिए ऊंटनी का काम हो, न कि अनुप्रयोग के सभी एपीआई के लिए। (वाई)
१४:०१ पर droidbot

15

परिणाम यह निकला

return Json(result);

अपराधी था, जिसने क्रमांकन प्रक्रिया के कारण ऊंट की स्थापना की अनदेखी की। और वह

return Request.CreateResponse(HttpStatusCode.OK, result, Request.GetConfiguration());

मैं जो तलाश कर रहा था वह था।

भी

json.UseDataContractJsonSerializer = true;

काम करता है में एक स्पैनर डाल रहा था और मैं नहीं देख रहा था Droid नहीं निकला।


यह वास्तव में गलत उत्तर है। प्रश्न में मेरा अपडेट देखें।
टॉम

मुझे वास्तव में यह मामला लगा। लौटते समय Json(result), मैं पास्कलकेस में सब कुछ देख रहा था, लेकिन जब मैं लौटा Content(StatusCode, result)तो उम्मीद के मुताबिक काम किया।
DeeKayy90

12

उपरोक्त सभी उत्तर मेरे लिए ओविन होस्टिंग और निनजेक्ट के साथ काम नहीं करते थे। यहाँ मेरे लिए क्या काम किया गया है:

public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        // Get the ninject kernel from our IoC.
        var kernel = IoC.GetKernel();

        var config = new HttpConfiguration();

        // More config settings and OWIN middleware goes here.

        // Configure camel case json results.
        ConfigureCamelCase(config);

        // Use ninject middleware.
        app.UseNinjectMiddleware(() => kernel);

        // Use ninject web api.
        app.UseNinjectWebApi(config);
    }

    /// <summary>
    /// Configure all JSON responses to have camel case property names.
    /// </summary>
    private void ConfigureCamelCase(HttpConfiguration config)
    {
        var jsonFormatter = config.Formatters.JsonFormatter;
        // This next line is not required for it to work, but here for completeness - ignore data contracts.
        jsonFormatter.UseDataContractJsonSerializer = false;
        var settings = jsonFormatter.SerializerSettings;
#if DEBUG
        // Pretty json for developers.
        settings.Formatting = Formatting.Indented;
#else
        settings.Formatting = Formatting.None;
#endif
        settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
    }
}

मुख्य अंतर यह है: GlobalConfiguration.Configuration के बजाय नया HttpConfiguration ()।


OWIN के माध्यम से स्वयं की मेजबानी के लिए, यह एकदम सही है। धन्यवाद!
जूलियन मेलविले

3
यदि आप ओवेन का उपयोग कर रहे हैं, तो यह समाधान पूरी तरह से काम करता है, लेकिन केवल तब ही जब आप अपने सभी बालों को फाड़ देते हैं!
अलास्टेयर

10

WebApiConfig का कोड:

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

            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

            //This line sets json serializer's ContractResolver to CamelCasePropertyNamesContractResolver, 
            //  so API will return json using camel case
            config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();

        }
    }


सुनिश्चित करें कि आपका एपीआई एक्शन विधि निम्नलिखित तरीके से डेटा लौटाता है और आपने Json.Net/Newtonsoft.Json इंस्टॉल का नवीनतम संस्करण स्थापित किया है:

    [HttpGet]
    public HttpResponseMessage List()
    {
        try
        {
            var result = /*write code to fetch your result*/;
            return Request.CreateResponse(HttpStatusCode.OK, cruises);
        }
        catch (Exception ex)
        {
            return Request.CreateResponse(HttpStatusCode.InternalServerError, ex.Message);
        }
    }

4

आपके ओविन स्टार्टअप में यह लाइन जोड़ें ...

 public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var webApiConfiguration = ConfigureWebApi();            
        app.UseWebApi(webApiConfiguration);
    }

    private HttpConfiguration ConfigureWebApi()
    {
        var config = new HttpConfiguration();

        // ADD THIS LINE HERE AND DONE
        config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 

        config.MapHttpAttributeRoutes();
        return config;
    }
}

3

यहाँ एक अस्पष्ट है, जब मार्ग विशेषता GET url से मेल नहीं खाती है, लेकिन GET url विधि के नाम से मेल खाती है, jsonserializer ऊंट मामले के निर्देश को अनदेखा किया जाएगा उदा।

http: // वेबसाइट / API / भू / geodata

//uppercase fail cakes
[HttpGet]
[Route("countries")]
public async Task<GeoData> GeoData()
{
    return await geoService.GetGeoData();
}

//lowercase nomnomnom cakes
[HttpGet]
[Route("geodata")]
public async Task<GeoData> GeoData()
{
    return await geoService.GetGeoData();
}

2

मैंने इसे निम्नलिखित तरीकों से हल किया है।

[AllowAnonymous]
[HttpGet()]
public HttpResponseMessage GetAllItems(int moduleId)
{
    HttpConfiguration config = new HttpConfiguration();
            config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            config.Formatters.JsonFormatter.UseDataContractJsonSerializer = false;

            try
            {
                List<ItemInfo> itemList = GetItemsFromDatabase(moduleId);
                return Request.CreateResponse(HttpStatusCode.OK, itemList, config);
            }
            catch (System.Exception ex)
            {
                return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex.Message);
            }
}

0

मैं ब्रीज़ के साथ वेबएपी का उपयोग कर रहा हूं और मैंने एक ही मुद्दे को चलाया जब एक गैर-हवा कार्रवाई को एक हवा नियंत्रक में निष्पादित करने की कोशिश की गई। मैंने Apprach Request.GetConfiguration का उपयोग करने की कोशिश की, लेकिन वही परिणाम। इसलिए, जब मैं Request.GetConfiguration द्वारा लौटाए गए ऑब्जेक्ट का उपयोग करता हूं, तो मुझे पता चलता है कि अनुरोध द्वारा उपयोग किए जाने वाले धारावाहिक का उपयोग यह जादू करने के लिए एक विंड-सर्वर का उपयोग है। किसी भी तरह से, मैंने अपना मुद्दा एक अलग HttpConfiguration बनाने का हल किया:

public static HttpConfiguration BreezeControllerCamelCase
        {
            get
            {
                var config = new HttpConfiguration();
                var jsonSerializerSettings = config.Formatters.JsonFormatter.SerializerSettings;
                jsonSerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
                jsonSerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                config.Formatters.JsonFormatter.UseDataContractJsonSerializer = false;

                return config;
            }
        }

और यह अनुरोध पर पैरामीटर के रूप में पारित कर रहा है।

return this.Request.CreateResponse(HttpStatusCode.OK, result, WebApiHelper.BreezeControllerCamelCase);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.