سؤال

I have created an Web-API 2 Post method to upload a physical file to the server. I noticed I could still call that API without passing an actual file.

So when the server side runs these 2 lines of code

var sp = new MultipartFormDataStreamProvider(fileName);
await Request.Content.ReadAsMultipartAsync(sp);

When the client (not a browser, not fiddler) calls the API but does not upload a file, I get an exception (that is trapped).

QUESTION:
Is there a way to check if the Request carries a file, BEFORE calling the Request.Content.ReasAsMultipartAsync??

My problem is NOT to trap the exception, but to find a clean way to learn before I get into the exception that there was no file so that I can notify the calling client about it.

هل كانت مفيدة؟

المحلول 2

Agree with @Radim's response.

Another approach you can take (only if you host your service in IIS only, the default template does it)

HttpResponseMessage result = null;
var httpRequest = HttpContext.Current.Request;

// Check if files are available
if (httpRequest.Files.Count > 0)
{

Note that you are taking a dependency on System.Web here, but if you are on IIS and not self hosting this is fine.

نصائح أخرى

Firstly, I would suggest to wrap this statement in try catch, as shown here: Sending HTML Form Data.

// 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);

try
{
  // Read the form data.
  await Request.Content.ReadAsMultipartAsync(provider);

  // TODO ... process files

  return Request.CreateResponse(HttpStatusCode.OK);
}
catch (System.Exception e)
{
  return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
}

Why to use explicit try catch? We never now who and how will assemble the http request (Browser, Fiddler, third-party tool) ... and the content could be simply damaged, impossible to handle standard way.

The point with Async content readers is, that we have to read the content, to get the answer:

is there any file included?

That's the way Web API is designed. Read the content only once, only if needed. Before that ... there is no info about the content available.

For example, if there is a request coming from a Browser with a <form> like this:

<form method="post" 
   enctype="multipart/form-data"
   action="/api/MyService/Upload">

 <input type="file" name="myFile"/>
 <button type="submit">submit</button>

</form>

Then even in case, that we will just submit (without selecting any file) part of the request body will be:

-----------------------------7de411d9099c
Content-Disposition: form-data; name="myFile"; filename=""
Content-Type: application/octet-stream


-----------------------------7de411d9099c--

So, until we will read we do not know if there is any file

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top