Android – Upload files to ASP.NET Web API service

In previous posts, I showed you how to get/post data to ASP.NET Web API service. However, until now, I only used JSON for communicating between server and client and what about for binary data? For example, uploading files to ASP.NET Web API? How should the controller work and which kind of HTTP request/HTTP format should the Android client send to server? In this blog post, I will show you a simple way to transfer binary data. In the demo, I have 2 components : web service and android client. Unlike the other post, for this one, unfortunately, I don’t have any sample web service (online over internet) for you to test. I don’t own any windows server (neither VPS nor dedicated server :() therefore I can’t host any web service allowing file uploading.

In the download section, at the end of post, you’ll find the source code of web service and Android client. To play the demo, you’ve to publish the service to your localhost and connect your client to it. If you don’t know how to publish a web service to your localhost, please follow instructions here .

Moreover, in this post, I will show you how a web service serves different kinds of client. I have already prepared 4 clients: Android client, console client, drag and drop web client and file browsing web client. The client and server will use HTTP request of mime multipart encoding type for transferring data. You will see this setting applied at all sample clients.

1. Web service

When you open the web service solution, you’ll see there are 3 projects.
– The “Upload File To ASPNET Web API” project is the web service itself and 2 web clients.
– The “Upload File To ASPNET Web API Client” is the console client.
– The “Upload File To ASPNET Web API Models” defines contract between server and client.

In this part, we’ll focus only on the web service to analyze how it works. Go to “Upload File To ASPNET Web API” project –> HDFilesController where the logic code of web service locates.

public Task<IQueryable<HDFile>> Post()
		var uploadFolderPath = HostingEnvironment.MapPath("~/App_Data/" + UploadFolder);

		//#region CleaningUpPreviousFiles.InDevelopmentOnly
		//DirectoryInfo directoryInfo = new DirectoryInfo(uploadFolderPath);
		//foreach (FileInfo fileInfo in directoryInfo.GetFiles())
		//	fileInfo.Delete();

		if (Request.Content.IsMimeMultipartContent())
			var streamProvider = new WithExtensionMultipartFormDataStreamProvider(uploadFolderPath);
			var task = Request.Content.ReadAsMultipartAsync(streamProvider).ContinueWith<IQueryable<HDFile>>(t =>
				if (t.IsFaulted || t.IsCanceled)
					throw new HttpResponseException(HttpStatusCode.InternalServerError);

				var fileInfo = streamProvider.FileData.Select(i =>
					var info = new FileInfo(i.LocalFileName);
					return new HDFile(info.Name, Request.RequestUri.AbsoluteUri + "?filename=" + info.Name, (info.Length / 1024).ToString());
				return fileInfo.AsQueryable();

			return task;
			throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable, "This request is not properly formatted"));
	catch (Exception ex)
		throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.BadRequest, ex.Message));

uploadFolderPath variable determines where the files should be temporarily uploaded into server. I upload directly to App_Data folder but you can set to other folder as you want. Just remember to give full control permission to IUSER so that IIS can write file to that folder.
After setting the folder, the content of request will be validated if it’s a mime-multipart type. If the request is not conformed, web service will reject with HttpStatusCode.NotAcceptable. If the request is correct, the binary data will be extracted from content and IIS stores files in specified location.
However we should always remember that we “never trust user input”. The file name given in HTTP request maybe not conformed (file name in Unix platform can be not accepted in Windows platform), so we have to change the original file name in the request to new file name which we can be sure that it won’t “hurt” our server. I choose the format of {GUID}.{FILE_EXTENSION}, you can choose another format as you like, maybe with time stamp. Just making a class inherits from MultipartFormDataStreamProvider and override the GetLocalFileName with your own logic. For example, my custom MultipartFormDataStreamProvider looks like following

public class WithExtensionMultipartFormDataStreamProvider : MultipartFormDataStreamProvider
	public WithExtensionMultipartFormDataStreamProvider(string rootPath)
		: base(rootPath)

	public override string GetLocalFileName(System.Net.Http.Headers.HttpContentHeaders headers)
		string extension = !string.IsNullOrWhiteSpace(headers.ContentDisposition.FileName) ? Path.GetExtension(OSUtil.GetValidFileName(headers.ContentDisposition.FileName)) : "";
		return Guid.NewGuid().ToString() + extension;

After all files were successfully uploaded to server, the Post action reply the client with a list of object in JSON format. This list contains many JSON objects with file name (on server), size and URL. Return URL back to client allowing user the possibility to get file back or share file with other user.

I have already extended the web service so that the user can download files not only through the given URLs but also through a GET HTTP request with correct parameter. In the controller, I wrote a GET action receiving file name as parameter, search for file name in server if it exists and give file back.

public HttpResponseMessage Get(string fileName)
	HttpResponseMessage result = null;

	DirectoryInfo directoryInfo = new DirectoryInfo(HostingEnvironment.MapPath("~/App_Data/" + UploadFolder));
	FileInfo foundFileInfo = directoryInfo.GetFiles().Where(x => x.Name == fileName).FirstOrDefault();
	if (foundFileInfo != null)
		FileStream fs = new FileStream(foundFileInfo.FullName, FileMode.Open);

		result = new HttpResponseMessage(HttpStatusCode.OK);
		result.Content = new StreamContent(fs);
		result.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
		result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
		result.Content.Headers.ContentDisposition.FileName = foundFileInfo.Name;
		result = new HttpResponseMessage(HttpStatusCode.NotFound);

	return result;

That is all about our web service. One POST action for posting binary data from client to server and one GET action for give binary data back from server to client. That means we have 2 ways binary data communicating channel.

2. Clients

In this second part, we build up our clients. As I mentioned at the beginning, I will introduce 4 types of client to prove that we can use our web service for many client system. Important: Remember to start you web service when you connect the clients to it. :).

2.1 Android client

Before getting started, I recommend you to read this article first (if you didn’t) . I will use dependency injection in example, it’s nothing special. Just if you don’t know how DI works, it’s very difficult for you to understand how the code works later.

The second note is Android client can only access the web service at your real localhost. He can’t access the web service in Debug mode of Visual Studio (for example http://localhost:4260/…). So, you have to really publish the web service code to your localhost. If you don’t know how to publish the web service, you can read the instructions at the link I post at the beginning.

In Android client, there are only 2 activities: the main activity and the result activity. The main activity is a list activity where I will show all files under “sdcard/wallpapers” folder. When the Android client starts, I will list all files in folder, pop them up the main activity so that user can choose which file they would like to upload to server.

public List<HDFile> getLocalFiles() {
	List<HDFile> result = new ArrayList<HDFile>();
	String sdCard = Environment.getExternalStorageDirectory().getAbsolutePath();
	String wallpaperPath = sdCard + "/wallpapers/";
	File files[] = new File(wallpaperPath).listFiles();
	for(int index=0;index < files.length;index++)
		HDFile wallpaper = new HDFile();
	return result;

The code listing above will get path of “sdcard”, find the folder “wallpapers” beneath it and then push all files into a list. HDFile is the contract object for communicating between server and client. CryptoUtil and IOUtil are just helper utilization class. You can check the code out from the repositories at the end of post.

After the local files were loaded successfully, I will display them on our main activity with check boxes so that we can tick which files we want to upload. However, as default, the list activity doesn’t provide us a layout with check box in front. Therefore, we need to define an adapter to customize the layout as following

public class ListViewLocalFileAdapter extends ArrayAdapter<HDFile> {
    private List<HDFile> hdFiles;
    private Context context;

    public ListViewLocalFileAdapter(Context context, int textViewResourceId, List<HDFile> objects) {
        super(context, textViewResourceId, objects);
        this.context = context;
        this.hdFiles = objects;


    static class ViewHolder
        protected CheckBox checkBox;
        protected TextView textViewName;

    public View getView(int position, View convertView, ViewGroup parent) {

        View view = null;
        if (convertView == null)
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.list_file_item,null);
            final ViewHolder viewHolder = new ViewHolder();
            viewHolder.checkBox = (CheckBox)view.findViewById(;
            viewHolder.textViewName= (TextView)view.findViewById(;

            view = convertView;

        ViewHolder viewHolder=(ViewHolder)view.getTag();
        return view;

    private CompoundButton.OnCheckedChangeListener CheckBoxOnCheckedChangeListener = new CompoundButton.OnCheckedChangeListener() {
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            CheckBox checkBox = (CheckBox)buttonView;
            HDFile hdFile = (HDFile) checkBox.getTag();

    public List<HDFile> getItems()
        return hdFiles;

And then when the app starts, the main activity will look like this

List With Checkbox activity

Remember that the sample files are loaded from “sdcard/wallpapers” folder, be sure that you have some sample files in that folder and of course, the folder “wallpapers” must also exist.

Android Debug Monitor File Explorer

To upload file to server, just choose some files and tap on the upload button on the action bar. That will make a HTTP POST to server and upload our files.

<?xml version="1.0" encoding="utf-8"?>

<menu xmlns:android="">
    <item android:id="@+id/main_menu_upload"
          android:showAsAction="ifRoom|withText" />

public boolean onCreateOptionsMenu(Menu menu) {
	MenuInflater menuInflater = getMenuInflater();
	menuInflater.inflate(, menu);
	return true;

public boolean onOptionsItemSelected(MenuItem item) {

	switch (item.getItemId()) {
			List<HDFile> selectedFiles = new ArrayList<HDFile>();
			for(HDFile file:adapter.getItems())
				if (file.isSelected())

			if (selectedFiles.size()>0)
				AlertMessageBox.Show(getApplicationContext(),"Info","Please select a file to upload", AlertMessageBox.AlertMessageBoxIcon.Info);
			return true;
			return super.onOptionsItemSelected(item);


public void uploadFiles(List<HDFile> files) {
	new UploadFilesTask().execute(files.toArray(new HDFile[files.size()]));

class UploadFilesTask extends AsyncTask<HDFile,String,Integer>
	Integer totalCount = 0;
	protected Integer doInBackground(HDFile... params) {
		Integer uploadCount =0;
		totalCount = params.length;
		uploadedFiles = new ArrayList<HDFile>();
		for(int index=0;index < params.length;index++)
			File file = new File(params[index].getFilePath());
			JSONHttpClient jsonHttpClient = new JSONHttpClient();
			HDFile[] hdFiles = jsonHttpClient.PostFile(ServiceUrl.REST_SERVICE_URL, params[index].getId(),file,params[index].getName(),HDFile[].class);
			if (hdFiles != null && hdFiles.length == 1)
		return uploadCount;

	protected void onPostExecute(Integer uploadCount) {
		UploadErrorCode errorCode = UploadErrorCode.OK;
		if (uploadCount ==0)
			errorCode = UploadErrorCode.Failed;
		else if (uploadCount < totalCount)
			errorCode = UploadErrorCode.PartlySuccessful;
		if (uploadFilesCompleteListener != null)


The files will be uploaded one by one to server. You can extend my code for notifying upload progress changes. According to the count of uploaded files, we send appropriate error code back (failed, partly successful or OK). When upload progress finishes, the information of uploaded files will be shown on the result activity.

Uploaded files

The code for this activity is pretty simple, I think you can read and understand yourself.

2.2 .Net client

We have checked how the Android client works. In this part, I will show you how to consume our web service in a desktop application. The .net client is much more simple than Android client, there is no UI for it. ๐Ÿ™‚ . I just make a simple console application, create a HTTP post with MultipartFormDataContent, push the content to it and send it to server.

private static async void UploadFiles()
	Uri server = new Uri("http://localhost:4260/api/hdfiles");
	HttpClient httpClient = new HttpClient();

	StringContent stringContent = new StringContent("Broken Sword: The Shadow of the Templars (also known as Circle of Blood in the United States)[1] is a 1996 point-and-click adventure game developed by Revolution Software. The player assumes the role of George Stobbart, an American tourist in Paris, as he attempts to unravel a conspiracy. The game takes place in both real and fictional locations in Europe and the Middle East.", Encoding.UTF8, "text/plain");
	StreamContent streamConent = new StreamContent(new FileStream(@"..\..\TestData\HintDesk.png", FileMode.Open, FileAccess.Read, FileShare.Read));

	MultipartFormDataContent multipartFormDataContent = new MultipartFormDataContent();
	multipartFormDataContent.Add(stringContent, "Broken Sword", "Broken Sword.txt");
	multipartFormDataContent.Add(streamConent, "HintDesk", "HintDesk.png");

	//HttpResponseMessage responseMessage = await httpClient.PostAsync(server, multipartFormDataContent);
	HttpResponseMessage responseMessage = httpClient.PostAsync(server, multipartFormDataContent).Result;

	if (responseMessage.IsSuccessStatusCode)
		IList<HDFile> hdFiles = await responseMessage.Content.ReadAsAsync<IList<HDFile>>();
		if (Directory.Exists(DownloadFolder))
			(new DirectoryInfo(DownloadFolder)).Empty();

		foreach (HDFile hdFile in hdFiles)
			responseMessage = httpClient.GetAsync(new Uri(hdFile.Url)).Result;

			if (responseMessage.IsSuccessStatusCode)
				using (FileStream fs = File.Create(Path.Combine(DownloadFolder, hdFile.Name)))
					Stream streamFromService = await responseMessage.Content.ReadAsStreamAsync();

The HTTP request of code listing above contains 2 files “Broken Sword.txt”, and “HintDesk.png”. After posting files successfully, I will download them back again, just for testing if everything works. You see, the .net client is not much different from unit test but it’s good example to show how to consume the web service in desktop application.

2.3 Web client: Drag and Drop

In this part, we’ll discuss our 3rd client: the web client with drag and drop. We’ll use feature “drag and drop” of HTML5 to allow user to drag/drop file from his local computer to server.

Web client drag and drop

The source code of this client is in the same project of web service. Browse to Views –> DirectUpload –> Index.cshtml is where the layout of this client locates.

Drag And Drop HTML

In the Index.cshtml is the HTML code for building up the container where user can drop files and another container for showing the information of uploaded files. The javascript code for handling drag and drop is in the “~/bundles/draganddropscripts” defined in BundleConfig.cs

bundles.Add(new ScriptBundle("~/bundles/draganddropscripts")

In fileuploadbydraganddrop.js is where we will handle the drop event

function drop(evt) {

    var files = evt.originalEvent.dataTransfer.files;

    if (files.length > 0) {
        if (window.FormData !== undefined) {
            var data = new FormData();
            for (i = 0; i < files.length; i++) {
                data.append("file" + i, files[i]);


                type: "POST",
                url: root + "api/hdfiles",
                contentType: false,
                processData: false,
                data: data,
                success: function (res) {
                    $.each(res, function (i, item) {
        } else {
            alert("Your browser needs to support HTML5.");

After files are dropped to container, an ajax call will be sent to HDFilesController. When ajax call finishes, result will pushed back to viewModel. Then Knockout.js will bind data to result container.

2.4 Web client: Form

Our last client is also a web client. However, we use now the web client using form object. This web client works as same as web client with drag and drop. However I have to combine HTML and Javascript to display the uploading progress like following

<section class="content-wrapper main-content clear-fix">
	<div id="divFormUpload">
		<form id="formUpload" action="@Url.Content("~/api/hdfiles")" method="post" enctype="multipart/form-data">
			<label class="displayinline">Files</label>
			<input name="inputFiles" type="file" multiple />
			<input type="submit" value="Upload" />
			<div id="divProgress" style="display: none">
				<div id="divPercentBar" class="classDivPercentBar"></div>
				<div id="divPercentText" class="classDivPercentText">0%</div>
				@*<img alt="" id="upload-animation" src="/Content/images/loading.gif" />*@

	<ul data-bind="template: { name: 'fileContainer', foreach: uploads }"></ul>
	<script type="text/html" id="fileContainer">
			<span>Uploaded: <small data-bind="text: Name"></small>.</span>
			<span>Size: <small data-bind="text: Size"></small>kB</span>
			<span>Server path: <small><a data-bind="    attr: { href: Url }, text: Url"></a></small></span>


$(document).ready(function () {
    var divProgress = $("#divProgress");
    var divBar = $("#divPercentBar");
    var divPercent = $("#divPercentText");

        beforeSend: function () {
            var percentVal = '0%';
        uploadProgress: function (event, position, total, percentComplete) {
            var percentVal = percentComplete + '%';
        success: function (res) {
            var percentVal = '100%';
            $.each(res, function (i, item) {
        complete: function (xhr) {
var viewModel = {
    uploads: ko.observableArray([])

Web client form

The api controller URL isn’t set in javascript code but directly in HTML. The javascript is just for displaying the progress changes.

3. Conclusion

– Now we’re at the end of the post. We’ve already learnt how to transfer binary data between server and client. We already know how to consume the web service with many types of client.
– The source code of server and other client can be downloaded from following link:
– Android client can be downloaded from following link
– Util classes can be checked out from

4. Updates

4.1. Update 31.01.2014

The standard limitation for file size in IIS is about 4MB. If you want to allow uploading bigger file, you can add following setting in Web.config, for example, this config below allows file size up to 100MB.

<httpRuntime targetFramework="4.5" maxRequestLength="102400" />

        <requestLimits maxAllowedContentLength="104857600" />

Please note that maxRequestLength is measured in Kb and maxAllowedContentLength in bytes. Both values above equal to 100Mbytes.

4.2. Update 18.04.2014

In the demo Android client when a file is posted to web service its name part will be set by Id

HDFile[] hdFiles = jsonHttpClient.PostFile(ServiceUrl.REST_SERVICE_URL, params[index].getId(), file, params[index].getName(), HDFile[].class);

This name part you can read it again by accessing FileData.Headers.ContentDisposition.Parameters

Get Id from Post request

4.3. Update 29.10.2014

Add video demo

77 thoughts on “Android – Upload files to ASP.NET Web API service”

  1. @longId: I can’t help you much because you’re using free hosting plan. Event set customErrors mode to Off I can’t see the real error at server site. Therefore I don’t really why the web service can’t be loaded.

  2. I got a problem: my PC was disconnect from internet in 3s when uploading and then reconnect (weak connection). The application was not responding. Please help me solver this problem! Thanks.

  3. @longld: I have no solution right now for resuming uploading. You may take a search to find your own solution.

    It’s nice if you can write your solution to fix your problems so that someone else who has same problem can solve it too.

  4. Hello,

    Thank you for your post on how to create a restful api to transfer files.
    It working well with files and i’ve been able to customize to my needs.

    I’ve got an error when somebody try to upload some data on the server with a different syntax than usual.

    the text file to be uploaded is created directly in the request .


    Content-Disposition: form-data; name=”fileToUpload”; filename=”file.txt”

    line 1 – this is some sample data
    line 2 – this is some sample data


    The files are well uploaded to the server but the http code return is 500 instead of 200.
    Have you got any idea on how solve the problem?

    I’ve put he request and answer below:

    POST /api/hdfiles HTTP/1.1


    Connection: keep-alive

    Content-Length: 252

    Accept: */*

    Origin: chrome-extension://hgmloofddffdn

    Authorization: Basic ZmJfaW52aX##########

    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36

    Content-Type: multipart/form-data; boundary=eb451794c9bf426c

    Accept-Encoding: gzip,deflate

    Accept-Language: en-GB,en;q=0.8,en-US;q=0.6,pl;q=0.4


    Content-Disposition: form-data; name=”fileToUpload”; filename=”file.txt”

    line 1 – this is some sample data
    line 2 – this is some sample data



    HTTP/1.1 500 Internal Server Error

    Cache-Control: no-cache

    Pragma: no-cache

    Expires: -1

    Server: Microsoft-IIS/7.5

    X-AspNet-Version: 4.0.30319

    X-Powered-By: ASP.NET

    Date: Thu, 13 Nov 2014 10:34:50 GMT

    Content-Length: 0

  5. @Boris: In my demo you can use Fiddler to catch HTTP request of ‘Form to Upload’ and compare with your one.

    For example, when I upload a raw text file over ‘Form to Upload’ I have this log (Result: File was uploaded with OK code). You can compare the log and find out where is the error of your POST.

    POST http://localhost:4260/api/hdfiles HTTP/1.1
    Host: localhost:4260
    Connection: keep-alive
    Content-Length: 279
    Accept: */*
    Origin: http://localhost:4260
    X-Requested-With: XMLHttpRequest
    User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36
    Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryvAsEq2JyNyvoHVWs
    Referer: http://localhost:4260/FormUpload
    Accept-Encoding: gzip,deflate
    Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4,vi;q=0.2
    Content-Disposition: form-data; name="inputFiles"; filename="BingSiteAuth.xml"
    Content-Type: text/xml
    This is content of raw text file
  6. It’s really weird .
    I’ve tested the request with text file

    POST HTTP/1.1
    Content-Type: multipart/form-data; boundary=-------------------------acebdf13572468
    User-Agent: Fiddler
    Authorization: Basic ZmJfaW52aXRhdG#############
    Content-Length: 337

    Content-Disposition: form-data; name="filename"; filename="test.txt"
    Content-Type: text/plain

    this is a sample text

    But for the same http request , i can have http 500 or http 200 depends on if create the request with the fiddler “parsed tab “or the” raw tab”.

    here are fiddler screenshot:

    i’ll keep you updated. ๐Ÿ˜€

  7. @Boris: It’s weird. I think something wrong happens at Post action. Remove these code rows from Post action and check if error still comes

    if (t.IsFaulted || t.IsCanceled)
    	throw new HttpResponseException(HttpStatusCode.InternalServerError);
  8. Thanks for the tips .
    We have tested without the check of faulted request .
    The http answer is OK , the transfer of the file is still ok but the json array is empty with no informations about the transfer.
    My colleague might find something on the POST . (CRLF issues)

  9. After the WE, it’s working without any modifications ….
    In case of my colleague have added a ” \r\n” (carriage return & new line) after the boundary.(it was missing)

    thanks for your help on this case ๐Ÿ˜€

  10. Thanks for the awesome post, now regarding the created file name on the server, I can access the ID using the i.header but the file name is random, is there a way where I can set the file name to be created or set it the same as the ID.
    Hope to hear from you soon.

  11. hello sir i have error in eclipse after add ACTIVITY_ENTRY_NAME AS library in MainActivity Error: [2015-03-28 10:40:17 – Dex Loader] Unable to execute dex: Multiple dex files define Lcom/hintdesk/core/R$drawable;
    [2015-03-28 10:40:17 – MainActivity] Conversion to Dalvik format failed: Unable to execute dex: Multiple dex files define Lcom/hintdesk/core/R$drawable;
    [2015-03-28 10:42:36 – MainActivity] Dx

  12. ok i will re-import the project in new workspace in eclipse but file uploading filed.. dialog comes.. LogCat gives at :: com.hintdesk.Upload_File_To_ASP_Web_API.infrastructure.IOCApplication.onCreate( at this line RoboGuice.setBaseApplicationInjector(this, RoboGuice.DEFAULT_STAGE, RoboGuice.newDefaultRoboModule(this), new IOCModule());

  13. Hi, I am trying get this work, but I have few problems.
    First: the web api solutions works correctly on my localhost, but just the drag and drop and form functionalities. When I try to run the Android client… the app starts well.. but when i try to upload the selected files… it send me to the second view.. and if I go back, I got the messages “Upload Failed” or something like that.
    pd_ no errors show on Android Studio.
    Second: I try to put it in a free hosting to check “another” alternative and again the drag and drop and form functionalities work well… but this time when I select the files and “select” upload, the app stop working and I am getting this error on Android Studio :

    This is the url of the site :

    I hope you can help me.

  14. @Serdfd:
    The first problem: Debug the server code to check if everything is ok. By the way check the comments in this post too. Anyone may have same problem like yours.

    The second problem: It seems that the JSON result from server is not correct. I suggest you should debug the code locally and see where the problem is.

    Use the debug function!

  15. Hi, I have a question… Iยดm programming on and my Web service is on VB. Can I implement some procedure like this for VB? or this only works in C#?

  16. I didn’t know about the 4mb standard limitation of IIS. you helped me a lot thank you very much ๐Ÿ™‚

  17. Fantastic article and best I’ve read on the net with actual practical examples.

    Many thanks,

  18. Hi Getting error taht “IUploadedFileActivityViewModel” not found. And when I see it is not in the interface folder.Please suggest esle all things are best and upto the mark

  19. i need to submit a form with fields (name, email, address) with attachments to Web API (which sends it off in an email), can you suggest how I can implement this?

Leave a Reply

Your email address will not be published. Required fields are marked *