Cant Post a Upload Image with IHttpActionResult - c#

i have try with postman in my local server to route the API
this is my code
[HttpPost]
[Route("photo")]
public IHttpActionResult Upload()
{
// LOCAL VARIABLE
int ErrCode = 1;
dynamic ExpObj = new ExpandoObject();
string FilePath = HttpContext.Current.Server.MapPath("/Img");
// GET SID & DECRYPTING OBJEK TO JSON OBJ
var HttpRequest = HttpContext.Current.Request;
string SID = GetSID(this.Request.Headers);
dynamic objek = GetobjekuMultipart(SID, HttpRequest.Form["objek"]);
// EXTRACT OBJEK
string UserID = objek.userID;
if (HttpRequest.Files.Count > 0)
{
// GET UPLOADED IMAGE
var PostedFile = HttpRequest.Files["image"];
// SET FILE NAME ( USERID + Right(FileName,10) )
string FileName = GetFileName(UserID, PostedFile.FileName, 10);
// SAVE IMAGE
string ImagePath = Path.Combine(FilePath, FileName);
PostedFile.SaveAs(ImagePath);
ExpObj.imageURL = ServerUrl + ServerPath + FileName;
}
else
{
ErrCode = -900;
}
// RETURN IF GOT ERROR
if (ErrCode < 0)
{
return StatusCode((HttpStatusCode)(ErrCode * (-1)));
}
// SERIALIZING & ENCRYPTING
string SerializedObj = JsonConvert.SerializeObject(ExpObj, JsonSetting);
string EncryptedReturn = Encrypt(SerializedObj, SID);
// RETURN
return Ok(EncryptedReturn);
}
and this is my public method (General Method)
public string Decrypt(string cipherText, string sid)
{
RNCryptor.Decryptor D = new Decryptor();
string DecryptedString = "";
if (Prod == true)
{
try
{
DecryptedString = D.Decrypt(cipherText, sid + SigningKey);
}
catch (Exception ex)
{
int ErrCode = -902; // Error in Decrypt
throw new HttpResponseException((HttpStatusCode)(ErrCode * (-1)));
}
}
else
{
DecryptedString = cipherText;
}
return DecryptedString.Trim();
}
public dynamic GetObjekMultipart(string sid, string Objek)
{
string StrObjek = Decrypt(Objek, sid);
return JsonConvert.DeserializeObject<dynamic>(StrObjek);
}
public string GetFileName(string UserID, string fileName, int length)
{
string FileName;
string FileFormat;
// GET FILE FORMAT
string[] Words = fileName.Split('.');
FileFormat = "." + Words[Words.Length - 1];
// GET FILE NAME WITHOUT THE FILE FORMAT
FileName = fileName.Substring(0, fileName.Length - FileFormat.Length);
// SET THE FILE NAME
FileName = UserID + "-" + GetRight(FileName, length) + FileFormat;
return FileName;
}
and POSTMAN Result is "Object reference not set to an instance of an object"
the result said that the httprequest.form is NULL
please help :(

Related

How to encode QR with TLV values in C#

I have this code in C# which use it to generate a QR code base64 and want to decode the output into original TLV values as strings, for example in my code I am generating the QR code encode base64 and want to get back with original TLVs tags and store it in separate string per each value
using System;
namespace tlvgenerator
{
class Program
{
static void Main(string[] args)
{
string Name = GetHexString(1, Encoding.UTF8.GetBytes("Name")); //Tag1
string Serial = GetHexString(2, Encoding.UTF8.GetBytes("123456789123456789")); //Tag2
string dateTimeStr = GetHexString(3, Encoding.UTF8.GetBytes("2022-07-17T11:20:51Z")); //Tag3
string ModelNum = GetHexString(4, Encoding.UTF8.GetBytes("12356.123")); //Tag4
string PartNo = GetHexString(5, Encoding.UTF8.GetBytes("9782.45")); //Tag5
string SN = GetHexString(6, Encoding.UTF8.GetBytes("abcdef12345"));//Tag6
string Shelf = GetHexString(7, Encoding.UTF8.GetBytes("A2F345"));//Tag6
string Area = GetHexString(8, Convert.FromBase64String(Area)); //Tag7
string Building = GetHexString(9, Convert.FromBase64String(Building)); //Tag8
string decString = Name + Serial + dateTimeStr + ModelNum + PartNo + SN + Shelf + Area + Building;
string finalQR = HexToBase64(decString);
Console.WriteLine(finalQR);
}
static string GetHexString(int tagNo, byte[] tagValue)
{
string strTagNo = string.Format("0{0:X}", tagNo);
string tagNoVal = strTagNo.Substring(strTagNo.Length - 2, 2);
string strTagValueLength = string.Format("0{0:X}", tagValue.Length);
string tagValueLengthVal = strTagValueLength.Substring(strTagValueLength.Length - 2, 2);
return tagNoVal + tagValueLengthVal + BitConverter.ToString(tagValue).Replace("-", "");
}
static string gethexDec(Int32 TagValue)
{
string hxint = String.Format("0{0:X}", TagValue);
return hxint.Substring(hxint.Length - 2, 2);
}
public static string HexToBase64(string strInput)
{
try
{
var bytes = new byte[strInput.Length / 2];
for (var i = 0; i < bytes.Length; i++)
{
bytes[i] = Convert.ToByte(strInput.Substring(i * 2, 2), 16);
}
return Convert.ToBase64String(bytes);
}
catch (Exception)
{
return "-1";
}
}
}
}

How to check if the filename already exists

I need little help to modify my function. How can I check if the file already exists with the same name? and if it does then to add a newguid string to the name and save the new file.
public string UploadStorageFile(StorageModel newFile, int userId)
{
string uniqueFileName = null;
if(newFile.FileName != null)
{
string uploadsFolder = Path.Combine(_webHostEnvironment.WebRootPath, $"repositories/{userId}");
if (!Directory.Exists(uploadsFolder))
{
Directory.CreateDirectory(uploadsFolder);
}
uniqueFileName = Guid.NewGuid().ToString() + "_" + newFile.FileName.FileName;
string filePath = Path.Combine(uploadsFolder, uniqueFileName);
using(var fileStream = new FileStream(filePath, FileMode.Create))
{
newFile.FileName.CopyTo(fileStream);
}
}
return uniqueFileName;
}
For Checking, if a File already exists, you can use the File.Exists() method.
Here is a basic example, on how to check if a File does already exist:
public bool DoesFileAlreadyExist(string uploadFolder, string fileName)
{
var file = $"{uploadFolder}\{fileName}";
return File.Exists(file);
}
Specific on your Code, you could use the method like in this example (Just call the method, and check if it is existing):
public string UploadStorageFile(StorageModel newFile, int userId)
{
string uniqueFileName = null;
if(newFile.FileName != null)
{
string uploadsFolder = Path.Combine(_webHostEnvironment.WebRootPath, $"repositories/{userId}");
if (!Directory.Exists(uploadsFolder))
{
Directory.CreateDirectory(uploadsFolder);
}
if (!DoesFileAlreadyExist(uploadsFolder, newFile.Filename)
{
uniqueFileName = Guid.NewGuid().ToString() + "_" + newFile.FileName.FileName;
string filePath = Path.Combine(uploadsFolder, uniqueFileName);
using(var fileStream = new FileStream(filePath, FileMode.Create))
{
newFile.FileName.CopyTo(fileStream);
}
}
return uniqueFileName;
}
return "NO FILE CREATED";
}

What is the best way to create multiple xml files and export it as one zip file

My Project is in ASP.NET MVC, Right now I am using Razor Engine Service (RazorEngineService.RunCompile) to create multiple XML files and making it as a single Zip file and exporting it.
But the problem is that when we pass the model object each time to process the template and return it as separate XML files and completing the whole operation it takes more time to complete (Almost ~40 Seconds for 10 objects) for whole content to export.
Is there anything wrong with my current approach or am I doing it correctly right now? Please guide me If I am doing any mistakes in this approach.
private FileInfo Export(List<Model> modelList)
{
string timeStr = Datetime.Now.ToString();
string archiveFileName = "Main.zip";
string archivePath = Path.Combine(_reportFolderPath, archiveFileName);
using (ZipArchive archive = ZipFile.Open(archivePath, ZipArchiveMode.Create))
{
foreach (var list in modelList)
{
string fileName = model.name + model.Id;
string filePath = GetModelExport(list, fileName, timeStr);
archive.CreateEntryFromFile(filePath, fileName + ".xml");
}
archive.Dispose();
}
return new FileInfo(archivePath);
}
private string GetModelExport(Model model, string fileName, string timeStr)
{
var processedTemplate = ProcessTemplate(model, TemplateName, TemplateKey);
string reportFilelName = fileName + "_" + timeStr + ".xml";
string filePath = Path.Combine(_reportFolderPath, reportFilelName);
using (var file = new StreamWriter(filePath))
{
file.Write(processedTemplate);
}
return filePath;
}
private string ProcessTemplate(Model model, string templateName, string templateKey)
{
var templateFilePath = Path.Combine(_reportTemplateFolder, templateName);
return ReportUtils.ProcessTemplate(templateFilePath, templateKey, model);
}
public static string ProcessTemplate(string templatePath, string templateKey, object model = null)
{
var templateService = RazorEngineService.Create();
var result = templateService.RunCompile(File.ReadAllText(templatePath), templateKey, null, model);
return result;
}
some of your code is missing so i cant see the whole picture, this is what i would start with..... gd luck.
public class HolderTempName
{
private TemplateService _templateService;
private Dictionary<string, string> _templateContainer;
public HolderTempName()
{
//this will save creating this everytime
_templateService = RazorEngineService.Create();
//this will hold the template so it does not have to fetch on each loop,
//if the same template is used.
_templateContainer = new Dictionary<string, string>();
}
//you will need to tweeek this to get the type out
private string GetTemplate(string templateName, templatePath)
{
if(!_templateContainer.Conatains(templateName))
{
var text = File.ReadAllText(templatePath);
_templateContainer[templateName] = text;
}
return _templateContainer[templateName];
}
private FileInfo Export(List<Model> modelList)
{
string timeStr = Datetime.Now;
string archiveFileName = "Main.zip";
string archivePath = Path.Combine(_reportFolderPath, archiveFileName);
using (ZipArchive archive = ZipFile.Open(archivePath, ZipArchiveMode.Create))
{
foreach (var item in modelList)
{
var templateFilePath = Path.Combine(_reportTemplateFolder, TemplateName); //<--TemplateName seems like a local private
//these should come from where cant see where...
var template = GetTemplate( TemplateName, templateFilePath)
string modelResponse = ProcessModel(item,template,TemplateKey ); //<-- why is not passing in the template
//step 2;
//making this above done in parrell and then add aync, but before all that measure what is taking time
string pathname = MakeFileName(_reportFolderPath, reportFilelName, timeStr);
SaveToDisk(pathname, modelResponse);
string fileName = model.name + model.Id;
archive.CreateEntryFromFile(filePath, fileName + ".xml");
}
archive.Dispose();
}
return new FileInfo(archivePath);
}
private string MakeFileName(string path ,string filename, string tStamp)
{
string reportFilelName = fileName + "_" + timeStr + ".xml";
string filePath = Path.Combine(_reportFolderPath, reportFilelName);
return filePath;
}
private void SaveToDisk(string filePath, string content)
{
using (var file = new StreamWriter(filePath))
{
file.Write(processedTemplate);
}
}
public static string ProcessTemplate(object model, string template, templateKey)
{
var result = templateService.RunCompile(template, templateKey, null, model);
return result;
}
}

How can i download a text file from the server folder not inside project solution

I want to download the textfile on button click from Kendo grid rows. I got an Id of selected row and pass it to my
controller and now it doesnt download the file as it is showing the error below. Thou the error seems to be fixed
Failed to load resource: net::ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION
The file naming is like this : e669a7e7-7eb2-4cfa-b950-3b79ed621a57
public ActionResult DownloadIndex(int id)
{
try
{
string Filelocation = "MyServerLocationFolder";
OnePossModel md = new Models.OnePossModel();
JsonParamBuilder myBuilder = new JsonParamBuilder();
myBuilder.AddParam<Guid>("userid", System.Guid.Parse(User.Identity.GetUserId()));
myBuilder.AddParam<int>("id", Convert.ToInt32(id));
string jsonReq = Models.JsonWrapper.JsonPOST(ApiBaseUrl + "/WriteFile", myBuilder.GetJSonParam());
string poassFilename = Models.DeserialiseFromJson<string>.DeserialiseApiResponse(jsonReq);
string filepath = Filelocation + poassFilename.ToString();
byte[] filedata = System.IO.File.ReadAllBytes(filepath);
string contentType = MimeMapping.GetMimeMapping(filepath);
var cd = new System.Net.Mime.ContentDisposition
{
FileName = poassFilename,
Inline = true,
};
Response.AddHeader("Content-Disposition", "attachment;filename=\"" + poassFilename + "\"");
return File(filedata, "application/txt", Server.UrlEncode(poassFilename));
}
catch (Exception ex)
{
throw ex;
}
}
Use "text/plain" instead of "application/txt":
public ActionResult DownloadIndex(int id)
{
try
{
string Filelocation = "MyServerLocationFolder";
OnePossModel md = new Models.OnePossModel();
JsonParamBuilder myBuilder = new JsonParamBuilder();
myBuilder.AddParam<Guid>("userid", System.Guid.Parse(User.Identity.GetUserId()));
myBuilder.AddParam<int>("id", Convert.ToInt32(id));
string jsonReq = Models.JsonWrapper.JsonPOST(ApiBaseUrl + "/WriteFile", myBuilder.GetJSonParam());
string poassFilename = Models.DeserialiseFromJson<string>.DeserialiseApiResponse(jsonReq);
string filepath = Filelocation + poassFilename.ToString();
byte[] filedata = System.IO.File.ReadAllBytes(filepath);
return File(filedata, "text/plain", Server.UrlEncode(poassFilename));
}
catch (Exception ex)
{
throw ex;
}
}

C# fail to create file in directory if has other file

Can someone help me, I just learning C# for about 2 month, I have this problem,
i'm building a class for filter data from temp file and create the result in new txt file inside directory, if directory is empty nor at the same date, it build perfectly, and if there another file at same date it should create with increase the last number at lastname.
My problem when I run code, it is not creating if the directory has files with the same dates, then the result should be something like this:
C:\result_2014051301.txt
C:\result_2014051401.txt
C:\result_2014051402.txt <-- Failed, it is not ..2014051401.txt
class Entity2
{
public Entity2()
{
string fileTemp = "DEFAULT.temp";
string indexD = Properties.Settings.Default.ChIndex2D;
string indexC = Properties.Settings.Default.ChIndex2C;
string indexS = Properties.Settings.Default.ChIndex2S;
string tempPath = AppDomain.CurrentDomain.BaseDirectory;
string targetPath = Properties.Settings.Default.ExtractALL_DIR;
string SourceFile = Path.Combine(tempPath, fileTemp);
string tempFileX = Path.GetTempFileName();
if (!System.IO.Directory.Exists(targetPath))
{
System.Windows.Forms.MessageBox.Show("Error missing .temp", "Message Box");
}
else
{
string ext = ".txt";
int sequence = 0;
DateTime dateFileName = DateTime.Today;
string discode = Properties.Settings.Default.ChannelID_2;
string filename = discode + "_" + dateFileName.ToString("yyyyMMdd");
string pathX = Properties.Settings.Default.ExtractALL_DIR + #"/Channel2";
if (!Directory.Exists(pathX))
{
Directory.CreateDirectory(pathX);
}
string[] files = Directory.GetFiles(pathX, filename + "*.txt", SearchOption.TopDirectoryOnly);
if (files.Length > 0)
{
Array.Sort(files);
string lastFilename = files[files.Length - 1];
sequence = Int32.Parse(lastFilename.Substring(0, lastFilename.Length - 4).Replace(pathX + filename, ""));
}
sequence++;
string newFileName = filename + sequence.ToString().PadLeft(2, '0') + ext;
string DestFile = Path.Combine(pathX, newFileName);
using (var ab = new StreamReader(SourceFile))
using (var cd = new StreamWriter(DestFile))
{
string lineX;
while ((lineX = ab.ReadLine()) != null)
{
if (lineX.LastIndexOf("100", 3) != -1 || lineX.LastIndexOf("MGR", 15) != -1 || lineX.LastIndexOf(indexC, 15) != -1)
{
lineX = lineX.Replace(indexD, "");
lineX = lineX.Replace("DEFAULT", discode);
if (lineX.LastIndexOf("800", 3) != -1)
{
lineX = lineX.Replace(indexS, "");
}
cd.WriteLine(lineX);
}
}
}
}
}
}
This piece is not functioning correctly:
Int32.Parse(lastFilename.Substring(0, lastFilename.Length - 4).Replace(pathX + filename, ""));
pathX + filename is C:\folderfile.txt not C:\folder\file.txt.
You either need to add the \ or call Path.Join.
That will cause the Parse operation to fail since it tries to consume the who string (minus the extension).

Categories