MVC4 exception when saving HttpPostedFileBase for the second time - image

in my ASP.NET MVC4 project I need a way to upload a picture that gets saved to a folder on the server. I came up with the controller code below: it basically works, but only for the first time! When calling this method again (with the same TeacherId to set a new image), I get a System.IO.IOException (HResult -2147024864) that tells me, that the file is in use by another process. How can I avoid the locking? And why does it actually work in the first place? I tidy up all images and streams, but it seams I'm somehow missing something important. Thanks you for your help!
[HttpPost]
public ActionResult Upload(HttpPostedFileBase pic, int TeacherId)
{
if (pic.ContentLength > 0) {
var fileName = "Teacher" + TeacherId.ToString() + "tmp.jpg";
var path = Path.Combine(Server.MapPath("~/TempImages"), fileName);
Image i = Image.FromStream(pic.InputStream, true, true);
if (i.Size.Width > 700 || i.Height > 700)
{
Image resizedImage;
resizedImage = ResizeImage(i, new Size { Width = 700, Height = 700 }, true);
i.Dispose();
resizedImage.Save(path,ImageFormat.Jpeg);
resizedImage.Dispose();
}
else
{
i.Dispose();
}
pic.InputStream.Close();
pic.InputStream.Dispose();
TempData["TeacherId"] = TeacherId.ToString();
return RedirectToAction("EditImage", new { TeacherId = TeacherId });
}
return RedirectToAction("UploadImage", new { TeacherId = TeacherId });
}

Related

Rotativa BuildFile not hitting the Action Method

I have two action methods in my Controller class:
DetailsAll: to get some data and display in the view
SaveAsPDF: Called on windows.load of DetailsAll.cshtml which should save DetailsAll view as pdf
My issue is in SaveAsPDF Action method. Here I am trying to use Rotativa ActionAsPdf and subsequently BuildFile methods to generate and save the PDF. However, when executing the line "BuildFile", it is not hitting the breakpoint in my DetailsAll Action method, subsequently causing the PDF to be generated blank.
Could you please help where I am going wrong?
[HttpGet]
public ActionResult DetailsAll()
{
var selectionBuilder = builderFactory.GetGeocodeReportSelectionViewModelBuilder();
var companyList = selectionBuilder.Build();
List<GeocodeReportViewModel> viewModel = new List<GeocodeReportViewModel>();
foreach(SelectListItem record in companyList.Companies)
{
var builder = builderFactory.GetGeocodeReportViewModelBuilder(int.Parse(record.Value));
viewModel.Add(builder.Build());
}
var model = new AllGeocodeReportViewModel
{
GeocodeReports = viewModel
};
return View(model);
}
[HttpGet]
public string SaveAsPDF()
{
var report = new ActionAsPdf("DetailsAll")
{
FileName = "OEM_GeocodeReport_" + System.DateTime.Now.ToString("MMYY") + ".pdf",
PageSize = Size.A4,
PageOrientation = Orientation.Landscape,
PageMargins = { Left = 1, Right = 1 }
};
byte[] pdf = report.BuildFile(ControllerContext);
System.IO.File.WriteAllBytes("C:\\" + report.FileName, pdf);
return "true";
}
Finally found the issue after extensive search. I need to send Authentication cookies along with the BuildFile request for this to work. Added the below code and it generates PDF correctly now:
public void SaveAsPDF()
{
var cookies = Request.Cookies.AllKeys.ToDictionary(k => k, k => Request.Cookies[k].Value);
var report = new ActionAsPdf("DetailsAll")
{
FileName = "OEM_GeocodeReport_" + System.DateTime.Now.ToString("MMyy") + ".pdf",
PageSize = Size.A4,
PageOrientation = Orientation.Portrait,
PageMargins = { Left = 3, Right = 3 },
FormsAuthenticationCookieName = System.Web.Security.FormsAuthentication.FormsCookieName,
Cookies = cookies
};
byte[] pdf = report.BuildFile(ControllerContext);
System.IO.File.WriteAllBytes("C:\\" + report.FileName, pdf);
}

Rename a recorded file every time I save a record in xamarin

I am saving my records using this code:
string path = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
public string fileName { get; set; }
fileName = Path.Combine(path, "sample.wav");
if (!recorder.IsRecording)
{
recorder.StopRecordingOnSilence = TimeoutSwitch.IsToggled;
//Start recording
var audioRecordTask = await recorder.StartRecording();
BtnDoneRec.IsEnabled = false;
await audioRecordTask;
RecEditor.IsEnabled = true;
BtnDoneRec.IsEnabled = false;
PlayButton.IsEnabled = true;
var filePath = recorder.GetAudioFilePath();
if (filePath != null)
{
var stream = recorder.GetAudioFileStream();
using (var fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write))
{
stream.CopyTo(fileStream);
}
}
}
else
{
//stop recording ...
await recorder.StopRecording();
}
I want my record to have a specific name which is labeled with my RecEditor
using (var streamReader = new StreamReader(fileName))
{
File.Move("sample.wav", RecEditor.Text + ".wav");
}
So it will rename "sample.wav" to "RecEditor text.wav" every time I click my save button.
But when I click save, it gives me this record
System.IO.FileNotFoundException: 'Could not find file '/sample.wav'.'
The record is stored in /storage/emulated/0/sample.wav
The sample.wav is created in my device but I don't know why it give me 'Could not find file '/sample.wav'.' error. What am i doing wrong here?
I believe that what you're looking is something like this:
if(File.Exists(fileName))
{
var newFileName = Path.Combine(path, $"{RecEditor.Text}.wav");
File.Move(fileName, newFileName);
}
You don't need to open a new Stream as you are doing. Also, you need to put the full file path not only the file name.
You might want to validate that RecEditor.Text is not empty before using its value for the newfileName
Hope this helps.-

How to save image path in database and save image in specific folder of project.NET core

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(Employee emp)
{
if (ModelState.IsValid)
{
var files = HttpContext.Request.Form.Files;
foreach (var Image in files)
{
if (Image != null && Image.Length > 0)
{
var file = Image;
var root = _appEnvironment.WebRootPath;
var uploads = "uploads\\img";
if (file.Length > 0)
{
// you can change the Guid.NewGuid().ToString().Replace("-", "")
// to Guid.NewGuid().ToString("N") it will produce the same result
var fileName = Guid.NewGuid().ToString("N") + Path.GetExtension(file.FileName);
using (var fileStream = new FileStream(Path.Combine(root, uploads, fileName), FileMode.Create))
{
await file.CopyToAsync(fileStream);
// This will produce uploads\img\fileName.ext
emp.ImageUrl = Path.Combine(uploads, fileName);
}
}
}
}
db.Add(emp);
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
else
{
var errors = ModelState.Values.SelectMany(v => v.Errors);
}
return View(emp);
}
HTML
<input asp-for="ImageUrl" type="file" Class="form-control" />
when i save image, image save successfully in database, but it takes full image path like this C:\Users\VIZO\Desktop\employee.jpg i dont want like this, i need to save image path something like this ~images\employee.jpg. The other problem is image doesnt saving in specific folder of project, i need to save image in this path of my project
uploads\img
So basically your _appEnvironment.WebRootPath by default will be:
%PathToProject%/wwwroot.
For the filePath on your database i would do something like this:
var root = _appEnvironment.WebRootPath
var uploads = "uploads\\img";
if (file.Length > 0)
{
// you can change the Guid.NewGuid().ToString().Replace("-", "")
// to Guid.NewGuid().ToString("N") it will produce the same result
var fileName = Guid.NewGuid().ToString("N") + Path.GetExtension(file.FileName);
using (var fileStream = new FileStream(Path.Combine(root, uploads, fileName), FileMode.Create))
{
await file.CopyToAsync(fileStream);
// This will produce uploads\img\fileName.ext
emp.BookPic = Path.Combine(uploads, fileName);
}
}
If you require any more clarification or guidance please feel free to comment and allow me to explain in more detail.
Thanks.

PivotViewer not showing images if too many pivotviewer properties

I'm updating a pivot viewer application and have run into the following issue. Hopefully someone will have an answer as I'm stuck.
The issue: When the page is loaded the side with properties and other features load fine, but the trading cards don't load any images. Some of them load the default white background while the majority show a dark grey, almost black background. All of them can be zoomed into and show all the properties, but no images.
Debugging: I've discovered that commenting out some of the properties causes the images to load correctly every time. If I comment out only 1 or 2 then the images will load some of the time (about 2 out of 10 page refreshes). Currently there are 29 properties contained in a list and the data is being loaded from a database and then used in the pivotviewer.ItemsSource.
Any ideas?
Code with some name changes (the option two one is the one with the properties I'm commenting out):
MainPage.xaml.cs
public MainPage()
{
InitializeComponent();
PivotViewModel pivotModel = new PivotViewModel();
CollectionsComboBox.SelectedIndex = 0;
this.DataContext = pivotModel;
}
private void DropDown_ItemSelected(object sender, EventArgs e)
{
// Process selected index change here
if (((ComboBox)sender).SelectedValue == "Option One")
{
OptionOnePivotViewModel OptionOnePivot = new OptionOnePivotViewModel();
PivotViewer.ItemsSource = OptionOnePivot.Data;
PivotViewer.PivotProperties = OptionOnePivot.PivotProperties;
PivotViewer.ItemTemplates = OptionOnePivot.TemplateCollection;
PivotViewer.ItemAdornerStyle = blankAdorner;
}
else
{
OptionTwoPivotViewModel OptionTwoPivot = new OptionTwoPivotViewModel();
PivotViewer.ItemsSource = OptionTwoPivot.Data;
PivotViewer.PivotProperties = OptionTwoPivot.PivotProperties;
PivotViewer.ItemAdornerStyle = basicAdorner;
PivotViewer.ItemTemplates = OptionTwoPivot.TemplateCollection;
}
}
OptionTwoPivotViewModel.cs:
public OptionTwoPivotViewModel()
{
DomainContext = new OptionTwoDomainContext();
Data = DomainContext.Load(DomainContext.GetHRDatasQuery()).Entities;
PivotProperties = getPivotProperties();
SmallTemplate = "EmpSmall";
TemplateCollection = new PivotViewerItemTemplateCollection()
{
(PivotViewerItemTemplate) Application.Current.Resources[SmallTemplate]
};
}
private List<PivotViewerProperty> getPivotProperties()
{
List<PivotViewerProperty> properties = new List<PivotViewerProperty>
{
new PivotViewerStringProperty{ Id="Name", Options=PivotViewerPropertyOptions.CanSearchText, DisplayName="Name", Binding=new System.Windows.Data.Binding("Name")},
new PivotViewerStringProperty{ Id="Status", Options=PivotViewerPropertyOptions.CanFilter, DisplayName="Status", Binding=new System.Windows.Data.Binding("Status")},
new PivotViewerDateTimeProperty{ Id="StartDate", Options=PivotViewerPropertyOptions.CanFilter, DisplayName="Start Date", Binding=new System.Windows.Data.Binding("StartDate")},
//additional properties follow...
};
return properties;
Edit: I've noticed that if I set a breakpoint in the following property getter then continue the images also load fine.
public ImageSource BackgroundImage
{
get
{
string location = Image_Location;
location = location.Substring(location.LastIndexOf("/"));
Uri uri;
if (Image_Location.Contains(".gif"))
{
uri = new Uri(Image_Location, UriKind.Absolute);
}
else
{
var host = Application.Current.Host.Source.Host;
uri = new Uri("https://" + host + "/fileLibrary/employees/images/500"+location, UriKind.RelativeOrAbsolute);
}
// set the image source
BitmapImage bmpImg = new BitmapImage(uri);
_loaded = _backgroundImage != null;
if (!_loaded)
{
bmpImg.ImageOpened += ImageOpened;
bmpImg.ImageFailed += ImageFailed;
}
return new BitmapImage(uri);
}
TemplateCollection = new PivotViewerItemTemplateCollection()
{
(PivotViewerItemTemplate) Application.Current.Resources[SmallTemplate]
};
Not assigning a property in the initializer above?

How to upload images on Facebook wall by using MVC3, C#?

I'm trying to upload photos into Facebook by using MVC3 C#. The code is running successfully but the photos are not uploaded into Facebook. I'm having add ID and App Secret. I tried many ways and for many days I worked hard, but the result is zero. Here is the code of my controller
[HttpPost][HttpGet]
public ActionResult Profile(HttpPostedFileBase file, FacebookOAuthResult facebookOAuthResult) {
dynamic args = new ExpandoObject();
args = new Dictionary<string, object>();
args["message"] = "hi";
args["picture"] = "http://apps.facebook.com/Uploads/photos";
string accesstoken=FacebookWebContext.Current.AccessToken;
FacebookClient fbApp = new FacebookClient(accesstoken);
try {
fbApp.Post("MYAPPID" + "/Photos", args);
} catch (FacebookOAuthException ex) {
//
}
// Verify that the user selected a file
if (file != null && file.ContentLength > 0) {
var path1 = Path.Combine(Server.MapPath("~/Content/uppoads"), file.FileName);
//file.SaveAs(path1);
fbApp.Post("MYAPPID" + "/photos", path1);
}
// redirect back to the index action to show the form once again
return RedirectToAction("Profile");
}
Could anyone help me to find the solution? Thanks in advance.
You are Post the local path of the photo to Facebook, FB doesn't know what it is.
You should post the photo as binary in the Post body.
var media = new Facebook.FacebookMediaObject();
var filebytes = System.IO.File.ReadAllBytes(path1);
media.SetValue(filebytes);
fbApp.Post("248050331932489" + "/photos", media);

Resources