मुझे ASP.Net वेब API GET में कई पैरामीटर कैसे पास करने चाहिए?


136

मैं .Net MVC4 वेब API का उपयोग कर रहा हूं (उम्मीद है) एक Restful एपीआई को लागू करता है। मुझे सिस्टम में कुछ मापदंडों को पारित करने और कुछ कार्रवाई करने की आवश्यकता है, फिर परिणामों के रूप में वस्तुओं की सूची लौटाएं। विशेष रूप से मैं दो तिथियों में गुजर रहा हूं और उन दोनों के बीच रिकॉर्ड वापस कर रहा हूं। मैं रिकॉर्ड किए गए ट्रैक का भी पता लगा रहा हूं ताकि बाद के कॉल सिस्टम में दोबारा न मिलें।

मैंने कुछ दृष्टिकोणों पर विचार किया है:

  1. Params को एक सिंगल JSON स्ट्रिंग में सीरियल करना और API में अलग करना। http://forums.asp.net/t/1807316.aspx/1

  2. क्वेरी स्ट्रिंग में परमेस पास करें।
    एक आराम करने वाले एपीआई के लिए कई क्वेरी मापदंडों को पारित करने का सबसे अच्छा तरीका क्या है?

  3. मार्ग में परिमों को परिभाषित करना: एपी / कंट्रोलर / डेट 1 / डेट 2

  4. एक POST का उपयोग करना जो स्वाभाविक रूप से मुझे किसी ऑब्जेक्ट को परम के साथ पास करने देता है

  5. वेब API (वर्तमान में) के बाद से ODATA पर शोध करना इसका समर्थन करता है। मैंने इसके साथ बहुत कुछ नहीं किया है, इसलिए मैं इससे बहुत परिचित नहीं हूं।

ऐसा लगता है कि डेटा को खींचे जाने पर उचित REST प्रथाएं इंगित करती हैं, आपको एक GET का उपयोग करना चाहिए। हालांकि, GET भी अशक्त होना चाहिए (कोई साइड-इफेक्ट्स पैदा नहीं करता है), और मुझे आश्चर्य है कि अगर मेरा विशिष्ट कार्यान्वयन उल्लंघन करता है कि चूंकि मैं एपीआई सिस्टम में रिकॉर्ड चिह्नित करता हूं, इसलिए मैं साइड-इफेक्ट्स पैदा कर रहा हूं।

इसने मुझे चर मापदंडों के समर्थन के सवाल पर भी पहुंचा दिया। यदि इनपुट पैरामीटर सूची बदलती है, तो ऐसा होने पर चॉइस 3 के लिए अपने मार्ग को फिर से परिभाषित करना थकाऊ होगा। और क्या हो सकता है अगर मापदंडों को रन-टाइम पर परिभाषित किया गया हो ...

किसी भी मामले में, मेरे विशिष्ट कार्यान्वयन के लिए, कौन सा विकल्प (यदि कोई हो) सबसे अच्छा लगता है?

जवाबों:


10

इस रिकॉर्ड अंकन का क्या मतलब है? यदि यह केवल लॉगिंग उद्देश्यों के लिए उपयोग किया जाता है, तो मैं GET का उपयोग करूंगा और सभी कैशिंग को अक्षम कर दूंगा, क्योंकि आप इस संसाधनों के लिए प्रत्येक क्वेरी को लॉग इन करना चाहते हैं। यदि रिकॉर्ड मार्किंग का एक और उद्देश्य है, तो POST जाने का रास्ता है। उपयोगकर्ता को पता होना चाहिए, कि उसके कार्य प्रणाली को प्रभावित करते हैं और POST विधि एक चेतावनी है।


चिन्हित करने से मेरा मतलब है कि केवल उन ट्रैकिंग को रिकॉर्ड किया जाता है जिन्हें संसाधित किया जाता है और वापस लौटाया जाता है ताकि बाद की कॉल उन्हें दोहराए नहीं। मेरे मामले में मैं सिर्फ एक तालिका में एक सम्मिलित करने के लिए ट्रैक कर रहा हूँ जो संसाधित हैं।
sig606

अभी मैंने इसे मुख्य रूप से POST के रूप में लागू किया है क्योंकि आपने जो कहा है - क्रियाएं होती हैं और उपभोक्ता उनके बारे में जानता है। इसके अलावा विभिन्न डेटा पास करने के संबंध में यह आसान और सबसे लचीला लगता है।
sig606

@ sig606: POST मेरे लिए जाने का तरीका है, लेकिन आपका प्रोटोकॉल सुरक्षित नहीं है। क्या होगा अगर कुछ होता है और रिकॉर्ड क्लाइंट की ओर से पुनर्प्राप्त किए जाते हैं, लेकिन बग के कारण संसाधित नहीं किया जाता है? आप उन्हें किसी भी अधिक वापस नहीं करेंगे और ग्राहक को खोए हुए डेटा के साथ छोड़ दिया जाता है।
लुकलेड

अभी मेरे API को संसाधित होने के बाद केवल रिकॉर्ड मिलते हैं। इसलिए उपभोक्ता एपीआई दो तारीखों को पास करता है। उन दो तारीखों के बीच रिकॉर्ड को संसाधित और चिह्नित किया जाता है। फिर कॉल करने वाले को डेटा वापस कर दिया जाता है। मुझे लगता है कि अगर ग्राहक तक पहुंचने से पहले प्रसंस्करण के दौरान या प्रसंस्करण के बाद कुछ होता है, तो मुझे एक समस्या है।
sig606

141

मुझे लगता है कि सबसे आसान तरीका केवल उपयोग करना है AttributeRouting

यह आपके नियंत्रक के भीतर स्पष्ट है, आप अपनी वैश्विक WebApiConfigफ़ाइल में ऐसा क्यों चाहते हैं ?

उदाहरण:

    [Route("api/YOURCONTROLLER/{paramOne}/{paramTwo}")]
    public string Get(int paramOne, int paramTwo)
    {
        return "The [Route] with multiple params worked";
    }

{}नाम अपने मापदंडों से मेल करने की जरूरत है।

उस तरह से सरल, अब आपके पास एक अलग है GETजो इस उदाहरण में कई पैरामियों को संभालता है।


12
यह भी खूब रही। अधिकांश लोग WebApiConfigफ़ाइल में मार्ग सेट करने की सलाह देते हैं , लेकिन यह वास्तव में अच्छा है।
रहिक

4
दरअसल, हम (ज्यादातर लोग) आपके कॉन्फिगरेशन के लिए सेंट्रलाइज्ड मैनेजमेंट एरिया होने की सलाह देते हैं। वेब एपीआई (Microsoft या अन्यथा) के मामले में, REST के लिए केंद्रीकृत पैटर्न प्रमुख हैं। विशेषता रूटिंग प्यारा है, लेकिन यह एकतरफा अपवादों को बहुत अधिक आकर्षक बनाता है।
डेविड बेट्ज़

3
सहमत, मुझे वास्तव में अपने उत्तर को अपडेट करने की आवश्यकता है। जीईटी के साथ कई मापदंडों को करने का एक बेहतर तरीका है। जब मैं वेबएपीआई में नया था, तब मैंने इसे पोस्ट किया था, अब मैं एट्रीब्यूटरिंग का उपयोग नहीं करता हूं (जब तक कि मैं सिर्फ एक नया नियंत्रक नहीं बनाना चाहता), और क्वैरीस्ट्रिंग के सभी पैरामीटर पारित कर देता हूं, वे स्वचालित रूप से मैप करते हैं। जब मुझे मौका मिले तो अपडेट करना ताकि लोग इस पुराने तरीके का इस्तेमाल न करें
मार्क पाइज़्ज़ाक - ट्रिलोन.आईओ

क्या Routeनामांकित मापदंडों (जैसे क्वेरी पैरामीटर) के लिए सेट करने का एक तरीका है ?
शिम्मी वेइटहैंडलर

1
यदि क्रिया विधि नाम की आवश्यकता है, तो इसे समायोजित करने के लिए संशोधित किया जा सकता है। [मार्ग ("एपीआई / योरकंट्रोलर / गेट / {paramOne} / {paramTwo}")] सार्वजनिक स्ट्रिंग जाओ (int paramOne, int paramTwo) {वापसी "कुछ"; }
डैश

49

WebApiConfigप्रविष्टियों में बस एक नया मार्ग जोड़ें ।

उदाहरण के लिए, कॉल करने के लिए:

public IEnumerable<SampleObject> Get(int pageNumber, int pageSize) { ..

जोड़ें:

config.Routes.MapHttpRoute(
    name: "GetPagedData",
    routeTemplate: "api/{controller}/{pageNumber}/{pageSize}"
);

फिर HTTP कॉल में पैरामीटर जोड़ें:

GET //<service address>/Api/Data/2/10 

10
यह एकमात्र ऐसा उत्तर प्रतीत होता है जो सभी भागों को सूचीबद्ध करता है। काश कि कोई बेहतर ढंग से api/controller?start=date1&end=date2यूआरआई शैली का उपयोग करने का वर्णन करता ।
हॉट लिप्स

@Hot एंड्रयू स्ट्रिंग का जवाब क्वेरी स्ट्रिंग तर्क के साथ अच्छी तरह से काम करता है। अनिवार्य रूप से, आप क्वेरी स्ट्रिंग नामों को श्रेणी के गुणों से बांधते हैं और उन्हें अपनी विधि में पास करते हैं। आपकी विधि [FromUri] विशेषता के साथ चिह्नित एक एकल वर्ग तर्क लेगी और इसके गुणों के रूप में आपके क्वेरी स्ट्रिंग तर्क होंगे।
डेविड पीटरसन 20

उत्तम सामग्री। धन्यवाद!
ह्यूगो नवा कोप्प 16

hi @HotLicks और GrahamWright क्या आपको लगता है कि आप इस प्रश्न का उत्तर दे सकते हैं? धन्यवाद, stackoverflow.com/questions/57565318/…

45

मुझे बस एक RESTfull एपीआई लागू करना था जहां मुझे मापदंडों को पारित करने की आवश्यकता है। मैंने मार्क स्ट्रिंग के पहले उदाहरण "एपीआई / सिंक्रनाइज़ेशन" द्वारा वर्णित उसी शैली में क्वेरी स्ट्रिंग में मापदंडों को पारित करके ऐसा किया था? प्रारंभ = तारीख 1 और अंत = तारीख 2 "

नियंत्रक में मैंने C # में URL विभाजन से एक टिप का उपयोग किया है ?

// uri: /api/courses
public IEnumerable<Course> Get()
{
    NameValueCollection nvc = HttpUtility.ParseQueryString(Request.RequestUri.Query);
    var system = nvc["System"];
    // BL comes here
    return _courses;
}

मेरे मामले में मैं अजाक्स के माध्यम से WebApi की तरह देख रहा था:

$.ajax({
        url: '/api/DbMetaData',
        type: 'GET',
        data: { system : 'My System',
                searchString: '123' },
        dataType: 'json',
        success: function (data) {
                  $.each(data, function (index, v) {
                  alert(index + ': ' + v.name);
                  });
         },
         statusCode: {
                  404: function () {
                       alert('Failed');
                       }
        }
   });

आशा है कि ये आपकी मदद करेगा...


2
मुझे लगता है कि आप WebApi का उपयोग नहीं कर रहे हैं, क्योंकि ParameterBinding आपके quiystring को आपके api पद्धति के मापदंडों को स्वचालित रूप से मैप करेगा ...
साम्राज्य

1
हां, [मार्ग ("api / DbMetaData / {system} / {searchString}") की तरह उपयोग और विशेषता के लिए एक बेहतर तरीका होगा और फिर गेट (स्ट्रिंग सिस्टम, स्ट्रिंग सर्चस्ट्रिंग) में पैरामाटर्स जोड़ें और फिर "के साथ कॉल करें" ... एपी / डीबेटेटाटा / मायसिस्टम / मायसर्चस्ट्रिंगिंग "
निगेल

मैंने अपने C # MVC WebApi में उनके उदाहरण का उपयोग किया और यह ठीक काम किया। उदाहरण के लिए +1
Si8

38

मुझे http://habrahabr.ru/post/164945/ पर एक्सक्लूसिव हल मिला

public class ResourceQuery
{
   public string Param1 { get; set; }
   public int OptionalParam2 { get; set; }
}

public class SampleResourceController : ApiController
{
    public SampleResourceModel Get([FromUri] ResourceQuery query)
    {
        // action
    }
}

5
यहाँ सुराग [फ्रायरी] है
ट्रान्सपोर्टर

2
हालांकि लेख रूसी में है, @tranceporter सही है। "FromUri" url से पैरामीटर प्राप्त करने का एक शानदार तरीका है। एक अन्य लेख जो सहायक हो सकता है: asp.net/web-api/overview/formats-and-model-binding/…
ग्रेग

यह वही है जो मैं काफी समय से कर रहा हूं और यह बहुत अच्छा काम कर रहा है! मैं भी इस समाधान की सिफारिश करेंगे।
डेविड पीटरसन

यदि आप किसी अन्य सहायक विधि (नहीं Get) में कॉल करते हैं , तो क्या आप अभी भी उपयोग कर सकते हैं [FromUri]? मुझे लगता है कि काम करने के लिए नहीं मिल सकता है।
jocull

8

GET या POST का उपयोग करना स्पष्ट रूप से @LukLed द्वारा समझाया गया है । उन तरीकों के बारे में जो आप मापदंडों को पारित कर सकते हैं जो मैं दूसरे दृष्टिकोण के साथ जाने का सुझाव दूंगा (मुझे ODATA के बारे में ज्यादा जानकारी नहीं है )।

1. Params को एक सिंगल JSON स्ट्रिंग में बदलना और इसे API में अलग करना। http://forums.asp.net/t/1807316.aspx/1

यह यूजर फ्रेंडली और एसईओ फ्रेंडली नहीं है

2. क्वेरी स्ट्रिंग में पैरामेस डालें। एक आराम करने वाले एपीआई के लिए कई क्वेरी मापदंडों को पारित करने का सबसे अच्छा तरीका क्या है?

यह सामान्य पसंदीदा तरीका है।

3. मार्ग में परिमों को निर्धारित करना: एपी / कंट्रोलर / डेट 1 / डेट 2

यह निश्चित रूप से एक अच्छा दृष्टिकोण नहीं है। इससे लगता है कि कुछ एक date2का उप संसाधन है date1और ऐसा नहीं है। दोनों date1और date2क्वेरी पैरामीटर कर रहे हैं और एक ही स्तर में आता है।

साधारण मामले में, मैं इस तरह से एक यूआरआई का सुझाव दूंगा,

api/controller?start=date1&end=date2

लेकिन मैं व्यक्तिगत रूप से नीचे दिए गए यूआरआई पैटर्न को पसंद करता हूं लेकिन इस मामले में हमें मापदंडों को मैप करने के लिए कुछ कस्टम कोड लिखना होगा।

api/controller/date1,date2

दरअसल, वे मेरे मूल स्पष्टीकरण थे। मुझे लगता है कि LukLed ने मेरे टैग और URL लिंक को चमकाया।
sig606

जहां तक ​​एसईओ है, इस मामले में यह लागू नहीं होगा। यह कोड "सर्वर-टू-सर्वर" होगा, इसलिए मुझे परवाह नहीं होगी कि बाहरी दुनिया ने कभी इसकी खोज की है। वास्तव में, मुझे यह सुनिश्चित करना होगा कि यादृच्छिक पहुंच से बचने के लिए उचित सुरक्षा कदम उठाए जाएं। मुझे सिस्टम के एक अन्य भाग के लिए JSON सीरियललाइज़ेशन करना पड़ा है (ऐसा लगता है कि बग को obj की बड़ी सूचियों को पोस्ट करने की कोशिश की जा रही है, इसलिए मुझे स्ट्रिंग को अनुक्रमित करना था), इसलिए यह इस मामले में ज्यादा खिंचाव नहीं होगा ।
sig606

1
मुझे आशा है कि आपके पास पहले से ही उत्तर हैं फिर आप सवाल क्यों पूछ रहे हैं?
VJAI

2
इस देर से प्रतिक्रिया के लिए क्षमा करें, निशान। मैंने कुछ समाधानों की कोशिश की थी, लेकिन यह निश्चित नहीं था कि कौन सबसे अच्छा था और उद्योग-मानक दृष्टिकोण के साथ रहने की कोशिश कर रहा था, इसलिए मैंने एसओ में यहां पोस्ट किया।
sig606

1
@Mark कुछ आगे की तरह: stackoverflow.com/questions/9681658/… ?
र्रेडटैट


3
 [Route("api/controller/{one}/{two}")]
    public string Get(int One, int Two)
    {
        return "both params of the root link({one},{two}) and Get function parameters (one, two)  should be same ";
    }

रूट लिंक ({एक}, {दो}) और फ़ंक्शन फ़ंक्शन पैरामीटर (एक, दो) दोनों ही समान होने चाहिए


2

मुझे पता है कि यह वास्तव में पुराना है, लेकिन मैं हाल ही में एक ही चीज चाहता था और यहां जो मैंने पाया ...

    public HttpResponseMessage Get([FromUri] string var, [FromUri] string test) {
        var retStr = new HttpResponseMessage(HttpStatusCode.OK);
        if (var.ToLower() == "getnew" && test.ToLower() == "test") {
            retStr.Content = new StringContent("Found Test", System.Text.Encoding.UTF8, "text/plain");
        } else {
            retStr.Content = new StringContent("Couldn't Find that test", System.Text.Encoding.UTF8, "text/plain");
        }

        return retStr;
    }

तो अब आपके पते पर / URI / ...

http (s): // myURL / API / myController / var = getnew और परीक्षण = परीक्षण

परिणाम: "मिला टेस्ट"


http (s): // myURL / API / myController / var = getnew और परीक्षण = कुछ भी

परिणाम: "वह परीक्षण नहीं पा सका"


मैं व्यक्तिगत रूप से C # में इस शैली को पसंद करता हूं, क्योंकि मैं मूल विधि के हस्ताक्षर को बदल सकता हूं, और राउटिंग कॉन्फिग्स को ट्विक किए बिना वास्तव में जो मैं पूरा करने की कोशिश कर रहा हूं, उसे ओवरलोड कर सकता हूं। आशा है कि यह उन लोगों की मदद करता है जो जीईटी अनुरोध करने के लिए इस (शायद पुरातन) दृष्टिकोण के अभ्यस्त हैं।
रिक रिग्स

1
मुझे एक ईवेंट API बनाना है जो किसी तीसरे पक्ष के कैलेंडर ऐप द्वारा उपभोग किया जाता है, जो इस दृष्टिकोण का उपयोग करता है। मुझे खुशी है कि मुझे यह जवाब मिला!
क्लेरी


0
    public HttpResponseMessage Get(int id,string numb)
    {
        //this will differ according to your entity name
        using (MarketEntities entities = new MarketEntities())
        {
          var ent=  entities.Api_For_Test.FirstOrDefault(e => e.ID == id && e.IDNO.ToString()== numb);
            if (ent != null)
            {
                return Request.CreateResponse(HttpStatusCode.OK, ent);
            }
            else
            {
                return Request.CreateErrorResponse(HttpStatusCode.NotFound, "Applicant with ID " + id.ToString() + " not found in the system");
            }
        }
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.