How to send image file along with other parameter in asp.net? - 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;
}

Related

Sftp upload from memory stream asp.net

I am trying to upload a csv file that is created from a query and upload via sftp.
I am trying to avoid creating a file and then reading the file to upload it by keeping the data in memory.
Thanks in advance
var customerAddresses = addresses.Select(p => new { p.Customer.Name, p.Customer.AlternateName, p.City, p.StateProvince });
using (var memoryStream = new MemoryStream())
{
//if you pass a file path to streamWriter it creates a csv with the correct format and data
using (var streamWriter = new StreamWriter())
{
using (var csv = new CsvWriter(streamWriter))
{
csv.WriteRecords(customerAddresses);
var fileName = DateTime.UtcNow.ToString(dateFromat) + destinationFileName;
var privateKey = new PrivateKeyFile(sshKeyLocation);
var connectionInfo = new PrivateKeyConnectionInfo(address,
username,
new PrivateKeyFile(sshKeyLocation)
);
memoryStream.Flush();
using (var client = new SftpClient(connectionInfo))
{
client.Connect();
client.ChangeDirectory(serverDirectory);
client.UploadFile(memoryStream, fileName); //is always an empty file
}
}
}
Try adding setting memoryStream Position to beginning with Seek before calling UploadFile and calling streamWriter.Flush();, not memoryStream.Flush():
streamWriter.Flush();
memoryStream.Seek(0, SeekOrigin.Begin);
using (var client = new SftpClient(connectionInfo))
{
client.Connect();
client.ChangeDirectory(serverDirectory);
client.UploadFile(memoryStream, fileName);
}
I never figured out how to get it to work with MemoryStream and changed to to write a file and then read and upload that file.
public HttpResponseMessage Post([FromBody] CustomerIds[] CustomerIds)
{
try
{
if(CustomerIds.Length == 0)
{
throw new Exception("No customer ids passed in post body.");
}
else if (!File.Exists(sshKeyLocation))
{
throw new Exception("Missing ssh file.");
}
if(!Directory.Exists(localDirectory))
{
Directory.CreateDirectory(localDirectory);
}
var customerAddresses = _repository.GetPrimaryAddress(CustomerIds.Select(c => c.Id))
.Select(p => new
{
p.Customer.Name,
p.Customer.AlternateName,
p.City,
p.StateProvince
}
);
if (customerAddresses == null || !customerAddresses.Any())
{
throw new Exception("No customer addresses found for selected customers.");
}
var fileName = DateTime.UtcNow.ToString(dateFromat) + destinationFileName;
var localFilePath = Path.Combine(localDirectory, fileName);
CreateFile(customerAddresses, localFilePath);
UploadFile(localFilePath, fileName);
return new HttpResponseMessage(System.Net.HttpStatusCode.OK);
}
catch(Exception error)
{
logger.Error(error, error.Message);
throw error;
}
}
private void CreateFile(IEnumerable<object> customerAddresses, string filePath)
{
using (TextWriter streamWriter = new StreamWriter(filePath))
using (var csv = new CsvWriter(streamWriter))
{
csv.WriteRecords(customerAddresses);
}
}
private void UploadFile(string localFilePath, string destinationFileName)
{
var connectionInfo = new PrivateKeyConnectionInfo(address,
username,
new PrivateKeyFile(sshKeyLocation)
);
using (var fileStream = new FileStream(localFilePath, FileMode.Open))
using (var client = new SftpClient(connectionInfo))
{
client.Connect();
client.ChangeDirectory(serverDirectory);
client.UploadFile(fileStream, destinationFileName);
}
}
I've run out of time to continue trying to upload using the MemoryStream and will just have to use this solution. Disappointed I couldn't get it to work.

How to use Tempdata to display the list

I have did the excel upload in dotnet core .I had to use tempdata to retrieve the details of the excel in list.Instead in my below code i had used Static object to retrieve the list.My code works as like this ,when i click on upload button it will display the details in the excel sheet.and when click on save it will save it to database and i need to edit in grid view using ajax call also .Help me out
My Action in controller is
public async Task<IActionResult> ImportEmployeeDetails(IFormFile excelfile)
{
try
{
EmployeesViewModelList employeesListObject = new EmployeesViewModelList();
List<EmployeeModel> employeesViewModelList = new List<EmployeeModel>();
if (excelfile == null || excelfile.Length == 0)
{
return View(employeesListObject);
}
var supportedTypes = new[] { ".xls", ".xlsx" };
var ext = Path.GetExtension(excelfile.FileName);
if (!supportedTypes.Contains(ext))
{
return View(employeesListObject);
}
var path = Path.Combine(
Directory.GetCurrentDirectory(), "wwwroot",
"EmployeeDetails.xlsx");
if (System.IO.File.Exists(path))
{
System.IO.File.Delete(path);
}
using (var stream = new FileStream(path, FileMode.Create))
{
await excelfile.CopyToAsync(stream);
}
FileInfo file = new FileInfo(path);
using (ExcelPackage package = new ExcelPackage(file))
{
ExcelWorksheet worksheet = package.Workbook.Worksheets[1];
int rowCount = worksheet.Dimension.Rows;
int ColCount = worksheet.Dimension.Columns;
for (int i = 2; i <= rowCount; i++)
{
EmployeeModel emp = new EmployeeModel();
emp.EmployeeId = Convert.ToInt32(worksheet.Cells[i, 1].Value.ToString());
emp.EmpFirstName = worksheet.Cells[i, 2].Value.ToString();
employeesViewModelList.Add(emp);
}
employeesListObject.EmpModelList = employeesViewModelList;
return View(employeesListObject);
}
}
catch(Exception ex)
{
TempData["Message"] = "Opps! Something Went wrong!";
return RedirectToAction("ExcelPackage");
}
}
Try this, using your own list.
List<string> SomeList = new List<string>();
TempData["MyList"] = SomeList;
//then to get data just do
SomeList = TempData["MyList"] as List<string>; //This converts back to List<T>
Once you add the list to the TempData, you can retrive it from any Action or View in the same controller

Internal Server Error 500 on async upload asp mvc 5

Just started using ASP.Net 4.5 and my API always returns Internal Server Error.
Upload API
public class UploadController : ApiController
{
public async Task<HttpResponseMessage> PostFile()
{
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
string root = HttpContext.Current.Server.MapPath("~/App_Data/uploads/");
var provider = new CustomMultipartFormDataStreamProvider(root);
try
{
await Request.Content.ReadAsMultipartAsync(provider);
return Request.CreateResponse(HttpStatusCode.OK);
}
catch (System.Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
}
}
}
My Controller
var message = new HttpRequestMessage();
var content = new MultipartFormDataContent();
message.Method = HttpMethod.Post;
message.Content = content;
message.RequestUri = new Uri("http://localhost:12345/api/upload/");
var client = new HttpClient();
client.SendAsync(message).ContinueWith(task =>
{
var result = task.Result.ReasonPhrase;
if (task.Result.IsSuccessStatusCode)
{
//do something
}
});
The files are saved in the location (/App_Data/uploads/) but why is the status code always 500?
Please enlighten me. Thanks
Here is part of working controller:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create(Product product, HttpPostedFileBase file)
{
if (!ModelState.IsValid)
return PartialView("Create", product);
if (file != null)
{
var fileName = Path.GetFileName(file.FileName);
var guid = Guid.NewGuid().ToString();
var path = Path.Combine(Server.MapPath("~/Content/Uploads/ProductImages"), guid + fileName);
file.SaveAs(path);
string fl = path.Substring(path.LastIndexOf("\\"));
string[] split = fl.Split('\\');
string newpath = split[1];
string imagepath = "Content/Uploads/ProductImages/" + newpath;
using (MemoryStream ms = new MemoryStream())
{
file.InputStream.CopyTo(ms);
byte[] array = ms.GetBuffer();
}
var nId = Guid.NewGuid().ToString();
// Save record to database
product.Id = nId;
product.State = 1;
product.ImagePath = imagepath;
product.CreatedAt = DateTime.Now;
db.Products.Add(product);
await db.SaveChangesAsync();
TempData["message"] = "ProductCreated";
//return RedirectToAction("Index", product);
}
// after successfully uploading redirect the user
return Json(new { success = true });
}

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

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"
};
}
}
}
}

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.

Resources