I am on Umbraco version 4.0.1.2 and have the need to create content programatically. I am aware of, and have in the past, created nodes programatically so that is no the issue. The question I have is, how would I create a media item from an uploaded file that I collect in the front-end form (which would be an asp:file control).
// create the Media Node // TODO: get parent id for current category - as selected by user (see below) // - for now just stick these in the media root :: node = -1 m = Media.MakeNew( filename, MediaType.GetByAlias("image"), User.GetUser(0), 1219);
// Create a new folder in the /media folder with the name /media/propertyid string mediaRootPath = HttpContext.GetGlobalResourceObject("AppSettings", "MediaFilePath") as string; // get path from App_GlobalResources string storagePath = mediaRootPath + m.Id.ToString(); System.IO.Directory.CreateDirectory(storagePath); _fullFilePath = storagePath + "\\" + filename; uploadControl.PostedFile.SaveAs(_fullFilePath);
// Save file size try { System.IO.FileInfo fi = new FileInfo(_fullFilePath); m.getProperty("umbracoBytes").Value = fi.Length.ToString(); } catch { }
// Check if image and then get sizes, make thumb and update database if (",jpeg,jpg,gif,bmp,png,tiff,tif,".IndexOf("," + ext + ",") > 0) { int fileWidth; int fileHeight;
FileStream fs = new FileStream(_fullFilePath, FileMode.Open, FileAccess.Read, FileShare.Read);
protected void generateThumbnail(System.Drawing.Image image, int maxWidthHeight, int fileWidth, int fileHeight, string fullFilePath, string ext, string thumbnailFileName) { // Generate thumbnail float fx = (float)fileWidth / (float)maxWidthHeight; float fy = (float)fileHeight / (float)maxWidthHeight; // must fit in thumbnail size float f = Math.Max(fx, fy); //if (f < 1) f = 1; int widthTh = (int)Math.Round((float)fileWidth / f); int heightTh = (int)Math.Round((float)fileHeight / f);
// fixes for empty width or height if (widthTh == 0) widthTh = 1; if (heightTh == 0) heightTh = 1;
// Create new image with best quality settings Bitmap bp = new Bitmap(widthTh, heightTh); Graphics g = Graphics.FromImage(bp); g.SmoothingMode = SmoothingMode.HighQuality; g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.PixelOffsetMode = PixelOffsetMode.HighQuality;
// Copy the old image to the new and resized Rectangle rect = new Rectangle(0, 0, widthTh, heightTh); g.DrawImage(image, rect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel);
// Copy metadata ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders(); ImageCodecInfo codec = null; for (int i = 0; i < codecs.Length; i++) { if (codecs[i].MimeType.Equals("image/jpeg")) codec = codecs[i]; }
// Set compresion ratio to 90% EncoderParameters ep = new EncoderParameters(); ep.Param[0] = new EncoderParameter(Encoder.Quality, 90L);
// Save the new image bp.Save(thumbnailFileName, codec, ep); bp.Dispose(); g.Dispose();
this is a really lovely bit of code and works perfectly for what i am trying to do in my development environment
but when i move it to the live environment i get a permissions errror
Access to the path '1102' is denied.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.UnauthorizedAccessException: Access to the path '1102' is denied.
ASP.NET is not authorized to access the requested resource. Consider granting access rights to the resource to the ASP.NET request identity. ASP.NET has a base process identity (typically {MACHINE}\ASPNET on IIS 5 or Network Service on IIS 6) that is used if the application is not impersonating. If the application is impersonating via <identity impersonate="true"/>, the identity will be the anonymous user (typically IUSR_MACHINENAME) or the authenticated request user.
To grant ASP.NET access to a file, right-click the file in Explorer, choose "Properties" and select the Security tab. Click "Add" to add the appropriate user or group. Highlight the ASP.NET account, and check the boxes for the desired access.
where 1102 is the name of the media node id it is trying to create
it does not manage to create the folder
this is IIS7 on Win2k3 and the Network Service has full control of the media folder
Thanks. This post has been helpful to me. I'm not sure what this business about getting the media root path from appSettings is. Wouldn't a simple Server.MapPath("~/media") suffice? Or am I missing something?
Just thought I would post a reply here, since I found a much easier way to do this in 4.9 using code from the umbraco source (not sure if it was this easy in older versions):
Just create a PostedMediaFile from your file stream, create an UmbracoImageMediaFactory (specifically if you are doing images - there is also one for other files), and call DoHandleMedia, passing in the current media item and PostedMediaFile you just created.
Just wanted to update this post with my method I am using in Umbraco 7. My front end involves a form that allows a user to choose an image to upload for their business linsting.The back end code takes the file puts it in the media folder.
FRONT END @{ var businessListing = new BusinessListing();} @using (Html.BeginUmbracoForm<BusinessDirectorySurfaceController>("CreateListing")){ <fieldset> @Html.AntiForgeryToken() <legend>Create New Listing</legend> @Html.ValidationSummary("businessListing", true) @Html.LabelFor(m => businessListing.CompanyName) @Html.TextBoxFor(m => businessListing.CompanyName) @Html.ValidationMessageFor(m => businessListing.CompanyName) <br /> @Html.LabelFor(m => businessListing.Image) <input type="file" name="file" /> @Html.ValidationMessageFor(m => businessListing.Image) <br /> <button>Submit</button> </fieldset> }
BACK END / CODE BEHIND public ActionResult CreateListing([Bind(Prefix = "businessListing")]BusinessListing businessListing) { string id; if (Request.Files.Count > 0) { var file = Request.Files[0]; if (file != null && file.ContentLength > 0) { // TODO: dynamically get node Id for Business Listing Thumbnail // Create the media item var mediaImage = Services.MediaService.CreateMedia(businessListing.CompanyName, 1396, Constants.Conventions.MediaTypes.Image); // Save it to create the media Id Services.MediaService.Save(mediaImage); // Upload the image file var fileName = Path.GetFileName(file.FileName); // Create the new media folder if (!Directory.Exists(Server.MapPath("~/media/" + mediaImage.Id + "/"))) Directory.CreateDirectory(Server.MapPath("~/media/" + mediaImage.Id + "/")); // Build the file path var path = Path.Combine(Server.MapPath("~/media/" + mediaImage.Id + "/"), fileName); // Save the file to the server file.SaveAs(path); // Point the Umbraco media object at this new file mediaImage.SetValue("umbracoFile", path); // Save the new filepath Services.MediaService.Save(mediaImage); } }// The rest of your code}
Creating Media Programatically
Hi all,
I am on Umbraco version 4.0.1.2 and have the need to create content programatically. I am aware of, and have in the past, created nodes programatically so that is no the issue. The question I have is, how would I create a media item from an uploaded file that I collect in the front-end form (which would be an asp:file control).
Thanks for your examples and input.
-- Nik
You'll need to use the MakeNew method on Media:
The parameters are:
Thanks slace. I remeber seeing this now.
So, am I looking to put the path in the media.Image attribute then?
Sorry, this should probably be obvious.
Thanks,
Nik
I found a complete solution for this and thought it would make sense to share this in this post.
The following snippet is a slightly modified version of one that Paul Sterling posted on the old forum (thanks Paul for sharing):
this is a really lovely bit of code and works perfectly for what i am trying to do in my development environment
but when i move it to the live environment i get a permissions errror
Access to the path '1102' is denied.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.Exception Details: System.UnauthorizedAccessException: Access to the path '1102' is denied.
ASP.NET is not authorized to access the requested resource. Consider granting access rights to the resource to the ASP.NET request identity. ASP.NET has a base process identity (typically {MACHINE}\ASPNET on IIS 5 or Network Service on IIS 6) that is used if the application is not impersonating. If the application is impersonating via <identity impersonate="true"/>, the identity will be the anonymous user (typically IUSR_MACHINENAME) or the authenticated request user.
To grant ASP.NET access to a file, right-click the file in Explorer, choose "Properties" and select the Security tab. Click "Add" to add the appropriate user or group. Highlight the ASP.NET account, and check the boxes for the desired access.
where 1102 is the name of the media node id it is trying to create
it does not manage to create the folder
this is IIS7 on Win2k3 and the Network Service has full control of the media folder
When I changed line 41 to
<code>
string mediaRootPath = "/media/"; // get path from App_GlobalResources
</code>
The File data (size, width, height, etc) are correctly stored in the Database, but again, the new media folder and file are not created.
L
I've run into the same problem. Did you already found the solution?
aah! the files where crearted in C:/media/ instead of the right path... let me find out why that happend!
Have you created the additional key in the web.config file, under <appSettings>
Should be something like...
<add key="MediaFilePath" value="c:/inetpub/wwwroot/media/" />
/L
when I chaned string mediaRootPath = "/media/"; // get path from App_GlobalResources to:
(my full path for the website) everything is OK. It seems like the appsettings gives the wrong value...
Thanks. This post has been helpful to me. I'm not sure what this business about getting the media root path from appSettings is. Wouldn't a simple Server.MapPath("~/media") suffice? Or am I missing something?
Just thought I would post a reply here, since I found a much easier way to do this in 4.9 using code from the umbraco source (not sure if it was this easy in older versions):
Just create a PostedMediaFile from your file stream, create an UmbracoImageMediaFactory (specifically if you are doing images - there is also one for other files), and call DoHandleMedia, passing in the current media item and PostedMediaFile you just created.
PostedMediaFile postedMediaFile = new PostedMediaFile
{
FileName = YourFileName,
DisplayName = YourDisplayName,
ContentLength = StreamLength,
InputStream = Stream,
ReplaceExisting = true
};
UmbracoImageMediaFactory factory = (UmbracoImageMediaFactory)MediaFactory.GetMediaFactory(parentNodeId, postedMediaFile, new User(0));
factory.DoHandleMedia(ucImage, postedMediaFile, new User(0));
Too easy!
Nice one Daniel, worked great for me! :D
HI
When i click the save button i got the following error
'The SaveAs method is configured to require a rooted path, and the path '1233' is not rooted.'
this 1233 is Make a New folder ..... how to rectify this error
Kindly reply me
kindly reply
My front end involves a form that allows a user to choose an image to upload for their business linsting.The back end code takes the file puts it in the media folder.
FRONT END @{ var businessListing = new BusinessListing();} @using (Html.BeginUmbracoForm<BusinessDirectorySurfaceController>("CreateListing")){ <fieldset> @Html.AntiForgeryToken() <legend>Create New Listing</legend> @Html.ValidationSummary("businessListing", true) @Html.LabelFor(m => businessListing.CompanyName) @Html.TextBoxFor(m => businessListing.CompanyName) @Html.ValidationMessageFor(m => businessListing.CompanyName) <br /> @Html.LabelFor(m => businessListing.Image) <input type="file" name="file" /> @Html.ValidationMessageFor(m => businessListing.Image) <br /> <button>Submit</button> </fieldset> }
BACK END / CODE BEHIND
public ActionResult CreateListing([Bind(Prefix = "businessListing")]BusinessListing businessListing) { string id; if (Request.Files.Count > 0) { var file = Request.Files[0]; if (file != null && file.ContentLength > 0) { // TODO: dynamically get node Id for Business Listing Thumbnail // Create the media item var mediaImage = Services.MediaService.CreateMedia(businessListing.CompanyName, 1396, Constants.Conventions.MediaTypes.Image); // Save it to create the media Id Services.MediaService.Save(mediaImage); // Upload the image file var fileName = Path.GetFileName(file.FileName); // Create the new media folder if (!Directory.Exists(Server.MapPath("~/media/" + mediaImage.Id + "/"))) Directory.CreateDirectory(Server.MapPath("~/media/" + mediaImage.Id + "/")); // Build the file path var path = Path.Combine(Server.MapPath("~/media/" + mediaImage.Id + "/"), fileName); // Save the file to the server file.SaveAs(path); // Point the Umbraco media object at this new file mediaImage.SetValue("umbracoFile", path); // Save the new filepath Services.MediaService.Save(mediaImage); } }// The rest of your code}
is working on a reply...