ASP.NET कोर के साथ क्वेरी से मूल्यों को कैसे पढ़ें?


135

मैं ASP.NET Core MVC का उपयोग करके एक RESTful API का निर्माण कर रहा हूं और मैं एक संग्रह को रिटर्न करने वाले संसाधन पर फ़िल्टरिंग और पेजिंग निर्दिष्ट करने के लिए querystring मापदंडों का उपयोग करना चाहता हूं।

उस स्थिति में, मुझे फ़िल्टर करने के लिए क्वेरिस्ट्रिंग में दिए गए मानों को पढ़ना होगा और वापस लौटने के लिए परिणामों का चयन करना होगा।

मुझे पहले ही पता चला है कि कंट्रोलर Getएक्शन के अंदर HttpContext.Request.Queryरिटर्न रिटर्न एक है IQueryCollection

समस्या यह है कि मुझे नहीं पता कि इसका उपयोग मूल्यों को पुनः प्राप्त करने के लिए कैसे किया जाता है। सच में, मैंने सोचा कि ऐसा करने का तरीका उदाहरण के लिए है

string page = HttpContext.Request.Query["page"]

समस्या यह है कि HttpContext.Request.Query["page"]एक स्ट्रिंग वापस नहीं करता है, लेकिन ए StringValues

वैसे भी, कोई IQueryCollectionवास्तव में क्वेरिस्ट्रिंग मूल्यों को पढ़ने के लिए कैसे उपयोग करता है ?


1
मैंने उसी के लिए एक पोस्ट लिखी है जिसे आप यहाँ पा सकते हैं: neelbhatt40.wordpress.com/2017/07/06/…
नील

जवाबों:


134

आप [FromQuery]एक विशेष मॉडल को क्वेरिस्ट्रिंग से बांधने के लिए उपयोग कर सकते हैं :

https://docs.microsoft.com/en-us/aspnet/core/mvc/models/model-binding

जैसे

[HttpGet()]
public IActionResult Get([FromQuery(Name = "page")] string page)
{...}

5
मुझे लगता है कि [FromQuery]अट्रिब को भी हटाया जा सकता है क्योंकि .net बाइंडिंग डिफ़ॉल्ट रूप से सभी फॉर्म इनपुट और यूआरएल क्वेरिस्ट्रिंग परम की जांच करेगा, सिवाय इसके कि आपके पास इसके स्रोत को सीमित करने का कोई कारण है।
S.Serpooshan

12
(नाम = "पृष्ठ") अनावश्यक है - यह वैरिएबल को बाँध देगा यदि उसी का नाम दिया गया हो
a3uge

यह महत्वपूर्ण है अगर क्वेरिस्ट्रिंग पैरामीटर नाम संरचित है। उदाहरण के लिए 'object.propname'
जोस कैपिस्ट्रानो

96

IQueryCollectionयदि कोई एकल pageपैरामीटर निर्दिष्ट किया गया है, तो आप ToString विधि का उपयोग कर सकते हैं।

string page = HttpContext.Request.Query["page"].ToString();

यदि कई मान हैं, ?page=1&page=2तो ToString कॉल का परिणाम होगा1,2

लेकिन जैसा कि @ माइक-जी ने उनके उत्तर में सुझाव दिया था कि आप मॉडल बाइंडिंग का बेहतर उपयोग करेंगे और सीधे HttpContext.Request.Queryऑब्जेक्ट तक नहीं पहुंचेंगे ।


6
ToString आवश्यक नहीं है। संकलक इसे अनुमानित रूप से डालेगा, यदि आप एक स्ट्रिंग को क्वेरी-मान असाइन करते हैं ..
स्टीफन स्टीगर

26

ASP.NET कोर स्वचालित रूप से बाध्य होगा form values, route valuesऔर query stringsनाम से। इसका मतलब है आप बस यह कर सकते हैं:

[HttpGet()]
public IActionResult Get(int page)
{ ... }

MVC एक्शन पैरामीटर्स पर डेटा रिक्वेस्ट को नाम से बांधने की कोशिश करेगा ... नीचे डेटा स्रोतों की एक सूची है, जिसमें मॉडल उनके साथ दिखता है

  1. Form values: ये फॉर्म मूल्य हैं जो POST विधि का उपयोग करके HTTP अनुरोध में जाते हैं। (jQuery पोस्ट अनुरोध सहित)।

  2. Route values: रूटिंग द्वारा प्रदान किए गए मार्ग मूल्यों का सेट

  3. Query strings: URI का क्वेरी स्ट्रिंग भाग।

स्रोत: मॉडल बाइंडिंग कैसे काम करती है


FYI करें, आप स्वचालित और स्पष्ट दृष्टिकोण को भी जोड़ सकते हैं:

[HttpGet()]
public IActionResult Get(int page
     , [FromQuery(Name = "page-size")] int pageSize)
{ ... }

20

आप बस इस तरह एक वस्तु बना सकते हैं:

public class SomeQuery
{
    public string SomeParameter { get; set; }
    public int? SomeParameter2 { get; set; }
}

और फिर कंट्रोलर में कुछ इस तरह से बनाएं:

[HttpGet]
public IActionResult FindSomething([FromQuery] SomeQuery query)
{
    // Your implementation goes here..
}

इससे भी बेहतर, आप एपीआई मॉडल बना सकते हैं:

[HttpGet]
public IActionResult GetSomething([FromRoute] int someId, [FromQuery] SomeQuery query)

सेवा:

[HttpGet]
public IActionResult GetSomething(ApiModel model)

public class ApiModel
{
    [FromRoute]
    public int SomeId { get; set; }
    [FromQuery]
    public string SomeParameter { get; set; }
    [FromQuery]
    public int? SomeParameter2 { get; set; }
}

ऐसा कौन सा URL है जो इस पर लागू होगा? मैं इसके लिए नया हूं इसलिए मैं URL में "बैकवर्ड इंजीनियर" नहीं कर सकता। क्या यह example.com/somequery/… जैसा कुछ होगा ?
ईसाई

1
@Christian अगर आप किसी भी सम्मेलन में परिवर्तन नहीं करते, यह example.com/[controller]/[action]/{someid:int}?someparameter=1&someparameter2=2 होगा
LxL

19

यहाँ एक कोड नमूना है जिसका मैंने उपयोग किया है (.NET कोर दृश्य के साथ):

@{
    Microsoft.Extensions.Primitives.StringValues queryVal;

    if (Context.Request.Query.TryGetValue("yourKey", out queryVal) &&
        queryVal.FirstOrDefault() == "yourValue")
    {
    }
}

2
पूर्ण ऑब्जेक्ट नाम (या कथन का सही उपयोग) सहित के लिए अपवोट करें। मुझे पागल कर देता है जब लोग बस ऑब्जेक्टनाम को पूरी तरह से योग्य नहीं या कम से कम उपयोग करने वाले बयान के साथ डालते हैं। धन्यवाद।
ग्रानैडकोडर

11

StringValuesतार की एक सरणी है । आप एक सूचकांक प्रदान करके अपने स्ट्रिंग मान प्राप्त कर सकते हैं, जैसे HttpContext.Request.Query["page"][0]


1
धन्यवाद; यह एकमात्र प्रतिक्रिया थी जिसने वास्तव में प्रश्न का उत्तर दिया। (मेरे मामले में, मैं बाध्यकारी का उपयोग नहीं कर सकता क्योंकि मेरे पास एक और अधिक जटिल तर्क है जैसे "पहले क्वेरी स्ट्रिंग आज़माएं, अगर वह गायब है तो सत्र और इसी तरह की कोशिश करें"।)
मार्सेल पॉपस्क्यू

7

IQueryCollectionइस TryGetValue()पर एक दिया गया है जो दिए गए कुंजी के साथ एक मान लौटाता है। इसलिए, यदि आपके पास कोई क्वेरी पैरामीटर कहा जाता है someInt, तो आप इसका उपयोग कर सकते हैं:

var queryString = httpContext.Request.Query;
StringValues someInt;
queryString.TryGetValue("someInt", out someInt);
var daRealInt = int.Parse(someInt);

ध्यान दें कि जब तक आपके पास एक ही नाम के कई पैरामीटर नहीं होते हैं, तब तक StringValuesकोई समस्या नहीं होती है।


इस उत्तर को जोड़ने के लिए, यदि आप StringValues.ToString () कहते हैं, तो आप इसे सीधे एक स्ट्रिंग में डाल सकते हैं यदि आपको इसकी आवश्यकता है।
eltiare

भविष्य के पाठक: पूरी तरह से योग्य नाम "Microsoft.AspNetCore.Http.IQueryCollection queryString = this.Renseest .Query;" मेरा "असेंबली Microsoft.AspNetCore.Http.Features, संस्करण = 3.1.0.0," और "Microsoft.Extensions.Primitives.StringValues" में था (मेरा "असेंबली Microsoft.Extensions.Primatics, Version = 3.1.2.0," में था)
ग्रेनडाकोडर

3

यदि आप हमारे विचार में क्वेरिस्ट्रिंग का उपयोग करना चाहते हैं तो .net कोर

@Context.Request.Query["yourKey"]

अगर हम उस स्थान पर हैं जहाँ @ कॉन्टेक्ट उपलब्ध नहीं है, तो हम इसे पसंद कर सकते हैं

@inject Microsoft.AspNetCore.Http.IHttpContextAccessor HttpContextAccessor
@if (HttpContextAccessor.HttpContext.Request.Query.Keys.Contains("yourKey"))
{
      <text>do something </text>
}

कुकीज़ के लिए भी

HttpContextAccessor.HttpContext.Request.Cookies["DeniedActions"]

2
उस कोड की कोई आवश्यकता नहीं है। बस @ Context.Request.Query ["yourKey"] का उपयोग करें
Shadi Namrouti

हां @ShadiNamrouti आप देखने में सही हैं, जहां \ _Context उपलब्ध है, हम इसे @ @ Context.Request.Query ["yourKey" की तरह उपयोग कर सकते हैं, लेकिन यदि हम कंट्रोलर में हैं तो हमें HttpContextAccessor.HttpContext को इंजेक्ट करना होगा।
एम। एल अल-सईद

2

मेरे पास इस समस्या का बेहतर समाधान है,

  • अनुरोध अमूर्त वर्ग नियंत्रक सदस्य का एक सदस्य है
  • GetSearchParams () bellow helper class में बनाई गई एक एक्सटेंशन विधि है।

var searchparams = await Request.GetSearchParams();

मैंने कुछ विस्तार विधियों के साथ एक स्थिर वर्ग बनाया है

public static class HttpRequestExtension
{
  public static async Task<SearchParams> GetSearchParams(this HttpRequest request)
        {
            var parameters = await request.TupledParameters();

            try
            {
                for (var i = 0; i < parameters.Count; i++)
                {
                    if (parameters[i].Item1 == "_count" && parameters[i].Item2 == "0")
                    {
                        parameters[i] = new Tuple<string, string>("_summary", "count");
                    }
                }
                var searchCommand = SearchParams.FromUriParamList(parameters);
                return searchCommand;
            }
            catch (FormatException formatException)
            {
                throw new FhirException(formatException.Message, OperationOutcome.IssueType.Invalid, OperationOutcome.IssueSeverity.Fatal, HttpStatusCode.BadRequest);
            }
        }



public static async Task<List<Tuple<string, string>>> TupledParameters(this HttpRequest request)
{
        var list = new List<Tuple<string, string>>();


        var query = request.Query;
        foreach (var pair in query)
        {
            list.Add(new Tuple<string, string>(pair.Key, pair.Value));
        }

        if (!request.HasFormContentType)
        {
            return list;
        }
        var getContent = await request.ReadFormAsync();

        if (getContent == null)
        {
            return list;
        }
        foreach (var key in getContent.Keys)
        {
            if (!getContent.TryGetValue(key, out StringValues values))
            {
                continue;
            }
            foreach (var value in values)
            {
                list.Add(new Tuple<string, string>(key, value));
            }
        }
        return list;
    }
}

इस तरह आप अपने सभी खोज मापदंडों तक आसानी से पहुँच सकते हैं। मुझे आशा है कि इससे कई डेवलपर्स को मदद मिलेगी :)


क्या मुझे कुछ याद आ रहा है - जहाँ फ़िर एक्ससेप्शन को परिभाषित किया गया है, टास्क <SearchParams> को किस नाम से जाना जाता है?
डग थॉम्पसन - डौगीफ्रेश

1

कुछ टिप्पणियों में इसका उल्लेख है, लेकिन एस्प नेट कोर यह सब आपके लिए काम करता है।

यदि आपके पास एक क्वेरी स्ट्रिंग है जो नाम से मेल खाता है तो यह नियंत्रक में उपलब्ध होगा।

https: // myapi / कुछ-endpoint / 123 someQueryString = YayThisWorks

[HttpPost]
[Route("some-endpoint/{someValue}")]
public IActionResult SomeEndpointMethod(int someValue, string someQueryString)
    {
        Debug.WriteLine(someValue);
        Debug.WriteLine(someQueryString);
        return Ok();
    }

ouputs:

123

YayThisWorks

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