9

का उपयोग कर फॉर्म मल्टीपार्ट फॉर्म पोस्ट करें मेरे पास A guide to asynchronous file uploads in ASP.NET Web API RTM से अनुकूलित एक पोस्ट एएसपी.Net वेब एपीआई विधि है।एएसपी.Net वेब एपीआई

मैं पहले अनुरोध को निकालकर पूरा होने के बाद निकाल दिए गए सभी अनुरोधों के साथ दोषपूर्ण कार्य समस्या में भाग रहा हूं।

यहां परिदृश्य है: मेरे पास एक नमूना पृष्ठ है जो वेब पैरामीटर पोस्ट विधि के लिए अन्य पैरामीटर के साथ एक फ़ाइल पोस्ट करता है। यह पहली बार ठीक काम करता है और फ़ाइल अपलोड की जाती है। लेकिन, बाद के सभी अनुरोध कार्य को एक दोषपूर्ण स्थिति में समाप्त कर देते हैं। मुझे "एमआईएमई मल्टीपार्ट स्ट्रीम का अप्रत्याशित अंत मिलता है। माइम मल्टीपार्ट संदेश पूरा नहीं हुआ है। "कोई विचार क्यों?

नीचे पोस्ट किया गया मेरे पोस्ट विधि, नमूना HTML फॉर्म और कुल अपवाद का स्रोत कोड है।

public Task<HttpResponseMessage> Post([FromUri]string memberNumber) 
    { 
     // Check if the request contains multipart/form-data. 
     if (!Request.Content.IsMimeMultipartContent()) 
     { 
      throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); 
     } 

     string root = HttpContext.Current.Server.MapPath("~/App_Data"); 
     var provider = new MultipartFormDataStreamProvider(root); 

     // Read the form data and return an async task. 
     var task = Request.Content.ReadAsMultipartAsync(provider). 
      ContinueWith(t => 
      { 
       if (t.IsFaulted || t.IsCanceled) 
       { 
        throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.InternalServerError, t.Exception)); 
       } 

       return Request.CreateResponse(HttpStatusCode.OK, new MyModel()); 
      }); 

     return task; 
    } 

मैं इस तरह एक नमूना प्रपत्र का उपयोग इस वेब एपीआई फायरिंग कर रहा हूँ:

<form name="form1" method="post" enctype="multipart/form-data" action="api/claims/asd123" style="margin:auto;width:500px;"> 
    <div> 
     <label for="HCPracticeNumber">HC Pratice Number:</label> 
     <input type="text" name="HCPracticeNumber" id="HCPracticeNumber"/> 
    </div> 
    <div> 
     <label for="ServiceDate">Service/Treatment date:</label> 
     <input type="text" name="ServiceDate" id="ServiceDate"/> 
    </div> 
    <div> 
     <label for="AmountClaimed">Amount Claimed:</label> 
     <input type="text" name="AmountClaimed" id="AmountClaimed"/> 
    </div> 
    <div> 
     <label for="Image">Image Attachment:</label> 
     <input name="Image" type="file" /> 
    </div> 
    <div> 
     <input type="submit" value="Submit" /> 
    </div> 
</form> 

इस प्रकार AggregateException कि लौटा दिया जाता है जाता है:

<Error> 
<Message>An error has occurred.</Message> 
    <ExceptionMessage>One or more errors occurred.</ExceptionMessage> 
    <ExceptionType>System.AggregateException</ExceptionType> 
    <StackTrace/> 
    <InnerException> 
     <Message>An error has occurred.</Message> 
     <ExceptionMessage> 
      Unexpected end of MIME multipart stream. MIME multipart message is not complete. 
     </ExceptionMessage> 
     <ExceptionType>System.IO.IOException</ExceptionType> 
     <StackTrace> 
      at System.Net.Http.Formatting.Parsers.MimeMultipartBodyPartParser.<ParseBuffer>d__0.MoveNext() at System.Net.Http.HttpContentMultipartExtensions.MoveNextPart(MultipartAsyncContext context) 
     </StackTrace> 
    </InnerException> 
</Error> 

अद्यतन:

अपनी ब्लॉग साइट पर फिलिप के सुझाव के बाद, मैं मोडी इस तरह 0 को धारा स्थिति को रीसेट करने के बाद विधि fied:

 Stream reqStream = Request.Content.ReadAsStreamAsync().Result; 
     if (reqStream.CanSeek) 
     { 
      reqStream.Position = 0; 
     } 
     var task = Request.Content.ReadAsMultipartAsync(provider). 
      ContinueWith(t => 
      { 
       if (t.IsFaulted || t.IsCanceled) 
       { 
        throw new HttpResponseException(
        Request.CreateErrorResponse(HttpStatusCode.InternalServerError, 
        t.Exception)); 
       } 

       return Request.CreateResponse(HttpStatusCode.OK, new MyModel()); 

      }); 

लेकिन, यह बहुत ही मनमौजी कोड है। यह कभी-कभी काम करता है यह अन्य बार नहीं होता है। दूसरे शब्दों में, यह पूरी तरह से समस्या को ठीक नहीं करता है।

+0

क्या आप कहीं और अनुरोध के शरीर को पढ़ते हैं? यानी संदेशवाहक? आप फॉर्म से अन्य चर के साथ क्या करते हैं? आम तौर पर ऐसी त्रुटि का अर्थ यह होगा कि अनुरोध का शरीर पहले से ही पढ़ा गया है और सामग्री स्ट्रीम स्थिति अंत में है। –

+0

भी, क्या आप वेब एपीआई आरटीएम का उपयोग कर रहे हैं? –

+0

हां, मैं वेब एपीआई आरटीएम का उपयोग कर रहा हूं। हां, मेरे पास HTTP-Method-Override हैडर की जांच के लिए एक संदेश हैंडलर है और मेरे पास आपका वेबएपीयूज हैंडलर और दूसरा प्रमाणीकरण हैंडलर है। मैं अभी तक अन्य पैरामीटर के साथ कुछ भी नहीं कर रहा हूं, लेकिन मैं उन्हें भी पढ़ूंगा। इससे पहले कि मैं इससे निपटने से पहले मैं यह सामान काम करना चाहता हूं। क्या अन्य पैरामीटर पढ़ा नहीं जा रहा है इस समस्या पर असर पड़ता है? – badikumar

उत्तर

14

यह बताता है कि फिलिप ने टिप्पणियों में सुझाव दिया था कि वेब एपीआई उपयोग हैंडलर जिसे मैंने Implementing Message Handlers To Track Your ASP .net Web API Usage से अनुकूलित किया था, सामग्री सामग्री को पढ़ रहा था और इसलिए मेरे पोस्ट में अनुरोध संसाधित होने पर स्ट्रीम पर स्थिति साधक के साथ गड़बड़ कर रहा था तरीका।

तो, मैंने वेबएपीयूजेज हैंडलर को एक सशर्त बयान जोड़ा है, यदि अनुरोध IsMimeMultipartContent प्रकार का अनुरोध है तो अनुरोध निकाय को नहीं पढ़ा। यह समस्या ठीक है।

अद्यतन

मैं, एक और विकल्प के साथ जवाब को अपडेट करना चाहते मेरे लिए इतना है कि यह दस्तावेज है, ईमेल के माध्यम से फ़िलिप ने सुझाव दिया:

आप एपीआई उपयोग हैंडलर के अंदर इस कोड का उपयोग करते हैं, तो सिर्फ शरीर को पढ़ने से पहले:

//read content into a buffer 
    request.Content.LoadIntoBufferAsync().Wait(); 

    request.Content.ReadAsStringAsync().ContinueWith(t => 
    { 
     apiRequest.Content = t.Result; 
     _repo.Add(apiRequest); 
    }); 

अनुरोध बफ़र जाएगा और इसे दो बार पढ़ने के लिए संभव हो जाएगा, और इसलिए अपलोड पाइप लाइन नीचे आगे संभव हो जाएगा। उम्मीद है कि यह मदद करता है।

2

यह मूल पोस्टर के प्रश्न का उत्तर नहीं है। हालांकि, मेरे कोड में एक से अधिक बार ReadAsMultipartAsync() विधि को कॉल करने से भी एक ही अपवाद होता है:

public async Task<IHttpActionResult> PostFiles() 
{ 

    // Check if the request contains multipart/form-data. 
    if (!Request.Content.IsMimeMultipartContent()) 
    { 
     return Content(HttpStatusCode.BadRequest, "Unsupported media type. "; 
    } 
    try 
    { 
     var provider = new CustomMultipartFormDataStreamProvider(workingFolder); 

     await Request.Content.ReadAsMultipartAsync(provider); // OK 
     await Request.Content.ReadAsMultipartAsync(provider); // calling it the second time causes runtime exception "Unexpected end of MIME multipart stream. MIME multipart message is not complete" 
     ... 

    } 
    catch(Exception ex) 
    { 
     ... 
    } 
} 
संबंधित मुद्दे