हमें FromBody और FromUri को क्यों निर्दिष्ट करना है?


157

ASP.NET वेब API` में विशेषताओं FromBodyऔर FromUriविशेषताओं की आवश्यकता क्यों है ?

विशेषताओं का उपयोग करने और उनका उपयोग न करने के बीच क्या अंतर हैं?


11
जब यह [FromBody] एनोटेशन का उपयोग करने के लिए उपयोगी हो सकता है पर एक संकेत देने के लिए: यह उदाहरण के लिए खराब साख है जैसे कि उपयोगकर्ता नाम / पासवर्ड जैसे स्थैतिक क्रेडेंशियल भेजने के लिए पैरामीटर URL के भीतर एन्कोड किए गए। भले ही एसएसएल-एन्क्रिप्शन यह रोक सकता है कि URL के भीतर कोई तीसरा पक्ष मापदंडों तक पहुंच प्राप्त कर सकता है, यह अभी भी खराब अभ्यास बना हुआ है, क्योंकि ये क्रेडेंशियल्स ब्राउज़र लॉग और समान में संग्रहीत किए जा सकते हैं, जो निश्चित रूप से वांछित नहीं है। इस तरह के एक मामले में, एक [FromBody] एनोटेशन इस्तेमाल कर सकते हैं, HTTP संदेश के मुख्य भाग में एक पैरामीटर के भंडारण के लिए मजबूर करने की, एक उच्च शुरू
क्रिस

जवाबों:


193

जब ASP.NET वेब एपीआई नियंत्रक पर एक विधि कहता है, तो इसे पैरामीटर के लिए मान सेट करना होगा, एक प्रक्रिया जिसे पैरामीटर बाइंडिंग कहा जाता है ।

डिफ़ॉल्ट रूप से, वेब एपीआई मापदंडों को बांधने के लिए निम्नलिखित नियमों का उपयोग करता है:

  • यदि पैरामीटर एक "सरल" प्रकार है , तो वेब API URI से मान प्राप्त करने का प्रयास करता है । सरल प्रकारों में .NET आदिम प्रकार (इंट, बूल, डबल, और इसके बाद के संस्करण), प्लस टाइमस्पैन, डेटाइम, गाइड, दशमलव और स्ट्रिंग शामिल हैं, साथ ही किसी भी प्रकार के कनवर्टर के साथ कोई भी प्रकार जो स्ट्रिंग से परिवर्तित कर सकता है।

  • जटिल प्रकारों के लिए , वेब एपीआई मीडिया-प्रकार के फ़ॉर्मेटर का उपयोग करके, संदेश निकाय से मान को पढ़ने की कोशिश करता है ।

इसलिए, यदि आप उपर्युक्त डिफ़ॉल्ट व्यवहार को ओवरराइड करना चाहते हैं और वेब एपीआई को URI से एक जटिल प्रकार पढ़ने के लिए मजबूर करते हैं, [FromUri]तो पैरामीटर में विशेषता जोड़ें । वेब API को अनुरोध निकाय से एक सरल प्रकार पढ़ने के लिए बाध्य [FromBody]करने के लिए, पैरामीटर में विशेषता जोड़ें ।

इसलिए, आपके प्रश्न का उत्तर देने के लिए, वेब API में [FromBody]और [FromUri]विशेषताओं की आवश्यकता केवल ओवरराइड करने के लिए है, यदि आवश्यक हो, तो ऊपर वर्णित डिफ़ॉल्ट व्यवहार। ध्यान दें कि आप नियंत्रक विधि के लिए दोनों विशेषताओं का उपयोग कर सकते हैं, लेकिन केवल विभिन्न मापदंडों के लिए, जैसा कि यहां दिखाया गया है

नहीं है एक बहुत अधिक जानकारी वेब पर अगर आप गूगल "वेब एपीआई बाध्यकारी पैरामीटर"।


2
@ user3510527: यदि आप डिफ़ॉल्ट व्यवहार का पालन नहीं करते हैं, तो आपको इन विशेषताओं का उपयोग नहीं करना है। यदि आप डिफ़ॉल्ट व्यवहार को बदलना चाहते हैं, तो आपको उनका उपयोग करने की आवश्यकता है।
djikay

1
यदि यह अपना डिफ़ॉल्ट व्यवहार कर रहा है, तो हमें ओवेराइड की आवश्यकता क्यों है और इस विशेषता का उल्लेख करने पर हमें क्या लाभ होगा?
रजनीश

1
@ user3510527 आपको ओवरराइड करने की आवश्यकता नहीं है । आप बस डिफ़ॉल्ट व्यवहार का उपयोग कर सकते हैं। एक उदाहरण जहां कोई व्यक्ति ओवरराइड करना चाहता है, यदि वे अनुरोध के शरीर में एक साधारण पूर्णांक की आपूर्ति करना चाहते हैं, क्योंकि डिफ़ॉल्ट रूप से, यह यूआरआई में इसे खोजने की उम्मीद करेगा। मूल रूप से, आप बस डिफ़ॉल्ट व्यवहार छोड़ सकते हैं यदि आप चाहते हैं या आप ओवरराइड कर सकते हैं, तो यह आपके पास केवल एक विकल्प है। मुझे समझ नहीं आ रहा है कि भ्रम क्या है।
djikay

मैं केवल आंतरिक कार्य प्रक्रिया को जानना चाहता हूं यदि हम प्रपत्र विशेषता का उपयोग करते हैं, तो सीधे यह मान प्राप्त करेगा और किसी भी uri या formbody की जांच नहीं करेगा ...
रजनीश

7
मुझे आश्चर्य है कि अगर कोई एक विशेषता कह सकता है JustGetItजो कई विशेषताओं जैसे [FromBody, FromQuery]आदि को जोड़ने का एक ही उद्देश्य पेश करता है
द मफिन मैन

93

डिफ़ॉल्ट व्यवहार है:

  1. पैरामीटर है आदिम प्रकार ( int, bool, double, ...), वेब एपीआई की कोशिश करता से मूल्य प्राप्त करने के यूआरआई HTTP अनुरोध की।

  2. के लिए जटिल प्रकार (अपनी खुद की वस्तु, उदाहरण के लिए: Person), वेब एपीआई की कोशिश करता से मूल्य को पढ़ने के लिए शरीर HTTP अनुरोध की।

इसलिए, यदि आपके पास:

  • URI में एक आदिम प्रकार, या
  • शरीर में एक जटिल प्रकार

... तो आपको कोई विशेषता नहीं जोड़ना है (न [FromBody]ही [FromUri])।

लेकिन, यदि आपके पास शरीर में एक आदिम प्रकार है , तो आपको जोड़ना होगा[FromBody] अपने WebAP नियंत्रक विधि में अपने आदिम प्रकार के पैरामीटर के सामने । (क्योंकि, डिफ़ॉल्ट रूप से, WebAPI HTTP अनुरोध के URI में आदिम प्रकारों की तलाश कर रहा है।)

या, यदि आपके यूआरआई में एक जटिल प्रकार है , तो आपको जोड़ना होगा[FromUri] । (क्योंकि, डिफ़ॉल्ट रूप से, WebAPI डिफ़ॉल्ट रूप से HTTP अनुरोध के शरीर में जटिल प्रकारों की तलाश में है।)

आदिम प्रकार:

public class UsersController : ApiController
{
    // api/users
    public HttpResponseMessage Post([FromBody]int id)
    {

    }
    // api/users/id
    public HttpResponseMessage Post(int id)
    {

    }       
}

जटिल प्रकार:

public class UsersController : ApiController
{       
    // api/users
    public HttpResponseMessage Post(User user)
    {

    }

    // api/users/user
    public HttpResponseMessage Post([FromUri]User user)
    {

    }       
}

यह तब तक काम करता है जब तक आप अपने HTTP अनुरोध में केवल एक पैरामीटर भेजते हैं। एकाधिक भेजते समय , आपको एक कस्टम मॉडल बनाने की आवश्यकता होती हैजिसमें आपके सभी पैरामीटर इस तरह हों:

public class MyModel
{
    public string MyProperty { get; set; }
    public string MyProperty2 { get; set; }
}

[Route("search")]
[HttpPost]
public async Task<dynamic> Search([FromBody] MyModel model)
{
    // model.MyProperty;
    // model.MyProperty2;
}

ASP.NET वेब API में पैरामीटर बाइंडिंग के लिए Microsoft के दस्तावेज़ से :

जब एक पैरामीटर में [FromBody] होता है, तो वेब एपीआई एक फ़ॉर्मेटर का चयन करने के लिए सामग्री-प्रकार हेडर का उपयोग करता है। इस उदाहरण में, सामग्री प्रकार "एप्लिकेशन / json" है और अनुरोध निकाय एक कच्चा JSON स्ट्रिंग है (JSON ऑब्जेक्ट नहीं)। अधिकतम एक पैरामीटर पर संदेश निकाय से पढ़ने की अनुमति है।

यह काम करना चाहिए:

public HttpResponseMessage Post([FromBody] string name) { ... }

यह काम नहीं करेगा:

// Caution: This won't work!    
public HttpResponseMessage Post([FromBody] int id, [FromBody] string name) { ... }

इस नियम का कारण यह है कि अनुरोध निकाय को गैर-बफर स्ट्रीम में संग्रहीत किया जा सकता है जिसे केवल एक बार पढ़ा जा सकता है।


5
"अधिकतम एक पैरामीटर को संदेश निकाय से पढ़ने की अनुमति है" विशेष रूप से उपयोगी जानकारी थी
रयान

15

बस उपरोक्त उत्तर के अलावा ..

[FromUri] का उपयोग क्वेरिस्ट्रिंग से मापदंडों को पारित करने के बजाय उरी मापदंडों से जटिल प्रकारों को बांधने के लिए भी किया जा सकता है

पूर्व के लिए ..

public class GeoPoint
{
    public double Latitude { get; set; } 
    public double Longitude { get; set; }
}

[RoutePrefix("api/Values")]
public ValuesController : ApiController
{
    [Route("{Latitude}/{Longitude}")]
    public HttpResponseMessage Get([FromUri] GeoPoint location) { ... }
}

जैसे कहा जा सकता है:

http://localhost/api/values/47.678558/-122.130989

12

जब एक पैरामीटर में [FromBody] होता है, तो वेब एपीआई एक फ़ॉर्मेटर का चयन करने के लिए सामग्री-प्रकार हेडर का उपयोग करता है। इस उदाहरण में, सामग्री प्रकार "एप्लिकेशन / json" है और अनुरोध निकाय एक कच्चा JSON स्ट्रिंग है (JSON ऑब्जेक्ट नहीं)।

संदेश बॉडी से अधिकतम एक पैरामीटर को पढ़ने की अनुमति है। तो यह काम नहीं करेगा:

 // Caution: Will not work!    
public HttpResponseMessage Post([FromBody] int id, [FromBody] string name) { ... }

इस नियम का कारण यह है कि अनुरोध निकाय को गैर-बफर स्ट्रीम में संग्रहीत किया जा सकता है जिसे केवल एक बार पढ़ा जा सकता है

कृपया अधिक जानकारी के लिए वेबसाइट पर जाएं : http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.