Server.MapPath check for folder and create - model-view-controller

I'm uploading an image to a folder images. it's working fine.but what I actually want is to look for a folder name (I have the folder name) if not found create that folder and give it that name.how could that happen?
this is what I have done so far:
string ImageName = System.IO.Path.GetFileName(file.FileName);
string physicalPath = Server.MapPath("~/images/" + ImageName);
instead of images I should have folderName.
the complete view:
#{
ViewBag.Title = "Index";
}
#using (Html.BeginForm("FileUpload", "datum", FormMethod.Post,
new { enctype = "multipart/form-data" }))
{
<div>
category<br />
#Html.DropDownList("category", ViewBag.Roles as SelectList)
<br/>
description<br />
#Html.TextBox("description") <br />
Image<br />
<input type="File" name="file" id="file" value="Choose File" />
<input type="submit" value="Upload" class="submit" />
</div>
}
the complete controller
public class datumController : Controller
{
DataEntry db = new DataEntry();
public ActionResult Index()
{
var data = from p in db.categories
select p.categoryName;
SelectList list = new SelectList(data);
ViewBag.Roles = list;
return View();
}
public ActionResult create ()
{
return View();
}
[HttpPost]
public ActionResult FileUpload(HttpPostedFileBase file)
{
if (file != null)
{
string ImageName = System.IO.Path.GetFileName(file.FileName);
string physicalPath = Server.MapPath("~/images/" + ImageName);
// save image in folder
file.SaveAs(physicalPath);
//save new record in database
datum newRecord = new datum();
newRecord.category = Request.Form["category"];
newRecord.description = Request.Form["description"];
newRecord.imagePath = ImageName;
db.data.Add(newRecord);
db.SaveChanges();
}
//Display records
return RedirectToAction("Display");
}
so I should be getting the selected value from the drop down list and attach it to the physical path, check if folder exists if no then create folder and upload image to that folder

Try like below...
string subPath ="ImagesPath"; // your code goes here
bool exists = System.IO.Directory.Exists(Server.MapPath(subPath));
if(!exists)
System.IO.Directory.CreateDirectory(Server.MapPath(subPath));
For further info, please refer below link.
If a folder does not exist, create it

if (file != null && file.ContentLength > 0)
{
string path = Path.Combine(Server.MapPath("~/Images"), Path.GetFileName(file.FileName));
tbl_MixEmp.EmpImage = Path.Combine("~/Images", file.FileName);
file.SaveAs(path);
}

Related

Multiple photos upload via Cloudinary.DotNet

I have configured my CloudinaryService to upload JUST ONE photo on my cloud on cloudinary. But i have really great troubles with configuring this to make it work on multiple uploads. Please help me, here is my code for single upload:
public async Task<string> UploadPictureAsync(IFormFile pictureFile, string fileName)
{
byte[] destinationData;
using (var ms = new MemoryStream())
{
await pictureFile.CopyToAsync(ms);
destinationData = ms.ToArray();
}
UploadResult uploadResult = null;
using (var ms = new MemoryStream(destinationData))
{
ImageUploadParams uploadParams = new ImageUploadParams
{
Folder = "cars",
File = new FileDescription(fileName, ms),
PublicId = "audizone"
};
uploadResult = this.cloudinaryUtility.Upload(uploadParams);
}
return uploadResult?.SecureUri.AbsoluteUri;
}
}
}
I change IFormFile pictureFile to List<IFormFile> pictureFiles, going on with foreach (file in pictureFiles)...the only thing this service is doing is just uploading 2 or 3 times the same picture(the first one of three or two)...just not uploading two or three different photos.
<form asp-action="Create" method="post" enctype="multipart/form-data">
<input type="file" multiple
class="form-control text-primary text-center"
id="picture"
name="picture"
placeholder="Picture..." />
<input type="submit" value="Submit" class="btn btn-dark" style="border-bottom-left-
radius:25%;border-bottom-right-radius:25%" />
</form>
I managed to successfully loop using this method:
public static void BulkUpload(List<string> filePaths, ResourceType resourceType = ResourceType.Image, string type = "upload")
{
var cloudinary = GetCloudinary(); // Initializing Cloudinary
foreach (var path in filePaths)
{
byte[] bytes = File.ReadAllBytes(path);
var streamed = "streamed";
using (MemoryStream memoryStream = new MemoryStream(bytes))
{
ImageUploadParams uploadParams = new ImageUploadParams()
{
File = new FileDescription(streamed, memoryStream)
};
ImageUploadResult uploadResult = cloudinary.Upload(uploadParams);
if (uploadResult.StatusCode == HttpStatusCode.OK)
Console.WriteLine("uploaded: " + uploadResult.PublicId);
else
Console.WriteLine("Failed: " + uploadResult.Error);
}
}
}

ASP NET MVC 5 i18n using Nadeem's code, but I want to add returnUrl

I am going to include the code how I have it. I felt like what I had should work because I got no squiggly lines. lol But I end up with a Redirect Loop.
First off I got the basic implementation from Nadeem Afana's blog. I don't think the CultureHelper.cs or the BaseController.cs may be needed to implement a returnUrl functionality, but since they are part of the code I am including them here so that you don't have to dig through his website to look for it. I have tried to eliminate scrolling for you as well.
HERE IS MY CODE:
Helpers/CultureHelper.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Web;
namespace xxxUSA.Helpers
{
public static class CultureHelper
{
// Valid cultures REMOVED SOME CODES FOR BREVITY
private static readonly List<string> _validCultures = new List<string>
{ "en-AU", "en-BZ", "en-CA", "en-029", "en-IN", "en-IE", "en-JM",
"en-MY", "en-NZ", "en-PH", "en-SG", "en-ZA", "en-TT", "en-GB",
"en-US", "en-ZW", "es-CR", "es-DO", "es-EC", "es-SV", "es-GT",
"es-HN", "es-MX", "es-NI", "es-PA", "es-PY", "es-PE", "es-PR",
"es-ES", "es-US", "es-UY", "es-VE" };
private static readonly List<string> _cultures = new List<string> {
"en-US", // first culture is the DEFAULT
"es", // Spanish NEUTRAL culture
"ar" // Arabic NEUTRAL culture
};
public static bool IsRightToLeft()
{
return
System.Threading.Thread.CurrentThread
.CurrentCulture.TextInfo.IsRightToLeft;
}
public static string GetImplementedCulture(string name)
{
// make sure it's not null
if (string.IsNullOrEmpty(name))
return GetDefaultCulture(); // return Default culture
if (_validCultures.Where(c => c.Equals(name,
StringComparison.InvariantCultureIgnoreCase)).Count() == 0)
return GetDefaultCulture(); // return Default if invalid
if (_cultures.Where(c => c.Equals(name,
StringComparison.InvariantCultureIgnoreCase)).Count() > 0)
return name; // accept it
var n = GetNeutralCulture(name);
foreach (var c in _cultures)
if (c.StartsWith(n))
return c;
return GetDefaultCulture(); // return Default if no match
}
public static string GetDefaultCulture()
{
return _cultures[0]; // return Default culture
}
public static string GetCurrentCulture()
{
return Thread.CurrentThread.CurrentCulture.Name;
}
public static string GetCurrentNeutralCulture()
{
return GetNeutralCulture(Thread.CurrentThread.CurrentCulture.Name);
}
public static string GetNeutralCulture(string name)
{
if (name.Length < 2)
return name;
return name.Substring(0, 2);
}
}
}
Controllers/BaseController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Web;
using System.Web.Mvc;
using xxxUSA.Helpers;
namespace xxxUSA.Controllers
{
public class BaseController : Controller
{
protected override IAsyncResult BeginExecuteCore(
AsyncCallback callback, object state)
{
string cultureName = null;
// Attempt to read the culture cookie from Request
HttpCookie cultureCookie = Request.Cookies["_culture"];
if (cultureCookie != null)
cultureName = cultureCookie.Value;
else
cultureName = Request.UserLanguages != null &&
Request.UserLanguages.Length > 0 ? Request.UserLanguages[0]
: null; // obtain it from HTTP header AcceptLanguages
// Validate culture name
cultureName = CultureHelper.GetImplementedCulture(cultureName);
// Modify current thread's cultures
Thread.CurrentThread.CurrentCulture = new
System.Globalization.CultureInfo(cultureName);
Thread.CurrentThread.CurrentUICulture =
Thread.CurrentThread.CurrentCulture;
return base.BeginExecuteCore(callback, state);
}
}
}
OK, now we get into where I have modified some things. I will comment on anything I added
Controllers/HomeController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using xxxUSA.Helpers;
using xxxUSA.Models;
namespace xxxUSA.Controllers
{
public class HomeController : BaseController
{
ApplicationDbContext _db = new ApplicationDbContext();
public ActionResult Index()
{
return View();
}
public ActionResult About()
{
return View();
}
public ActionResult Contact()
{
return View();
}
//I ADDED THIS LAST PARAMETER
public ActionResult SetCulture(string culture, string returnUrl)
{
// Validate input
culture = CultureHelper.GetImplementedCulture(culture);
// Save culture in a cookie
HttpCookie cookie = Request.Cookies["_culture"];
if (cookie != null)
cookie.Value = culture; // update cookie value
else
{
cookie = new HttpCookie("_culture");
cookie.Value = culture;
cookie.Expires = DateTime.Now.AddYears(1);
}
Response.Cookies.Add(cookie);
//THIS WORKS
return Redirect(returnUrl);
//THIS DOES NOT
if (!string.IsNullOrEmpty(returnUrl) && Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
Now for the code on the Home Page
Views/Home/Index.cshtml
#{
var culture = System.Threading.Thread.CurrentThread
.CurrentUICulture.Name.ToLowerInvariant();
ViewBag.Title = culture;
}
//I ADDED THIS LAST PARAMETER
#helper selected(string c, string culture, string returnUrl)
{
if (c == culture)
{
#:checked="checked"
}
}
#using (Html.BeginForm("SetCulture", "Home"))
{
#Resources.ChooseYourLanguage
<input name="culture" id="en-us" value="en-us"
//I ADDED THIS LAST PARAMETER "About"
type="radio" #selected("en-us", culture, "About") /> English
<input type="Hidden" name="returnUrl" value="About" />
<input name="culture" id="es" value="es"
//I ADDED THIS LAST PARAMETER "About"
type="radio" #selected("es", culture, "About") /> Español
}
//LOTS OF STUFF LOADS HERE LIKE RESOURCE REFERENCES, GRAPHICS, CONTENT,
//NOT IMPORTANT FOR THE IMPLEMENTATION REMOVED FOR BREVITY
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript">
(function ($) {
$("input[type = 'radio']").click(function () {
$(this).parents("form").submit(); // post form
});
})(jQuery);
</script>
}
So the reason I added the "About" was so if I got it to work, It would redirect to the "About" Action instead of back to the same homepage. It doesn't work though.
Can I not overload the checkboxes #Selected Method the way I have?
Also, NOT IMPORTANT NOW, but what if I wanted to add this to other views from other controllers, Could I include another parameter to designate the controller and action it needs to return to so that I don't have to repeat the code in each controller?
I have contacted Nadeem on twitter and he said he would check it out and try and help. I really appreciate his work and seems like a very kind fellow.. Thanks in advance for simply helping in any capacity!
OK so I have a products/Ingredients page where I have stuff coming from the database, here how I hacked that to show the right field from the database. This is a total HACK BEWARE.
Views/Products.cshtml
#model IEnumerable<xxxUSA.Models.Ingredient>
#{
var culture = System.Threading.Thread.CurrentThread
.CurrentUICulture.Name.ToLowerInvariant();
ViewBag.Title = culture;
}
#helper selected(string c, string culture)
{
if (c == culture)
{#:checked="checked"}
}
<div class="row">
<div class="large-12 columns">
#using(Html.BeginForm("SetCulture", "Ingredient"))
{
<div class="row">
<div class="large-6 columns">
<label>#Resources.ChooseYourLanguage</label>
<input type="Hidden" name="returnUrl" value="/Prodcuts/" />
<input name="culture" id="en-us" value="en-us" type="radio"
#selected("en-us", culture) /> English
<input name="culture" id="es" value="es" type="radio"
#selected("es", culture) /> Español
</div>
</div>
}
#{ViewBag.Culture = System.Threading.Thread.CurrentThread
.CurrentUICulture.Name.ToLowerInvariant();}
//Here is where the conditional logic hack I use to show one field
//or another from the database based on culture
#if (ViewBag.Culture == "en-us") {
#Html.DisplayFor(modelItem => item.IngredientNameEn)
} else {
#Html.DisplayFor(modelItem => item.IngredientNameEs) }
Basically using that conditional logic anywhere I have data that has a spanish or english version. it's hacky as hell though.
Try this:
public ActionResult SetCulture(string culture, string returnUrl)
{
// Validate input
culture = CultureHelper.GetImplementedCulture(culture);
// Save culture in a cookie
HttpCookie cookie = Request.Cookies["_culture"];
if (cookie != null)
cookie.Value = culture; // update cookie value
else
{
cookie = new HttpCookie("_culture");
cookie.Value = culture;
cookie.Expires = DateTime.Now.AddYears(1);
}
Response.Cookies.Add(cookie);
if (!string.IsNullOrEmpty(returnUrl) && Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
I'm also using Nadeem's i18n solution in a project. The way you switch the culture in this project is through clicking on flags (anchor tags in image tags). I added a returnUrl and ended up with a redirect loop. To fix the redirect loop issue, I made a few changes to the code and ended up with this code:
File: BaseController.cs (added this method)
public ActionResult SetCulture(string culture, string returnUrl)
{
// Validate input
culture = CultureHelper.GetImplementedCulture(culture);
RouteData.Values["culture"] = culture;
// Save culture in a cookie
HttpCookie cookie = Request.Cookies["_culture"];
if (cookie != null)
{
// update cookie value
cookie.Value = culture;
}
else
{
cookie = new HttpCookie("_culture");
cookie.Value = culture;
cookie.Expires = DateTime.Now.AddYears(1);
}
Response.Cookies.Add(cookie);
return Redirect(returnUrl);
}
File: _layout.cshtml (flags for selecting culture):
#{ var daDkUrl = Url.Action("setculture", "base", new { culture = "da-DK", returnUrl = Request.RawUrl }); }
<a href="#daDkUrl">
<img src="~/content/images/flag_da.gif" width="16" height="11" alt="Dansk" />
</a>
|
#{ var enUsUrl = Url.Action("setculture", "base", new { culture = "en-US", returnUrl = Request.RawUrl }); }
<a href="#enUsUrl">
<img src="~/content/images/flag_en.gif" width="16" height="11" alt="English" />
</a>
Finally, ensure your controllers inherit from BaseController.cs.
public class TestController : BaseController
{
//Code
}

How to Store an Image in Database and then Display it in MVC

How to store Image in Database and then retrieve and display it using MVC
I am Using MVC3, Entity Framework Database First, and SQL SERVER 2008
In Database I have used varbinary(MAX) for the Image
Image varbinary(MAX) Checked
Further I used
[DisplayName("Image")]
public byte[] Image { get; set; }
in my mapping class
When I tried to save it in my Create action method
public ActionResult Create(MarjaaModel newMarjaa, HttpPostedFileBase uploadFile)
{
if (uploadFile != null && uploadFile.ContentLength > 0)
{
newMarjaa.Image = new byte[uploadFile.ContentLength];
uploadFile.InputStream.Read(newMarjaa.Image, 0, uploadFile.ContentLength);
}
try
{
data.submitMarjaa(newMarjaa);
return RedirectToAction("Index");
}
catch
{
return View();
}
}
I am successful in saving the image as binary data
But please tell me how I can retrieve this image and display it in my View
Finally I did it
A simple method in my controller
public ActionResult ShowImage(long id)
{
var model = data.getMarjaa(id);
return File(model.Image, "image/jpg");
}
and In my View
<td>
#if (item.Image == null)
{
<img width="40" height="40" src="http://www.abc.com/images/staff/no_worry[1].jpg" />
}
else
{
<img width="40" height="40" src='#Url.Action("ShowImage", "Admin", new { id = item.id })' />
}
</td>
<td>
#{
var base64 = Convert.ToBase64String(item.NewsImage);
var imgsrc = string.Format("data:image/jpg;base64,{0}", base64);
}
<img src='#imgsrc' style="max-width:100px;max-height:100px" />
</td>
only this need to view the pics

displaying image from db in Razor/MVC3

I have a table in the db, which has the following :- CountryID, CountryName, and CountryImage.
Now I am trying to display the image in the index and I have the following in the View :-
<td>
#if (item.Image != null)
{
<img src="#Model.GetImage(item.Image)" alt="#item.CountryName"/>
}
and then in the ViewModel I have :-
public FileContentResult GetImage(byte[] image)
{
if (image != null)
return new FileContentResult(image, "image/jpeg");
else
{
return null;
}
}
However I cannot see the image properly.
What am I doing wrong?
Thanks in advance for your help and time
UPDATE
Ok So I have implemented the following in the View :-
<td>
#if (item.Image != null)
{
<img src="#Url.Action("GetImage", "CountryController", new { id = item.CountryID })" alt="#item.CountryName" />
}
</td>
and in the CountryController :-
public ActionResult GetImage(int id)
{
var firstOrDefault = db.Countries.Where(c => c.CountryID == id).FirstOrDefault();
if (firstOrDefault != null)
{
byte[] image = firstOrDefault.Image;
return File(image, "image/jpg");
}
else
{
return null;
}
}
but when I try to debug the code, the ActionResult GetImage is not being hit
Two possibilities.
Write a controller action instead which given an image id will return this image:
public ActionResult GetImage(int id)
{
byte[] image = ... go and fetch the image buffer from the database given the id
return File(image, "image/jpg");
}
and then:
<img src="#Url.Action("GetImage", "SomeController", new { id = item.Id })" alt="#item.CountryName" />
Obviously now in your initial model you don't need the Image property. This will be retrieved subsequently in the controller action responsible for that.
Another possibility is to use data URI scheme to embed the images as base64 strings but it might not be widely supported by all browsers:
<img src="data:image/jpg;base64,#(Convert.ToBase64String(item.Image))" alt="#item.CountryName" />
You don't need a controller action in this case as the images are directly embedded into your markup as base64 strings.

MVC3 Display a dropdown list from one datasource and save to another datasource

I'm getting back to an MVC3 project after a 3 month hiatus. I need to display a drop down list that pulls from Database A, but saves to Database B. The property I need to persist is the NAICS/SIC code. Right now I just provide the user a text box to key in freeform text. So, I have the mechanics of that down. But instead it should provide only a valid list of codes from a source database.
The tricky thing to is I'm using a custom model binder to generate my ViewModels on the fly, so I don't have a distinct .cshtml file to customize.
[Serializable]
public class Step4ViewModel : IStepViewModel
{
public Step4ViewModel()
{
}
//load naics codes from somewhere
[Display(Name = "Describe the nature of your business.")]
public String NatureOfBusiness { get; set; }
[Display(Name="NAICS/SIC CODE")]
public String BusinessTypeCode { get; set; }
Tricky ViewModel
#using Microsoft.Web.Mvc;
#using Tangible.Models;
#model Tangible.Models.WizardViewModel
#{
var currentStep = Model.Steps[Model.CurrentStepIndex];
var progress = ((Double)(Model.CurrentStepIndex) / Model.Steps.Count) * 100;
}
<script type="text/javascript">
$(function () {
$("#progressbar").progressbar({
value: #progress
});
});
</script>
<div id="progressbar" style="height:20px;">
<span style="position:absolute;line-height:1.2em; margin-left:10px;">Step #(Model.CurrentStepIndex + 1) out of #Model.Steps.Count</span>
</div>
#Html.ValidationSummary()
#using (Html.BeginForm())
{
#Html.Serialize("wizard", Model)
#Html.Hidden("StepType", Model.Steps[Model.CurrentStepIndex].GetType())
#Html.EditorFor(x => currentStep, null, "")
if (Model.CurrentStepIndex > 0)
{
<input type="submit" value="Previous" name="prev" />
}
if (Model.CurrentStepIndex < Model.Steps.Count - 1)
{
<input type="submit" value="Save & Continue" name="next" />
}
else
{
<input type="submit" value="Finish" name="finish" />
}
#*<input type="submit" value="Save" name="Save" />*#
}
Controller
[HttpPost]
public ActionResult Index([Deserialize] WizardViewModel wizard, IStepViewModel step)
{
wizard.Steps[wizard.CurrentStepIndex] = step;
if (ModelState.IsValid)
{
//Always save.
var obj = new dr405();
//wire up to domain model;
foreach (var s in wizard.Steps)
{
Mapper.Map(s,obj,s.GetType(), typeof(dr405));
}
using (var service = new DR405Service())
{
//Do something with a service here.
service.Save(db, obj);
}
if (!string.IsNullOrEmpty(Request["next"]))
{
wizard.CurrentStepIndex++;
}
else if (!string.IsNullOrEmpty(Request["prev"]))
{
wizard.CurrentStepIndex--;
}
else
{
return View("Upload", obj);
}
}
else if (!string.IsNullOrEmpty(Request["prev"]))
{
wizard.CurrentStepIndex--;
}
return View(wizard);
}
WizardViewModel
[Serializable]
public class WizardViewModel
{
public String AccountNumber { get; set; }
public int CurrentStepIndex { get; set; }
public Boolean IsInitialized { get { return _isInitialized; } }
public IList<IStepViewModel> Steps { get; set; }
private Boolean _isInitialized = false;
public void Initialize()
{
try
{
Steps = typeof(IStepViewModel)
.Assembly.GetTypes().Where(t => !t.IsAbstract && typeof(IStepViewModel).IsAssignableFrom(t)).Select(t => (IStepViewModel)Activator.CreateInstance(t)).ToList();
_isInitialized = true;
//rewrite this. get the profile and wire them up or something.
this.AccountNumber = Tangible.Profiles.DR405Profile.CurrentUser.TangiblePropertyId;
}
catch (Exception e)
{
_isInitialized = false;
}
}
}
You can specify a template for a specific property on your view model by adding the UIHint attribute to the field. Since your view calls EditorFor on the model it will use the template you specified with UIHint.
BusinessTypeDropdown.ascx - (placed in Views/Shared/EditorTemplates
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<string>" %>
<% var businessTypes = ViewData["businessTypes"] as IEnumerable<string>; %>
<%= Html.DropDownListFor(m => m , new SelectList(businessTypes, Model))%>
In your View Model
[Serializable]
public class Step4ViewModel : IStepViewModel
{
public Step4ViewModel()
{
}
//load naics codes from somewhere
[Display(Name = "Describe the nature of your business.")]
public String NatureOfBusiness { get; set; }
[Display(Name="NAICS/SIC CODE")][UIHint("BusinessTypeDropdown")]
public String BusinessTypeCode { get; set; }
Then in your controller just set ViewData["businessTypes"] to your list of business types.
Without understanding your "tricky" view model code, it will be hard to make helpful suggestions.
However, there shouldn't be much problem here. You need to somehow create your dropdown list in yoru view, and populate it from data passed from your controller.
All the work happens in your controller. Populate your list or IEnumerable or whatever data source from your first database, then in your post handler save the selection it to your second database (the second part should not be much different from what you already have).

Resources