फाइल कोणीय से ASP.NET कोर पर अपलोड करें

Dec 11 2020

पहली बार मैं एक कोणीय घटक से ASPNET कोर वेब पेज पर एक फ़ाइल अपलोड करने की कोशिश कर रहा हूं, और बस इसे काम करने के लिए नहीं मिल सकता। उम्मीद है कि जो चल रहा है उसकी अनिवार्यता दिखाने के लिए निम्नलिखित कोड अंश पर्याप्त होंगे। मुद्दा यह है कि यद्यपि मैं इस बात की पुष्टि करता हूं कि HttpClient की पोस्ट विधि (frmData) को पारित पैरामीटर वैध है, ASPNet Core एक्शन विधि इसे कभी नहीं देखती है, और रिपोर्ट करती है कि IFormFile हमेशा शून्य है।

संपादित करें: मैंने पहले सामग्री-प्रकार के रूप में मल्टीपार्ट / फॉर्म-डेटा का उपयोग करने की कोशिश की थी लेकिन मैंने केस्टरेल के साहस में एक अखंड अपवाद दिया। मुझे अब एहसास हुआ कि ऐसा करने का यह सही तरीका है, और json सामग्री प्रकार का उपयोग करना मेरी मूल समस्या का स्रोत था। लेकिन मुझे नहीं पता कि यहां से कहां जाना है। मैं देख रहा हूँ कि कुछ गॉगलिंग में अपवाद होने के लिए लगभग एक बिलियन अलग-अलग कारण हैं।

पोस्टिंग समापन बिंदु 'JovenesA.Controllers.StudentssController.PostStudentGradesReport (JAWebAPI)'
04: 55: 38.4853 इंफो कंट्रोलरएशनइंवर
POST रूट {क्रिया = "PostStudentGradesReport", नियंत्रक = "Becas"} से मेल खाता है। निष्पादन कार्रवाई JovenesA.Controllers.BecasController.PostStudentGradesReport (JAWebAPI)
04: 55: 38.5032 त्रुटि
अनुरोध को निष्पादित करते समय एक बिना अपवाद अपवाद हुआ है।
04: 55: 38.5333 इन्फो वेबहोस्ट
POST अनुरोध 48.1225ms 500 पाठ / html में समाप्त हुआ; charset = utf-8
04: 55: 38.5333 इंफो केस्टरेल
 कनेक्शन आईडी "0HM4UHGE85O17", अनुरोध आईडी "0HM4UHGE85O17: 00000006": संपूर्ण अनुरोध निकाय को पढ़े बिना पूरा किया गया आवेदन।

किसी भी तरह की सहायता का स्वागत किया जाएगा!

कोणीय घटक:

fileEntry.file((file: File) => {
      console.log('fileEntry relativePath: ' + currFile.relativePath);
      console.log('filEntry.name: ', file.name);
      console.log('filEntry.size: ', file.size);

      const frmData = new FormData();
      frmData.append(file.name, file);

      this.studentData.uploadStudentGradesReport(file.name, frmData).subscribe(
        () => {
          this.successMessage = 'Changes were saved successfully.';
          window.scrollTo(0, 0);
          window.setTimeout(() => {
            this.successMessage = '';
          }, 3000);
        },
        (error) => {
          this.errorMessage = error;
        }
      );
    });

कोणीय सेवा:

public uploadStudentGradesReport(filename: string, frmData: FormData): Observable<any> {
    const url = this.WebApiPrefix + 'students/' + 'student-grades-report';
    const headers = new HttpHeaders().set('Content-Type', 'application/json');
    if (frmData) {
      console.log('ready to post ' + url + ' filename: ' + filename + ' options ' + headers);
      return this.http.post(url, frmData, { headers });
    }
}

ASPNET कोर नियंत्रण

// POST api/students/student-grades-report
[HttpPost("student-grades-report", Name = "PostStudentGradseReportRoute")]
//[ValidateAntiForgeryToken]
[ProducesResponseType(typeof(GradesGivenEntryApiResponse), 200)]
[ProducesResponseType(typeof(GradesGivenEntryApiResponse), 400)]
public async Task<ActionResult> PostStudentGradesReport([FromForm] IFormFile myFile)
{
    _Logger.LogInformation("Post StudentGradesReport  ");

    if (myFile != null)
    {
        var totalSize = myFile.Length;
        var fileBytes = new byte[myFile.Length];

यदि यह मदद करता है, तो यहां वह डेटा है जिसे POST अनुरोध में भेजा जा रहा है

POST http://192.168.0.16:1099/api/students/student-grades-re HTTP/ 1.1
मेजबान: 192.168.0.16:1099
कनेक्शन: जीवित रखें
सामग्री-लंबाई: 13561
स्वीकार करें: आवेदन / json, पाठ / सादे, * / *
DNT: 1
उपयोगकर्ता-एजेंट: मोज़िला / 5.0 (विंडोज NT 10.0; Win64; x64) AppleWebKit / 537.36 (KHTML, गेको की तरह) क्रोम / 87.0.4280.88 सफारी / 537.36
सामग्री-प्रकार: आवेदन / json
उत्पत्ति: http: // localhost: 3000
रेफ़र: http: // localhost: 3000 /
स्वीकार-एन्कोडिंग: गज़िप, अपस्फीति
स्वीकार-भाषा: en-US, en; q = 0.9, es-MX; q = 0.8, es; q = 0.7

------ WebKitFormBoundaryBVuZ7IbkjtQAKQ0a
सामग्री-विवाद: फ़ॉर्म-डेटा; नाम = "test1.PNG"; फ़ाइल नाम = "test1.PNG"
सामग्री-प्रकार: छवि / पीएनजी

 पीएनजी
 
  [छवि फ़ाइल की द्विआधारी सामग्री]  

------ WebKitFormBoundaryBVZZ7IbkjtQAKQ0a--

जवाब

2 jandrew Dec 12 2020 at 09:30

आप फ़ाइल को प्रपत्र डेटा के रूप में भेज रहे हैं, इसलिए आपको सही सामग्री प्रकार हेडर निर्दिष्ट करने की आवश्यकता है। वर्तमान application/jsonमें Content-Typeहेडर में आपका भेजना । एपीआई को कॉल करते समय भी यह सच है, जो पहली बार में भ्रमित हो सकता है। इस मामले में सही सामग्री प्रकार है multipart/form-data। आपका API नहीं देख रहा है IFormFileक्योंकि उसे लगता है कि अनुरोध JSON है। मैंने आपका कोणीय कोड सही सामग्री-प्रकार हेडर मूल्य के साथ संशोधित किया है।

संपादित करें: पता चलता है कि Content-Typeहेडर को मैन्युअल रूप से निर्दिष्ट करने से सीमा मानों को हेडर मूल्य में स्वचालित रूप से सेट नहीं होने का कारण होगा। इसके बजाय, सरल उपाय यह है कि हेडर को स्वयं न जोड़ा जाए, जिसके परिणामस्वरूप उचित सामग्री-प्रकार और सीमा मान स्वचालित रूप से सेट हो जाएंगे। यदि आप हेडर को स्वयं सेट करते हैं, तो आपको सीमा मान भी निर्धारित करने होंगे। अधिकांश स्थितियों के लिए, इसे डिफ़ॉल्ट रूप से छोड़ना शायद सबसे अच्छा समाधान है। प्रश्न / उत्तर के लिए लिंक जो इसे इंगित करता है। FormData मल्टीपार्ट / फॉर्म-डेटा - कोणीय में सीमा कैसे प्राप्त करें या सेट करें

public uploadStudentGradesReport(filename: string, frmData: FormData): Observable<any> {
    const url = this.WebApiPrefix + 'students/' + 'student-grades-report';
    const headers = new HttpHeaders().set('Content-Type', 'multipart/form-data');
    if (frmData) {
      console.log('ready to post ' + url + ' filename: ' + filename + ' options ' + headers);
      return this.http.post(url, frmData, { headers });
    }
}

आप उस कंटेंट-डिस्प्यूट को भी नोट कर सकते हैं जो आपके द्वारा दिए गए HTTP रिक्वेस्ट पर है, जो फाइल के प्रकार के साथ-साथ फॉर्म डेटा दिखाता है। उम्मीद है की यह मदद करेगा। मैंने आपके कोड का परीक्षण करने के लिए एक कोणीय परियोजना को फायर नहीं किया, लेकिन सामग्री-प्रकार को आपके मुद्दे को ठीक करना चाहिए।

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

frmData.append('file', file);

और फिर अपने नियंत्रक कार्रवाई के लिए

public async Task<IActionResult> PostStudentGradesReport([FromForm] IFormFile file)
{
    if (file.Length <= 0 || file.ContentType is null) return BadRequest();
    var actualFileName = file.FileName;

    using (var stream = file.OpenReadStream())
    {
        // Process file...
    }
    
    return Ok(); 
}
1 Coco Dec 11 2020 at 23:02

मैं गारंटी नहीं दे सकता कि यह काम करेगा, लेकिन आप Angular's HttpRequest का उपयोग करके देख सकते हैं। तो अपनी कोणीय सेवा में, यह प्रयास करें:

const request = new HttpRequest (
    'POST',
     url, // http://localhost/your_endpoint
     frmData,
     { withCredentials: false }
);
    
return this.http.request(request);

यह भी ध्यान दें कि आपको बैकएंड एपि को कॉल करने वाले फ़ंक्शन में डेटा सत्यापन नहीं करना चाहिए। अगर if(frmData)झूठ है तो आपका क्या काम है?