[.net] वेबएपीआई एकाधिक पुट / पोस्ट पैरामीटर


Answers

मूल रूप से WebAPI एकाधिक POST पैरामीटर के बाध्यकारी का समर्थन नहीं करता है। कॉलिन बताते हैं कि मेरे http://www.west-wind.com/weblog/posts/2012/May/08/Passing-multiple-POST-parameters-to-Web-API-Controller-Methods में उल्लिखित कई सीमाएं हैं जिनके संदर्भ में वे संदर्भित हैं।

एक कस्टम पैरामीटर बांधने की मशीन बनाकर एक कामकाज है। ऐसा करने के लिए कोड बदसूरत और दृढ़ है, लेकिन मैंने अपने ब्लॉग पर एक विस्तृत स्पष्टीकरण के साथ कोड पोस्ट किया है, यहां एक परियोजना में प्लग करने के लिए तैयार है:

एएसपी.नेट वेब एपीआई को कई सरल पोस्ट वैल्यू पास करना

Question

मैं एक वेबएपीआई नियंत्रक पर एकाधिक पैरामीटर पोस्ट करने की कोशिश कर रहा हूं। एक param यूआरएल से है, और दूसरा शरीर से है। यहां यूआरएल है: /offers/40D5E19D-0CD5-4FBD-92F8-43FDBB475333/prices/

मेरा नियंत्रक कोड यहां है:

public HttpResponseMessage Put(Guid offerId, OfferPriceParameters offerPriceParameters)
{
    //What!?
    var ser = new DataContractJsonSerializer(typeof(OfferPriceParameters));
    HttpContext.Current.Request.InputStream.Position = 0;
    var what = ser.ReadObject(HttpContext.Current.Request.InputStream);

    return new HttpResponseMessage(HttpStatusCode.Created);
}

शरीर की सामग्री जेएसओएन में है:

{
    "Associations":
    {
        "list": [
        {
            "FromEntityId":"276774bb-9bd9-4bbd-a7e7-6ed3d69f196f",
            "ToEntityId":"ed0d2616-f707-446b-9e40-b77b94fb7d2b",
            "Types":
            {
                "list":[
                {
                    "BillingCommitment":5,
                    "BillingCycle":5,
                    "Prices":
                    {
                        "list":[
                        {
                            "CurrencyId":"274d24c9-7d0b-40ea-a936-e800d74ead53",
                            "RecurringFee":4,
                            "SetupFee":5
                        }]
                    }
                }]
            }
        }]
    }
}

कोई विचार क्यों डिफ़ॉल्ट बाध्यकारी मेरे नियंत्रक के offerPriceParameters तर्क से जुड़ने में सक्षम नहीं है? यह हमेशा शून्य करने के लिए सेट है। लेकिन मैं DataContractJsonSerializer का उपयोग कर शरीर से डेटा पुनर्प्राप्त करने में सक्षम हूं।

मैं तर्क के FromBody विशेषता का उपयोग करने का भी प्रयास करता FromBody लेकिन यह या तो काम नहीं करता है।




यदि आप मॉडलबाइंडिंग तरीके से नहीं जाना चाहते हैं, तो आप यह करने के लिए डीटीओ का उपयोग कर सकते हैं। उदाहरण के लिए, डेटालेयर में एक पोस्ट एक्शन बनाएं जो जटिल प्रकार स्वीकार करता है और बिजनेसलेयर से डेटा भेजता है। आप UI-> API कॉल के मामले में ऐसा कर सकते हैं।

नमूना डीटीओ यहाँ हैं। एक छात्र को एक शिक्षक को सौंपें और छात्र को कई कागजात / विषय सौंपें।

public class StudentCurriculumDTO
 {
     public StudentTeacherMapping StudentTeacherMapping { get; set; }
     public List<Paper> Paper { get; set; }
 }    
public class StudentTeacherMapping
 {
     public Guid StudentID { get; set; }
     public Guid TeacherId { get; set; }
 }

public class Paper
 {
     public Guid PaperID { get; set; }
     public string Status { get; set; }
 }

फिर डेटालेयर में कार्रवाई इस प्रकार बनाई जा सकती है:

[HttpPost]
[ActionName("MyActionName")]
public async Task<IHttpActionResult> InternalName(StudentCurriculumDTO studentData)
  {
     //Do whatever.... insert the data if nothing else!
  }

इसे बिजनेसलेयर से कॉल करने के लिए:

using (HttpResponseMessage response = await client.PostAsJsonAsync("myendpoint_MyActionName", dataof_StudentCurriculumDTO)
  {
     //Do whatever.... get response if nothing else!
  }

अब यह तब भी काम करेगा यदि मैं एक साथ कई छात्र डेटा भेजना चाहता हूं। नीचे की तरह MyAction संशोधित करें। [FromBody] लिखने की कोई ज़रूरत नहीं है, WebAPI2 डिफ़ॉल्ट रूप से जटिल प्रकार [FromBody] लेता है।

public async Task<IHttpActionResult> InternalName(List<StudentCurriculumDTO> studentData)

और फिर इसे कॉल करते समय, डेटा की एक List<StudentCurriculumDTO> पास करें।

using (HttpResponseMessage response = await client.PostAsJsonAsync("myendpoint_MyActionName", List<dataof_StudentCurriculumDTO>)



अच्छा सवाल और टिप्पणियां - यहां उत्तरों से बहुत कुछ सीखा :)

एक अतिरिक्त उदाहरण के रूप में, ध्यान दें कि आप शरीर और मार्गों को भी मिश्रण कर सकते हैं

[RoutePrefix("api/test")]
public class MyProtectedController 
{
    [Authorize]
    [Route("id/{id}")]
    public IEnumerable<object> Post(String id, [FromBody] JObject data)
    {
        /*
          id                                      = "123"
          data.GetValue("username").ToString()    = "user1"
          data.GetValue("password").ToString()    = "pass1"
         */
    }
}

इस तरह कॉलिंग:

POST /api/test/id/123 HTTP/1.1
Host: localhost
Accept: application/json
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer x.y.z
Cache-Control: no-cache

username=user1&password=pass1


enter code here



यदि विशेषता रूटिंग का उपयोग किया जा रहा है, तो आप [FromUri] और [FromBody] विशेषताओं का उपयोग कर सकते हैं।

उदाहरण:

[HttpPost()]
[Route("api/products/{id:int}")]
public HttpResponseMessage AddProduct([FromUri()] int id,  [FromBody()] Product product)
{
  // Add product
}



आप https://github.com/keith5000/MultiPostParameterBinding बाइंडिंग से मल्टीपोस्ट पैरामीटर बाइंडिंग क्लास का उपयोग करके एकाधिक POST पैरामीटर की अनुमति दे सकते हैं

इसके प्रयेाग के लिए:

1) Source फ़ोल्डर में कोड डाउनलोड करें और इसे अपने वेब एपीआई प्रोजेक्ट या समाधान में किसी अन्य प्रोजेक्ट में जोड़ें।

2) कई POST पैरामीटर का समर्थन करने के लिए आवश्यक क्रिया विधियों पर विशेषता [मल्टीपोस्ट पैरामीटर] का उपयोग करें।

[MultiPostParameters]
public string DoSomething(CustomType param1, CustomType param2, string param3) { ... }

3) GlobalConfiguration पर कॉल करने से पहले कहीं भी इस लाइन को Global.asax.cs में एप्लिकेशन_स्टार्ट विधि में जोड़ें। कॉन्फ़िगर (WebApiConfig.Register) :

GlobalConfiguration.Configuration.ParameterBindingRules.Insert(0, MultiPostParameterBinding.CreateBindingForMarkedParameters);

4) क्या आपके क्लाइंट पैरामीटर को ऑब्जेक्ट के गुणों के रूप में पास करते हैं। DoSomething(param1, param2, param3) विधि के लिए JSON ऑब्जेक्ट का एक उदाहरण है:

{ param1:{ Text:"" }, param2:{ Text:"" }, param3:"" }

उदाहरण JQuery:

$.ajax({
    data: JSON.stringify({ param1:{ Text:"" }, param2:{ Text:"" }, param3:"" }),
    url: '/MyService/DoSomething',
    contentType: "application/json", method: "POST", processData: false
})
.success(function (result) { ... });

अधिक जानकारी के लिए https://github.com/keith5000/MultiPostParameterBinding जाएं।

अस्वीकरण: मैं सीधे जुड़े संसाधन से जुड़ा हूं।