I have just made a model and controller which insert new row in a custom table to my umbraco database.
I based it on petapoco tutorial http://creativewebspecialist.co.uk/2013/07/16/umbraco-petapoco-to-store-blog-comments/
Despite the script executing without errors the row is not inserted into the table.
here's what I have:
namespace MyImport.Models
{
[TableName("MyImport_Uploads")]
[PrimaryKey("ID", autoIncrement = true)]
[ExplicitColumns]
public class ImportFile
{
[Column("ID")]
[PrimaryKeyColumn(AutoIncrement=true)]
public int Id { get; set; }
[Required]
[Column("CompanyID")]
public string CompanyId { get; set; }
//public Guid CompanyId { get; set; }
[Required]
[Column("FilenameOriginal")]
public string FilenameOriginal { get; set; }
[Required]
[Column("Filename")]
public string Filename { get; set; }
[Required]
[Column("FileType")]
public string FileType { get; set; }
[Column("NumberOfItems")]
public int NumberOfItems { get; set; }
[Column("DateCreated")]
public DateTime DateCreated { get; set; }
[Column("DeleteExisting")]
public bool DeleteExisting { get; set; }
}
}
And controller:
namespace MyImport.Controllers
{
public class ImportController : SurfaceController
{
private Umbraco.Core.Persistence.UmbracoDatabase db = MyImport.Settings.UmbracoDbDSN;
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult ImportExcel(ImportModel model)
{
var fileTypes = new List<string>
{
"text/xml",
"application/xml",
};
string fileType = GetFileType(model.FileUpload.ContentType);
if(model.FileUpload != null && model.FileUpload.ContentLength > 0)
{
string uploadDir = "~/imports";
string origFileName = model.FileUpload.FileName;
string extension = origFileName.Substring(origFileName.LastIndexOf('.') + 1);
string pathToCheck = Path.Combine(Server.MapPath(uploadDir), origFileName);
// Check to see if a file already exists with the
// same name as the file to upload.
if (!System.IO.File.Exists(pathToCheck))
{
string companyId = MyImport.Member.CompanyIdDummy;
string tempfileName = companyId.ToLower() + "-" + DateTime.Now.ToString("yyyyMMddHHmmss") + "." + extension;
pathToCheck = Path.Combine(Server.MapPath(uploadDir), tempfileName);
model.FileUpload.SaveAs(pathToCheck);
var importFile = new ImportFile
{
CompanyId = companyId,
Filename = tempfileName,
FilenameOriginal = origFileName,
FileType = extension,
DateCreated = DateTime.UtcNow
};
db.Insert(importFile);
}
TempData.Add("Success", true);
}
//redirect to current page to clear the form
return RedirectToCurrentUmbracoPage();
}
}
Any suggestions? Thanks
I had the database wrongly set up.
Basically I had it as umbraco.sdf in App_Data folder while I intended to use my full MSSQL database where the table was created.
I recreated the project, reinstalled umbraco and HAD to choose Customize at the bottom of the screen where I was choosing setting up cms access. This is important as I was then directed to the screen where I could set up my database connection.
Otherwise umbraco just install into SQL Server Express database which is stored in umbraco.sdf file in the project.
I hope this make sense for anyone looking for the solution to the same problem.
Related
I want to pass a value from the model...
#Html.HiddenFor(model => model.ProductId)
Exception thrown: 'System.ArgumentException' in System.Web.Mvc.dll
Additional information: Value cannot be null or empty.
But it is throwing this exception and I don't know why... And no ProductId isn't null.
Action
[HttpGet]
public ActionResult Edit(int ProductId = 0)
{
PCsViewModel pcViewModel = new PCsViewModel();
ProductRepository productRepo = new ProductRepository();
Product dbProduct = productRepo.GetAll(item=>item.ID==ProductId);
PCsRepository pcsRepo = new PCsRepository();
PC dbPC = pcsRepo.GetAll(item=>item.ProductID==ProductId);
if (dbProduct != null && dbPC != null)
{
pcViewModel = new PCsViewModel(dbProduct,dbPC);
}
return View(pcViewModel);
}
ViewModel
public int ProductId { get; set; }
[Required]
public string Name { get; set; }
public string PCsInfo { get; set; }//for the front view
[Required]
public double Price { get; set; }
[Required]
public string ImagePath { get; set; }
[Required]
public string Processor { get; set; }
[Required]
public string OS { get; set; }
[Required]
public int RAM { get; set; }
[Required]
public int Storage { get; set; }
[Required]
public string VideoCard { get; set; }
[Required]
public int CategoryID { get; set; }
public PCsViewModel()
{
}
public PCsViewModel(Product product, PC pc)
{
this.ProductId = product.ID;
this.CategoryID = product.CategoryID;
this.OS = product.OS;
this.Processor = product.Processor;
this.Name = product.Name;
this.RAM = product.RAM;
this.Storage = product.Storage;
this.VideoCard = pc.VideoCard;
this.PCsInfo = "PC "+product.Name + "with processor " + product.Processor;
this.Price = (double)product.Price;
this.ImagePath = Path.Combine(Constants.ImagesPCsDirectory, product.ImageName);
}
Based of the discussion in the comments, it looks like your actual issue wasn't related to the ProductId property but instead your ImagePath property, which was being passed into a Url.Content() helper (to resolve the appropriate path).
This would work as expected if the path existed, but if that property was null or empty, you would receive the ArgumentNullException that you currently are. The best approach would likely be to just only render the specific path if that specific property wasn't null:
#if (!string.IsNullOrEmpty(Model.ImagePath)) {
// Use Url.Content(Model.ImagePath) within here safely
}
There are multiple different ways to handle this, such as adding an additional property on your model to clean things up:
public bool HasImage => !string.IsNullOrEmpty(ImagePath);
And then use:
#if (Model.HasImage) {
// Use Url.Content(Model.ImagePath) within here safely
}
I have a controller action which saves data to db on change. Model includes children Files, they are not saved to the database however. Data comes ok from the server, file is added to the model from the request ok, but it just won't save. There is no error occuring.
These are my models:
public class Guest
{
public Guest()
{
this.Files = new List<File>();
}
public int Id { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
public string Email { get; set; }
public string Tel { get; set; }
public int CompanyId { get; set; }
public int Votes { get; set; }
public virtual ICollection<File> Files {get; set;}
}
This is my VM
public class GuestViewModel
{
public Guest Guest { get; set; }
public IEnumerable<SelectListItem> Companies { get; set; }
}
and this is the controller
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit( GuestViewModel guestViewModel, HttpPostedFileBase upload)
{
if (upload != null && upload.ContentLength > 0)
{
var avatar = new File
{
FileName = System.IO.Path.GetFileName(upload.FileName),
FileType = FileType.Picture,
ContentType = upload.ContentType
};
using (var reader = new System.IO.BinaryReader(upload.InputStream))
{
avatar.Content = reader.ReadBytes(upload.ContentLength);
}
guestViewModel.Guest.Files = new List<File> { avatar };
}
if (ModelState.IsValid)
{
Guest guest = new Guest();
guest = guestViewModel.Guest;
_db.Entry(guest).State = EntityState.Modified;
_db.SaveChanges();
return RedirectToAction("Index");
}
return View(guestViewModel);
}
Any help is appreciated.
I think that you have to set the state for the child entities too, because when you attach an entity to a context setting the state directly, any child entities is attacched in "unchanged" state, so is ignored in save changes.
In this case, the state that you need to use for child files is Added.
Hope this helps!
I'm relatively new to ASP.net mvc, and am experiencing a very strange browser error. The problem is that it's on the customer's pc (which I have yet to get access to).
There seems to be an intermittent problem posting data from his computer, at the moment he has only tried chrome (and I have requested he try different browsers). I haven't been able to replicate the issue and have tried on two computers, three browsers and three different operating systems (windows 7, windows 8 (via mac parallels) and Osx Mavericks) .
I'll post the model and relevant controller code (hopefully it's not too sloppy coding)
I've clarified the following:
- we are both using the same version of chrome
- we both use the same ISP
- He has AVG running
-the site is hosted on Azure
- there is plenty of database and file memory allocated (only 10% being used)
- very little in my code has varied from online examples and again, it all works for me
So my question is really, where else do I look to find the errors:
- is there something in the code that I should consider adding or changing
- could it be a cookie issue on his version of chrome?
- is there a firewall issue somewhere?
model
public class KitchenItem:Post
{
public virtual ICollection<Image> Images { get; set; }
//Optional Project Variables
public bool Project { get; set; }
public string ProjectName { get; set; }
public string Customer { get; set; }
public DateTime? projectStart { get; set; }
public DateTime? projectEnd { get; set; }
}
}
inherited model:
public class Post
{
public int Id
{ get; set; }
[Required]
public string Title
{ get; set; }
[Required]
[Display(Name="Short Description")]
[DataType(DataType.MultilineText )]
public string ShortDescription
{ get; set; }
[Required]
[AllowHtml]
[UIHint("tinymce_full_compressed")]
public string Description
{ get; set; }
[Display(Name = "Meta Keywords")]
[DefaultValue (" ")]
public string Meta
{ get; set; }
public string UrlSlug
{ get; set; }
public bool Published
{ get; set; }
public DateTime? PostedOn
{ get; set; }
public DateTime? Modified
{ get; set; }
public int? CategoryID { get; set; }
public Category Category
{ get; set; }
[NotMapped]
public HttpPostedFileBase uploadedFile { get; set; }
public string mainImagePath { get; set; }
public virtual ICollection<Tag> Tags
{ get; set; }
}
ViewModel:
public class CreateProjectViewModel
{
public KitchenItem KitchenItem { get; set; }
[Display(Name = "Upload Image")]
public HttpPostedFileBase[] ImagesFiles { get; set; }
public Image[] Images { get; set; }
public int CategoryID { get; set; }
public int[] imageDeletes { get; set; }
}
Create Post:
[HttpPost]
[Authorize]
[ValidateAntiForgeryToken]
public ActionResult Create(CreateProjectViewModel viewModel)
{
KitchenItem model = new KitchenItem();
model = viewModel.KitchenItem;
try
{
/*
*Create ID from total Images to allow for specific folders to be created when file saved, iteration (totalImages)
*Calls for loop for each element of array to ensure that specific titles and tags are associated to correct image
* Add image to model collection to be saved to db
*/
List<Image> imgCollection = new List<Image>();
int totalKitchenItems = unitofWork.KitchenItemRepository.dbSet.Count() + 1;
//update model images
model.Images = handleEditImage(viewModel.ImagesFiles, viewModel.Images, imgCollection, model.Id);
//Log date posted
model.PostedOn = DateTime.Now;
Category cat = new Category();
model.Category = unitofWork.CategoryRepository.GetByID(viewModel.CategoryID);
//create post
unitofWork.KitchenItemRepository.Insert(model);
unitofWork.Save();
return RedirectToAction("Index");
}
catch (DbEntityValidationException dbEx)
{
foreach (var validationErrors in dbEx.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
Trace.TraceInformation("Class: {0}, Property: {1}, Error: {2}",
validationErrors.Entry.Entity.GetType().FullName,
validationError.PropertyName,
validationError.ErrorMessage);
}
foreach (var eve in dbEx.EntityValidationErrors)
{
Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
eve.Entry.Entity.GetType().Name, eve.Entry.State);
foreach (var ve in eve.ValidationErrors)
{
Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
ve.PropertyName, ve.ErrorMessage);
}
}
}
PopulateCategoriesDropDownList(0);
return RedirectToAction("Index");
}
}
Handle Image & Add Image Functions:
public ICollection<Image> handleEditImage(HttpPostedFileBase[] imageFiles, Image[] images, ICollection<Image> modelImages, int modelID)
{
/*
*Create ID from total Images to allow for specific folders to be created when file saved, iteration (totalImages)
*Calls for loop for each element of array to ensure that specific titles and tags are associated to correct image
* Add image to model collection to be saved to db
*/
List<Image> imgCollection = new List<Image>();
for (int i = 0; i < 5; i++)
{
Image uploadImage = new Image();
//check to make sure there is an image
if (imageFiles[i] != null)
{
//handle httppostedfilebase conversion to image file and add Url to image model
uploadImage = AddImage(imageFiles[i], images[i], modelID);
//Add img to be updated to model
imgCollection.Add(uploadImage);
}
}
if (modelImages != null)
{
//check for deleted images
foreach (var img in modelImages)
{
//loop through image array to determine whether image is currently assigned to model
for (int i = 0; i < 5; i++)
{
if (images[i].ImageUrl != null)
{
//replace string element modified before passed to view
images[i].ImageUrl = images[i].ImageUrl.Replace("../../", "~/");
}
if (img.ImageUrl == images[i].ImageUrl)
{
imgCollection.Add(img);
}
}
}
}
return imgCollection;
}
public Image AddImage(HttpPostedFileBase imageToSave, Image modelImage, int Id)
{
Image img = new Image();
img = modelImage;
img.ImageUrl = SaveUploadedFile(imageToSave, Id);
unitofWork.ImagesRepository.Insert(img);
return img;
}
I'm working on my first MVC 4 app, following the MVC First Web API Tutorial on Asp.net. I've left the names the same, but changed the model and controller code. Here's my model:
public class Product
{
public string SID { get; set; }
public string name { get; set; }
public string givenName { get; set; }
public string sn { get; set; }
public string mail { get; set; }
public string telephoneNumber { get; set; }
public string mobile { get; set; }
public string otherMobile { get; set; }
public string title { get; set; }
public string Manager { get; set; }
public DateTime whenChanged { get; set; }
}
public class ProductModel
{
public ProductModel()
{
ProductList = new List<Product>();
}
public IList<Product> ProductList { get; set; }
}
And here's my APIcontroller:
public class ProductsController : ApiController
{
ProductModel products = new ProductModel();
public IEnumerable<Product> GetAD()
{
DirectoryEntry domainRoot = new DirectoryEntry(LDAP_server);
DirectorySearcher searcher = new DirectorySearcher(searchStr);
SearchResultCollection results = searcher.FindAll();
foreach (SearchResult srchResult in results)
{
DirectoryEntry dirEntry = srchResult.GetDirectoryEntry();
if (dirEntry.Properties["givenName"].Value != null && dirEntry.Properties["sn"].Value != null && !dirEntry.Parent.Name.Contains("Terminated"))
{
products.ProductList.Add(new Product()
{
SID = dirEntry.Properties["sid"].Value.ToString(),
name = dirEntry.Properties["name"].Value.ToString(),
givenName = dirEntry.Properties["givenName"].Value.ToString(),
sn = dirEntry.Properties["sn"].Value.ToString(),
mail = dirEntry.Properties["mail"].Value.ToString(),
telephoneNumber = dirEntry.Properties["telephoneNumber"].Value.ToString(),
mobile = dirEntry.Properties["mobile"].Value.ToString(),
otherMobile = dirEntry.Properties["otherMobile"].Value.ToString(),
title = dirEntry.Properties["title"].Value.ToString(),
Manager = dirEntry.Properties["Manager"].Value.ToString(),
whenChanged = Convert.ToDateTime(dirEntry.Properties["whenChanged"].Value.ToString()),
});
}
}
return products.ProductList;
}
}
I'm getting the NullException on 'products.ProductList.Add(new Product()', am I missing something simple? Please forgive my coding, as I'm just trying to get this up and running, thanks.
the problem mostly likely is dealing with dirEntry, not Web API itself. rather than introduce LDAP into this, just create a bunch of dummy products to return.
FYI... there is also a memory leak issue with the use of LDAP objects. They need to be properly disposed of, both along the happy path and if an exception is thrown.
I'm an idiot. 'sid' is not the correct property name from AD, it is 'objectSid', thus always returning a null. I knew it was something simple.
I'm working on my first project using ASP MVC3. My application is code first using entity framework 4.1 and SQL server CE.
The application is a document library. The main model is Document which is a path to a pdf file and a bunch of metadata.
I have a "replace" function in my controller that takes one Document record, moves the file to an archive location, and updates the database with information about the replacement.
I am trying to store a list of strings with the document that represent filepaths to older versions of the same document.
No matter what I cannot get this list, called ArchivedFilePaths, to be anything but "null".
Model:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
namespace DocLibrary.Models
{
public class Document
{
public int DocumentId { get; set; }
public int CategoryId { get; set; }
public string DocumentCode { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string FileUrl { get; set; }
public int FileSize { get; set; }
public string FileSizeString { get; set; }
public int Pages { get; set; }
public string Creator { get; set; }
public int Revision { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime LastModifiedDate { get; set; }
public virtual Category Category { get; set; }
public List<String> ArchivedFilePaths { get; set; }
public SoftwareVersion SoftwareVersion { get; set; }
}
Controller:
public ActionResult Replace(HttpPostedFileBase file)
{
if (file != null && file.ContentLength > 0)
{
int id = Int32.Parse(Request["DocumentId"]);
Document doc = docsDB.Documents.Find(id);
//move the current version to the ~/Archive folder
string current_path = Path.Combine(Server.MapPath("~/Files"), Path.GetFileName(doc.FileUrl));
string archiveFileName = Path.GetFileNameWithoutExtension(doc.FileUrl) + "-" + doc.Revision.ToString() + ".pdf";
string destination_path = Path.Combine(Server.MapPath("~/Archive"), archiveFileName);
System.IO.File.Move(current_path, destination_path);
if (doc.ArchivedFilePaths == null)
{
doc.ArchivedFilePaths = new List<String>();
}
doc.ArchivedFilePaths.Add(destination_path);
//there are a bunch of statements that update the title, number of pages, etc. here, all of these work fine
try
{
docsDB.Entry(doc).State = EntityState.Modified;
docsDB.Logs.Add(new Log { LogDate = DateTime.Now, LogText = "Document replaced with a new version: " + doc.Title, });
docsDB.SaveChanges();
return RedirectToAction("Index");
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
//if a file was not selected;
return RedirectToAction("Index");
}
The Index view displays all of the files and their properties, including ArchivedFilePaths. After replacing a document with a new file, all of the items in the Document model update properly except ArchivedFilePaths.
If I inspect the list in VisualStudio, it is not null after the doc.ArchivedFilePaths.Add statement. So I don't believe the list is ever saved in the database and I suspect there is something wrong with my model. If I change it to a single string I can update it just fine.
Does anyone have any insight? Thanks.