ASP.NET वेब एपीआई में वैकल्पिक क्वेरी स्ट्रिंग पैरामीटर


212

मुझे निम्नलिखित WebAPI विधि को लागू करने की आवश्यकता है:

/api/books?author=XXX&title=XXX&isbn=XXX&somethingelse=XXX&date=XXX

सभी क्वेरी स्ट्रिंग पैरामीटर शून्य हो सकते हैं। यही है, कॉल करने वाला 0 से सभी 5 मापदंडों तक निर्दिष्ट कर सकता है।

में MVC4 बीटा मैं निम्नलिखित करते थे:

public class BooksController : ApiController
{
    // GET /api/books?author=tolk&title=lord&isbn=91&somethingelse=ABC&date=1970-01-01
    public string GetFindBooks(string author, string title, string isbn, string somethingelse, DateTime? date) 
    {
        // ...
    }
}

MVC4 RC अब इस तरह का व्यवहार नहीं करता है। यदि मैं 5 से कम पैरामीटर निर्दिष्ट करता हूं, तो यह एक 404कहावत के साथ उत्तर देता है :

अनुरोध से मेल खाने वाले नियंत्रक 'पुस्तकें' पर कोई कार्रवाई नहीं हुई।

URL राउटिंग में वैकल्पिक पैरामीटर को निर्दिष्ट किए बिना, इसे व्यवहार में लाने के लिए सही विधि हस्ताक्षर क्या है?


कार्रवाई पर [httpget] रखो।
user960567

2
अगर मैं सभी पैरामीटर सेट करता हूं, तो विधि को बुलाया जाता है; इसके अलावा यह इसके साथ शुरू होता है Getइसलिए यह स्वचालित रूप से HTTP GETविधि के साथ बाध्य है ...
frapontillo

यह कैसे वेब
एप

4
हाँ। मुझे पता है कि यह कैसे काम करता है। मैं इसे विशेष परिस्थिति में काम नहीं कर सकता।
frapontillo

यह भी कैसे संकलन किया? string?मान्य प्रकार नहीं है। आप इसे stringएक अशक्त प्रकार घोषित नहीं कर सकते क्योंकि यह एक संदर्भ प्रकार है।
एकोस्तिकमार्टिन

जवाबों:


307

यह मुद्दा MVC4 की नियमित रिलीज में तय किया गया है। अब आप कर सकते हैं:

public string GetFindBooks(string author="", string title="", string isbn="", string  somethingelse="", DateTime? date= null) 
{
    // ...
}

और सब कुछ बॉक्स से बाहर काम करेगा।


क्या मैं यहां डिफ़ॉल्ट के रूप में नल का उपयोग कर सकता हूं? उदाहरण के लिए: स्ट्रिंग लेखक = अशक्त?
बोरिस ज़िनचेंको

2
हां, nullएक स्थिर अभिव्यक्ति माना जाता है , और इसलिए एक वैध डिफ़ॉल्ट मान है
JDawg

मुझे आश्चर्य है कि क्यों हम के रूप में कहा भी वैकल्पिक पैरामीटर के लिए डिफ़ॉल्ट मान उल्लेख करना होगा यहाँ । C # में किसी भी प्रकार का हमेशा एक डिफ़ॉल्ट मान होता है इसलिए रनिंग-टाइम उस प्रकार के डिफ़ॉल्ट मान को ले सकता है यदि वह URI से इसे प्राप्त नहीं करता है। इसके पीछे तकनीकी कारण क्या है ?. मुझे यकीन है कि यह मॉडल बांधने की मशीन के साथ कुछ करना है।
RBT

@ आरबीटी ताकि मार्ग का मिलान किया जा सके
जेम्स वेस्टगेट

मैं तारीख मापदंडों का उपयोग कर रहा था और अगर मैं बस उन्हें अशक्त करने के लिए सेट काम नहीं कर रहा था। इसलिए मुझे इसे अशक्त और समुच्चय को डिफ़ॉल्ट मान के रूप में सेट करना होगा, और तदनुसार सर्वर साइड सत्यापन का उपयोग करना होगा और त्रुटि संदेशों को वापस करना होगा। इसने काम कर दिया।
एटा एच।

85

एक ही मॉडल के रूप में कई मापदंडों को पारित करना संभव है जैसा कि vijay ने सुझाव दिया है। जब आप FromUri पैरामीटर विशेषता का उपयोग करते हैं तो यह GET के लिए काम करता है। यह WebAPI को क्वेरी पैरामीटर से मॉडल भरने के लिए कहता है।

परिणाम सिर्फ एक पैरामीटर के साथ एक क्लीनर नियंत्रक कार्रवाई है। अधिक जानकारी के लिए देखें: http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api

public class BooksController : ApiController
  {
    // GET /api/books?author=tolk&title=lord&isbn=91&somethingelse=ABC&date=1970-01-01
    public string GetFindBooks([FromUri]BookQuery query)
    {
      // ...
    }
  }

  public class BookQuery
  {
    public string Author { get; set; }
    public string Title { get; set; }
    public string ISBN { get; set; }
    public string SomethingElse { get; set; }
    public DateTime? Date { get; set; }
  }

यह भी कई मापदंडों का समर्थन करता है, जब तक कि गुण संघर्ष नहीं करते हैं।

// GET /api/books?author=tolk&title=lord&isbn=91&somethingelse=ABC&date=1970-01-01
public string GetFindBooks([FromUri]BookQuery query, [FromUri]Paging paging)
{
  // ...
}

public class Paging
{
  public string Sort { get; set; }
  public int Skip { get; set; }
  public int Take { get; set; }
}

अद्यतन :
मानों को सुनिश्चित करने के लिए मॉडल गुणों के लिए संदर्भ प्रकारों या नलिकाओं (पूर्व int?) का उपयोग करना सुनिश्चित करें।


4
हां, लेकिन [FromUri] डेकोरेटर अकेले वैकल्पिक मापदंडों का समर्थन नहीं करता है।
जॉन मेयर

6
@ जॉनमेयर आप सही उपयोग कर रहे हैं [FromUri] सीधे मूल सवाल का जवाब नहीं है। यह मूल रूप से कहता है कि इन मॉडलों को उड़ी के मूल्यों के साथ आबाद करें। वैकल्पिक होने के लिए मॉडल के गुणों को उनके लिए अशक्त या संदर्भ प्रकार की आवश्यकता होगी। अतिरिक्त जानकारी जोड़ी।
एंड्रयू सी।

@AndrewC - क्या आप यह सुनिश्चित करने के लिए विस्तृत कर सकते हैं कि मूल्यों को वैकल्पिक बनाने के लिए आपको nullables का उपयोग करने की आवश्यकता क्यों है? यदि आप मानों को अशक्त नहीं बनाते हैं (उदाहरण के लिए, संपत्ति int Skip) और निर्दिष्ट संपत्ति के लिए कोई क्वेरी परम नहीं है, तो एपीआई नियंत्रक विधि अभी भी सफलतापूर्वक अनुरोध से मेल खाएगी और Skipउस प्रकार के लिए डिफ़ॉल्ट मान बस होगा। या इस मामले में 0
क्लार्क

2
@ क्लार्क - एक अशक्त प्रकार का उपयोग किए बिना आप यह नहीं जान पाएंगे कि क्या उपयोगकर्ता ने कोई मूल्य प्रदान नहीं किया है और उसे अनइंस्टाल्यूटेड टाइप वैल्यू मिला है (0 int) इसलिए आप नियंत्रक क्रिया में अपने डिफ़ॉल्ट को सुरक्षित रूप से लागू कर सकते हैं। यदि आप ऊपर दिए गए उदाहरण से टेक को देखते हैं, तो टेक फॉर 0 प्राप्त होने पर क्या करना चाहिए? क्या उपयोगकर्ता का मतलब 0 रिकॉर्ड का अनुरोध करना था या उन्होंने इसे निर्दिष्ट नहीं किया था और इसलिए आपको सभी रिकॉर्ड लेने चाहिए। आम तौर पर यदि आप एक मूल्य प्रकार (इंट, बूल, आदि) वैकल्पिक होना चाहते हैं तो यह अशक्त होना चाहिए।
एंड्रयू सी

70

नीचे दिए गए सभी मापदंडों के लिए प्रारंभिक डिफ़ॉल्ट मानों का उपयोग करें

public string GetFindBooks(string author="", string title="", string isbn="", string  somethingelse="", DateTime? date= null) 
{
    // ...
}

1
यह सही प्रक्रिया है लेकिन एक बात के लिए: DateTimeअशक्त नहीं है। मैंने पहले से ही DateTime?इसके बजाय उपयोग करने का प्रयास किया है , लेकिन तब एमवीसी दी गई विधि के लिए अनुरोध को मैप नहीं करता है यदि मैं अपने HTTP अनुरोध में केवल कुछ पैरामीटर सेट करता हूं।
frapontillo

आप दिनांक को स्ट्रिंग के रूप में पास कर सकते हैं और DateTime.Parse () फ़ंक्शन का उपयोग करके इसे अपने नियंत्रक फ़ंक्शन के अंदर पार्स कर सकते हैं।
मुहम्मद अमीन

1
@MuhammadAmin, DateTimeएक अशक्त डेटा प्रकार नहीं है। आपका कोड संकलित नहीं होना चाहिए, क्योंकि आप किसी nullप्रकार के मान को निर्दिष्ट करने में सक्षम नहीं होंगे DateTime। शायद, आपको इसे DateTime?डिफ़ॉल्ट रूप से भिन्न मान का उपयोग करना चाहिए या उपयोग करना चाहिए DateTime.Now
इवयलो स्लाव

1
@IvayloSlavov DateTime.Now एक संकलन समय स्थिर नहीं है, इसलिए इसे डिफ़ॉल्ट पैरामीटर के रूप में निर्दिष्ट नहीं किया जा सकता है।
गिरिबी

@ गिरी, तुम वास्तव में सही हो। Datetime.Nowडिफ़ॉल्ट पैरामीटर आरंभीकरण में उपयोग नहीं किया जा सकता है, मैं सही खड़ा हूं।
Ivaylo Slavov

1

यदि आप कई मापदंडों को पारित करना चाहते हैं तो आप कई मापदंडों को पारित करने के बजाय मॉडल बना सकते हैं।

यदि आप किसी भी पैरामीटर को पास नहीं करना चाहते हैं तो आप उसमें भी छोड़ सकते हैं, और आपका कोड साफ और स्वच्छ दिखेगा।


1
यह केवल अनुरोध बॉडी में POST मापदंडों के लिए सही है - url में params अभी भी व्यक्तिगत रूप से संदर्भ के रूप में संदर्भित हो सकते हैं।
नाथन

1

डिफ़ॉल्ट मानों को उन मापदंडों के लिए आपूर्ति नहीं की जा सकती है जिन्हें ' optional' घोषित नहीं किया गया है

 Function GetFindBooks(id As Integer, ByVal pid As Integer, Optional sort As String = "DESC", Optional limit As Integer = 99)

अपने में WebApiConfig

 config.Routes.MapHttpRoute( _
          name:="books", _
          routeTemplate:="api/{controller}/{action}/{id}/{pid}/{sort}/{limit}", _
          defaults:=New With {.id = RouteParameter.Optional, .pid = RouteParameter.Optional, .sort = UrlParameter.Optional, .limit = UrlParameter.Optional} _
      )

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