मैं ASP.NET MVC नियंत्रक एक्शन पैरामीटर के रूप में एक सरणी कैसे स्वीकार करूं?


84

मेरे पास ASP.net MVC कंट्रोलर है जिसे Designsनिम्नलिखित हस्ताक्षर के साथ एक कार्रवाई करनी है :

public ActionResult Multiple(int[] ids)

हालाँकि, जब मैं url का उपयोग करके इस क्रिया को नेविगेट करने का प्रयास करता हूं:

http://localhost:54119/Designs/Multiple?ids=24041,24117

idsपैरामीटर हमेशा रिक्त है। क्या ?ids=क्रिया के लिए URL क्वेरी पैरामीटर को सरणी में बदलने के लिए MVC प्राप्त करने का कोई तरीका है ? मैंने एक एक्शन फिल्टर का उपयोग करने की बात कही है, लेकिन जहाँ तक मैं बता सकता हूँ कि यह केवल उन पोस्ट के लिए काम करेगा जहाँ URL के बजाय अनुरोध डेटा में एरे पास हो जाता है।

जवाबों:


150

डिफ़ॉल्ट मॉडल बाइंडर को इस url की उम्मीद है:

http://localhost:54119/Designs/Multiple?ids=24041&ids=24117

सफलतापूर्वक बाँधने के लिए:

public ActionResult Multiple(int[] ids)
{
    ...
}

और यदि आप चाहते हैं कि यह अल्पविराम से अलग किए गए मूल्यों के साथ काम करे तो आप एक कस्टम मॉडल बाइंडर लिख सकते हैं:

public class IntArrayModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        if (value == null || string.IsNullOrEmpty(value.AttemptedValue))
        {
            return null;
        }

        return value
            .AttemptedValue
            .Split(',')
            .Select(int.Parse)
            .ToArray();
    }
}

और फिर आप इस मॉडल बाइंडर को एक विशेष एक्शन तर्क पर लागू कर सकते हैं:

public ActionResult Multiple([ModelBinder(typeof(IntArrayModelBinder))] int[] ids)
{
    ...
}

या इसे अपने Application_Startमें सभी पूर्णांक सरणी मापदंडों में विश्व स्तर पर लागू करें Global.asax:

ModelBinders.Binders.Add(typeof(int[]), new IntArrayModelBinder());

और अब आपकी नियंत्रक कार्रवाई इस तरह दिख सकती है:

public ActionResult Multiple(int[] ids)
{
    ...
}

2
मुझे याद आ रहा था [FromUri]public ActionResult Multiple([FromUri]int[] ids) {} (GET)
C0d1ngJammer

1
@ डारिन विश्व स्तर पर कस्टम बाइंडिंग को लागू करने का एक तरीका है, लेकिन केवल विशिष्ट कार्रवाई के लिए अनदेखा करें? मुझे ऐसा करने का कोई तरीका नहीं मिला: stackoverflow.com/questions/45379040/…
akd

15

डारिन दिमित्रोव के उत्तर पर विस्तार करने के लिए , आप जिस चीज़ से दूर हो सकते हैं, वह stringआपके URL पैरामीटर में एक साधारण स्वीकार कर रही है और इसे स्वयं एक सरणी में परिवर्तित कर रही है:

public ActionResult Multiple(string ids){
  int[] idsArray = ids.Split(',').Select(int.Parse).ToArray();
  /* ...process results... */
}

यदि आपको ऐसा करते समय एक पार्स त्रुटि मिलती है (क्योंकि किसी ने आपको एक विकृत सरणी दिया है), तो आप अपने अपवाद हैंडलर को 400 Bad Requestडिफ़ॉल्ट के बजाय एक त्रुटि वापस करने के लिए पैदा कर सकते हैं , और अधिक अमित्र 404 Not Foundत्रुटि जो एमवीसी एक समापन बिंदु नहीं मिलने पर वापस आती है।


9

आप इस URL प्रारूप का भी उपयोग कर सकते हैं, और ASP.NET MVC आपके लिए सब कुछ करेगा। लेकिन, URL एन्कोडिंग लागू करना याद रखें।

?param1[0]=3344&param1[1]=2222

6

मुझे नहीं पता कि ग्रॉकी का URL स्ट्रिंग कहां से आ रहा था, लेकिन मुझे कुछ जावास्क्रिप्ट के साथ यही समस्या थी कि मैं अपने नियंत्रक / कार्रवाई को कॉल करूं। यह nullएकाधिक-चयन सूची से (, जो मेरे द्वारा साझा किए जा रहे समाधान के लिए अद्वितीय है) एक URL , 1 या कई "आईडी" का निर्माण करेगा ।

मैंने डारिन के कस्टम मॉडल बाइंडर को कॉपी / पेस्ट किया और मेरे एक्शन / पैरामीटर को सजाया, लेकिन यह काम नहीं किया। मैं अभी भी मिल गया nullमूल्यवान int[] ids। यहां तक ​​कि "सुरक्षित" मामले में जहां मेरे पास वास्तव में कई आईडी थे।

मैं एक ASP.NET MVC अनुकूल पैरामीटर सरणी का उत्पादन करने के लिए जावास्क्रिप्ट को बदलना समाप्त कर दिया

?ids=1&ids=2

मुझे कुछ मूर्खतापूर्ण सामान करना था, हालांकि

ids || []                 #=> if null, get an empty array
[ids || []]               #=> if a single item, wrap it in an array
[].concat.apply([], ...)  #=> in case I wrapped an array, flatten it

तो, पूरा ब्लॉक था

ids = [].concat.apply([], [ids || []])
id_parameter = 'ids=' + ids.join('&ids=')

यह गड़बड़ है, लेकिन यह पहली बार है जब मुझे इस तरह की जावास्क्रिप्ट में हैक करना पड़ा।


1
बस उत्सुक अगर वहाँ है कि पिछले वाक्य में "पहली बार" से पहले एक लापता 'नहीं' है। अन्यथा, आप भाग्यशाली हैं!
DCShannon

1
@DCShannon: हाहा, मैं आपकी बात देख रहा हूँ! लेकिन, यह मेरा पहली बार था। मुझे यकीन नहीं है कि अगर इस तरह की बात सामान्य है या अगर मैं ओवरबोर्ड जा रहा हूं।
एंथनी मस्तरीन

0

.नेट कोर उत्तर

हाल के दिनों में यहां आने वालों के लिए, आप इसे .Net कोर के साथ कर सकते हैं:

http://localhost:54119/Designs/Multiple?ids=24041&ids=24117

तथा:

public ActionResult Multiple([FromQuery] int[] ids)
{
    ...
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.