How to upload a file on a server through api call in asp.net mvc - asp.net

public ActionResult Index(PublishPost post, HttpPostedFileBase file)
{
var apiURL = "http://test.sa.com/rest/social/update/1161/upload?access_token=6fWV564kj3drlu7rATh8="
WebClient webClient = new WebClient();
byte[] responseBinary = webClient.UploadFile(apiUrl, file.FileName);
string response = Encoding.UTF8.GetString(responseBinary);
/* Giving error here. How to proceed?
}
I want to upload a single file to this url and the response is shown in the figure above. How to proceed further with the same in C#? Please help

Try your code like below.
public ActionResult Index(PublishPost post, HttpPostedFileBase file)
{
var apiURL = "http://test.sa.com/rest/social/update/1161/upload?access_token=6fWV564kj3drlu7rATh8="
using (HttpClient client = new HttpClient())
{
using (var content = new MultipartFormDataContent())
{
byte[] fileBytes = new byte[file.InputStream.Length + 1];
file.InputStream.Read(fileBytes, 0, fileBytes.Length);
var fileContent = new ByteArrayContent(fileBytes);
fileContent.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment") { FileName = file.FileName };
content.Add(fileContent);
var result = client.PostAsync(apiURL, content).Result;
if (result.StatusCode == System.Net.HttpStatusCode.OK)
{
return new
{
code = result.StatusCode,
message = "Successful",
data = new
{
success = true,
filename = file.FileName
}
};
}
else
{
return new
{
code = result.StatusCode,
message = "Error"
};
}
}
}
}

Related

Call simple POST API from console App in VS2019 with XML

I have referred the Trying to call simple POST API from console App in VS2019. But, need to pass XML method in post instead of JSON . Any suggestions ?
static async Task Main(string[] args)
{
var TicketTask = await createTicket();
}
async static Task<string> createTicket()
{
var content = "unknown error";
using (var httpClient = new System.Net.Http.HttpClient())
{
using (var request = new System.Net.Http.HttpRequestMessage(new HttpMethod("POST"), "http://1.0.01.1/slive/"))
{
try
{
var base64authorization = Convert.ToBase64String(Encoding.ASCII.GetBytes("username:password"));
request.Headers.TryAddWithoutValidation("Authorization", $"Basic {base64authorization}");
request.Content = new StringContent("<soapenv:Envelope xmlns:xsi...", Encoding.UTF8, "application/xml"); ????? need to post a xml method here
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("text/xml");
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
HttpResponseMessage response = await httpClient.SendAsync(request).ConfigureAwait(false);
content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
Console.WriteLine(response);
}
catch (Exception ex)
{
content = ex.Message;
}
}
}
return content;
Found the solution, please correct me if there is a better way:
async static Task<string> createTicket2()
{
var content = "unknown error";
using (var httpClient = new System.Net.Http.HttpClient())
{
using (var request = new System.Net.Http.HttpRequestMessage(new HttpMethod("POST"), "http://10/sap-lve/"))
{
try
{
var base64authorization = Convert.ToBase64String(Encoding.ASCII.GetBytes("an:s"));
request.Headers.TryAddWithoutValidation("Authorization", $"Basic {base64authorization}");
String str1 = #"<s:Envelope xmlns:s='http://schemas.xmlsoap.org/soap/envelope/'><s:Body><Get_api_version xmlns='http://e.s.a.com'/></s:Body></s:Envelope>";
**request.Content = new StringContent(str1, Encoding.UTF8, "text/xml");** ;
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("text/xml");
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
HttpResponseMessage response = await httpClient.SendAsync(request).ConfigureAwait(false);
content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
//Console.WriteLine(response);
var result = response.Content.ReadAsStringAsync();
Console.WriteLine(result.Result);
}
catch (Exception ex)
{
content = ex.Message;
}
}
}
return content;
}

How to send image file along with other parameter in asp.net?

I want to send image files to SQL Server using C#.
The below code is working and saving files and their paths into the database. I need the same data in my API endpoint's response. I've created a custom response class, called RegistrationResponse.
I'm beginner in this so I'm looking for help.
public async Task<RegistrationResponse> PostFormData(HttpRequestMessage request)
{
object data = "";
NameValueCollection col = HttpContext.Current.Request.Form;
// Check if the request contains multipart/form-data.
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
string root = HttpContext.Current.Server.MapPath("~/images");
var provider = new MultipartFormDataStreamProvider(root);
// Read the form data and return an async task.
var task = Request.Content.ReadAsMultipartAsync(provider).
ContinueWith<HttpResponseMessage>(t =>
{
if (t.IsFaulted || t.IsCanceled)
{
Request.CreateErrorResponse(HttpStatusCode.InternalServerError, t.Exception);
}
//read file data
foreach (MultipartFileData dataItem in provider.FileData)
{
try
{
string description = string.Empty;
string userId = string.Empty;
String fileName = string.Empty;
// Show all the key-value pairs.
foreach (var key in provider.FormData.AllKeys)
{
foreach (var val in provider.FormData.GetValues(key))
{
if (key.ToString().ToLower() == "userid")
{
userId = val;
}
else if (key.ToString().ToLower() == "description")
{
description = val;
}
}
}
String name = dataItem.Headers.ContentDisposition.FileName.Replace("\"", "");
fileName = userId + Path.GetExtension(name);
File.Move(dataItem.LocalFileName, Path.Combine(root, fileName));
using (var db = new AlumniDBEntities())
{
//saving path and data in database table
Post userPost = new Post();
userPost.Files = fileName;
userPost.Description = description;
userPost.UserID = Convert.ToInt32(userId);
userPost.CreatedDate = DateTime.Now;
db.Posts.Add(userPost);
db.SaveChanges();
data = db.Posts.Where(x => x.PostID ==
userPost.PostID).FirstOrDefault();
string output = JsonConvert.SerializeObject(data);
}
}
catch (Exception ex)
{
return Request.CreateResponse(ex);
}
}
return Request.CreateResponse(HttpStatusCode.Created);
});
var response = new RegistrationResponse
{
success = true,
status = HttpStatusCode.OK,
message = "Success",
data = data
};
return response;
}

ASP.NET WEB API cant upload multipart/form-data (image) to Web server

After uploading image through ASP.NET WEB API successfuly through localhost . I uploaded my project to the hosting server but this time i got the error as
an error has occured
This is my controller
tutorEntities entities = new tutorEntities();
[HttpPost]
public HttpResponseMessage ImageUp()
{
var httpContext = (HttpContextWrapper)Request.Properties["MS_HttpContext"];
img std = new img();
// std.Title = httpContext.Request.Form["Title"];
// std.RollNo = httpContext.Request.Form["RollNo"];
// std.Semester = httpContext.Request.Form["Semester"];
HttpResponseMessage response = new HttpResponseMessage();
var httpRequest = HttpContext.Current.Request;
if (httpRequest.Files.Count > 0)
{
string random = Guid.NewGuid().ToString();
string url = "/UserImage/" + random + httpRequest.Files[0].FileName.Substring(httpRequest.Files[0].FileName.LastIndexOf('.'));
Console.WriteLine(url);
string path = System.Web.Hosting.HostingEnvironment.MapPath(url);
httpRequest.Files[0].SaveAs(path);
std.Path = "http://localhost:2541/" + url;
}
entities.imgs.Add(std);
entities.SaveChanges();
return Request.CreateResponse(HttpStatusCode.OK);
}
Ensure that AppPoolIdentity user has write permissions on the UserImage folder. Also, catch the exception in code for debugging:
try {
var httpContext = (HttpContextWrapper)Request.Properties["MS_HttpContext"];
img std = new img();
// std.Title = httpContext.Request.Form["Title"];
// std.RollNo = httpContext.Request.Form["RollNo"];
// std.Semester = httpContext.Request.Form["Semester"];
HttpResponseMessage response = new HttpResponseMessage();
var httpRequest = HttpContext.Current.Request;
if (httpRequest.Files.Count > 0)
{
string random = Guid.NewGuid().ToString();
string url = "/UserImage/" + random + httpRequest.Files[0].FileName.Substring(httpRequest.Files[0].FileName.LastIndexOf('.'));
Console.WriteLine(url);
string path = System.Web.Hosting.HostingEnvironment.MapPath(url);
httpRequest.Files[0].SaveAs(path);
std.Path = "http://localhost:2541/" + url;
}
entities.imgs.Add(std);
entities.SaveChanges();
return Request.CreateResponse(HttpStatusCode.OK);
}
catch(Exception ex) {
var response = new HttpResponseMessage(HttpStatusCode.InternalServerError)
{
Content = new StringContent(ex.ToString()),
ReasonPhrase = "Error"
}
throw new HttpResponseException(response);
}

Parameter has all propertys after webrequest

I have a really simple ASP.NET Api Controller with one method.
public HttpResponseMessage<User> Post(User user)
{
return new HttpResponseMessage<User>(new User() { Name = "New User at Server" });
}
My debugger says that the method is called but the problem is that the parameter "user" has all its content set to null; I am using Fiddler to look at request and response.. and all looks good.
This is my service code in the client.
public void AddUser(Models.User user, Action<Models.User> ShowResult)
{
var uiThreadScheduler = TaskScheduler.FromCurrentSynchronizationContext();
string url = "http://localhost:4921/User";
Uri uri = new Uri(url, UriKind.Absolute);
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
var sendWebPost = Task.Factory.FromAsync<Stream>(request.BeginGetRequestStream, request.EndGetRequestStream, null)
.ContinueWith(task =>
{
Tuple<string, string>[] stringToSend = { Tuple.Create<string, string>("user", ObjectToJson<Models.User>(user)) };
var bytesToSend = GetRequestBytes(stringToSend);
using (var stream = task.Result)
stream.Write(bytesToSend, 0, bytesToSend.Length);
}
).ContinueWith(task =>
{
Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null)
.ContinueWith<WebResponse>(task2 => { ValidateResponse(task2); return task2.Result; })
.ContinueWith<Models.User>(task3 => {return JsonToObject<Models.User>(task3);})
.ContinueWith(task4 => { TryClearWorking(); ShowResult(task4.Result); }, uiThreadScheduler);
});;
}
public static string ObjectToJson<T>(T obj) where T : class
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
MemoryStream stream = new MemoryStream();
StreamReader sr = new StreamReader(stream);
serializer.WriteObject(stream, obj);
sr.BaseStream.Position = 0;
string jsonString = sr.ReadToEnd();
return jsonString;
}
protected static byte[] GetRequestBytes(Tuple<string, string>[] postParameters)
{
if (postParameters == null || postParameters.Length == 0)
return new byte[0];
var sb = new StringBuilder();
foreach (var key in postParameters)
sb.Append(key.Item1 + "=" + key.Item2 + "&");
sb.Length = sb.Length - 1;
return Encoding.UTF8.GetBytes(sb.ToString());
}
Anyone who can give me some ideas where to start to look for errors.....
You need to set the Content-Length header.

ASP .Net Web API downloading images as binary

I want to try to use Web API make a rest call but I want the response to be the actual binary image stored in a database, not a JSON base64 encoded string. Anyone got some pointers on this?
Update-
This is what I ended up implementing:
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
result.Content = new StreamContent(new MemoryStream(profile.Avatar));
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
result.Content.Headers.ContentDisposition.FileName = "avatar.png";
return result;
You can set the response content to a StreamContent object:
var fileStream = new FileStream(path, FileMode.Open);
var resp = new HttpResponseMessage()
{
Content = new StreamContent(fileStream)
};
// Find the MIME type
string mimeType = _extensions[Path.GetExtension(path)];
resp.Content.Headers.ContentType = new MediaTypeHeaderValue(mimeType);
While this has been marked as answered, it wasn't quite what I wanted, so I kept looking. Now that I've figured it out, here's what I've got:
public FileContentResult GetFile(string id)
{
byte[] fileContents;
using (MemoryStream memoryStream = new MemoryStream())
{
using (Bitmap image = new Bitmap(WebRequest.Create(myURL).GetResponse().GetResponseStream()))
image.Save(memoryStream, ImageFormat.Jpeg);
fileContents = memoryStream.ToArray();
}
return new FileContentResult(fileContents, "image/jpg");
}
Granted, that's for getting an image through a URL. If you just want to grab an image off the file server, I'd imagine you replace this line:
using (Bitmap image = new Bitmap(WebRequest.Create(myURL).GetResponse().GetResponseStream()))
With this:
using (Bitmap image = new Bitmap(myFilePath))
EDIT: Never mind, this is for regular MVC. for Web API, I have this:
public HttpResponseMessage Get(string id)
{
string fileName = string.Format("{0}.jpg", id);
if (!FileProvider.Exists(fileName))
throw new HttpResponseException(HttpStatusCode.NotFound);
FileStream fileStream = FileProvider.Open(fileName);
HttpResponseMessage response = new HttpResponseMessage { Content = new StreamContent(fileStream) };
response.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpg");
response.Content.Headers.ContentLength = FileProvider.GetLength(fileName);
return response;
}
Which is quite similar to what OP has.
I did this exact thing. Here is my code:
if (!String.IsNullOrWhiteSpace(imageName))
{
var savedFileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Path.Combine(uploadPath, imageName));
var image = System.Drawing.Image.FromFile(savedFileName);
if (ImageFormat.Jpeg.Equals(image.RawFormat))
{
// JPEG
using(var memoryStream = new MemoryStream())
{
image.Save(memoryStream, ImageFormat.Jpeg);
var result = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ByteArrayContent(memoryStream.ToArray())
};
result.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
result.Content.Headers.ContentLength = memoryStream.Length;
return result;
}
}
else if (ImageFormat.Png.Equals(image.RawFormat))
{
// PNG
using (var memoryStream = new MemoryStream())
{
image.Save(memoryStream, ImageFormat.Png);
var result = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ByteArrayContent(memoryStream.ToArray())
};
result.Content.Headers.ContentType = new MediaTypeHeaderValue("image/png");
result.Content.Headers.ContentLength = memoryStream.Length;
return result;
}
}
else if (ImageFormat.Gif.Equals(image.RawFormat))
{
// GIF
using (var memoryStream = new MemoryStream())
{
image.Save(memoryStream, ImageFormat.Gif);
var result = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ByteArrayContent(memoryStream.ToArray())
};
result.Content.Headers.ContentType = new MediaTypeHeaderValue("image/gif");
result.Content.Headers.ContentLength = memoryStream.Length;
return result;
}
}
}
And then on the client:
var client = new HttpClient();
var imageName = product.ImageUrl.Replace("~/Uploads/", "");
var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
Properties.Settings.Default.DeviceMediaPath + "\\" + imageName);
var response =
client.GetAsync(apiUrl + "/Image?apiLoginId=" + apiLoginId + "&authorizationToken=" + authToken +
"&imageName=" + product.ImageUrl.Replace("~/Uploads/","")).Result;
if (response.IsSuccessStatusCode)
{
var data = response.Content.ReadAsByteArrayAsync().Result;
using (var ms = new MemoryStream(data))
{
using (var fs = File.Create(path))
{
ms.CopyTo(fs);
}
}
result = true;
}
else
{
result = false;
break;
}
This task is much easily achieved without using WebAPI. I would implement a custom HTTP handler for a unique extension, and return the binary response there. The plus is that you can also modify the HTTP Response headers and content type, so you have absolute control over what is returned.
You can devise a URL pattern (defining how you know what image to return based on its URL), and keep those URLs in your API resources. Once the URL is returned in the API response, it can be directly requested by the browser, and will reach your HTTP handler, returning the correct image.
Images are static content and have their own role in HTTP and HTML - no need to mix them with the JSON that is used when working with an API.

Resources