我正在处理一个拍卖应用程序,我正在创建一个方法,以便管理员可以提交一个 excel 电子表格,该电子表格将创建一个新的拍卖并将其存储在数据库中。所以首先我做了一个类(模型(Uploadfile
这样:
[NotMapped]
public class UploadFile
{
[Required]
public HttpPostedFileBase ExcelFile { get; set; }
}
我使用NotMapped
是因为我试图了解如何创建和使用未存储在数据库中的模型,这就是我的问题和误解所在。
我创建了一个控制器,这是我手动完成的,因为UploadFile
不是具有键的实体:
public class FileUploadsController : Controller
{
private AuctionEntities db = new AuctionEntities();
// GET: FileUploads
public ActionResult Index()
{
UploadFile UploadFile = new UploadFile();
return View(UploadFile);
}
[HttpPost]
public ActionResult Index(UploadFile UploadFile)
{
if (ModelState.IsValid)
{
if (UploadFile.ExcelFile.ContentLength > 0)
{
if (UploadFile.ExcelFile.FileName.EndsWith(".xlsx") || UploadFile.ExcelFile.FileName.EndsWith(".xls"))
{
XLWorkbook wb;
// in case if the file is corrupt
try
{
wb = new XLWorkbook(UploadFile.ExcelFile.InputStream);
}
catch (Exception ex)
{
ModelState.AddModelError(String.Empty, $"Check your file. {ex.Message}");
return View();
}
IXLWorksheet ws = null;
try // in case the sheet you are looking for is not found
{
ws = wb.Worksheet("sheet1");
}
catch
{
ModelState.AddModelError(String.Empty, "Sheet not found");
return View();
}
var firstRowUsed = ws.FirstRowUsed();
var auctionRow = firstRowUsed.RowUsed().RowBelow();
// create auction
string auctionName = auctionRow.Cell(1).Value.ToString();
DateTimeOffset startDate = DateTimeOffset.Parse(auctionRow.Cell(2).Value.ToString());
DateTimeOffset endDate = DateTimeOffset.Parse(auctionRow.Cell(3).Value.ToString());
string folderName = auctionRow.Cell(4).Value.ToString();
Models.Auction auction = new Models.Auction(auctionName, startDate, endDate, folderName);
db.Auctions.Add(auction);
// find the next table
var nextRow = auctionRow.RowBelow();
while (nextRow.IsEmpty())
{
nextRow = nextRow.RowBelow();
}
const int catNameCol = 1;
var catRow = nextRow.RowUsed().RowBelow();
// get categories from ws table and add to the auction
while (!catRow.Cell(catNameCol).IsEmpty())
{
string catName = catRow.Cell(1).Value.ToString();
int seqNo = Convert.ToInt32(catRow.Cell(2).Value.ToString());
string fileName = catRow.Cell(3).Value.ToString();
Cat cat = new Cat(auction.AuctionId, catName, seqNo, fileName);
auction.Cats.Add(cat);
catRow = catRow.RowBelow();
}
var findNextRow = catRow.RowBelow();
while (findNextRow.IsEmpty())
{
findNextRow = findNextRow.RowBelow();
}
const int itemNameCol = 1;
var itemRow = findNextRow.RowUsed().RowBelow();
while(!itemRow.Cell(itemNameCol).IsEmpty())
{
string itemName = itemRow.Cell(1).Value.ToString();
string itemDesc = itemRow.Cell(2).Value.ToString();
string catName = itemRow.Cell(3).Value.ToString();
string modelNo = itemRow.Cell(4).Value.ToString();
decimal retailValue = Convert.ToDecimal(itemRow.Cell(5).Value.ToString());
string fileName = itemRow.Cell(6).Value.ToString();
decimal initialBid = Convert.ToDecimal(itemRow.Cell(7).Value.ToString());
decimal increment = Convert.ToDecimal(itemRow.Cell(8).Value.ToString());
Cat itemCat = null;
foreach(var cat in auction.Cats)
{
if(catName == cat.CatName)
{
itemCat = cat;
}
}
Item item = new Item(itemName, itemDesc, modelNo, retailValue, fileName, startDate, endDate, initialBid, increment, null, null, null, itemCat);
itemCat.Items.Add(item);
itemRow = itemRow.RowBelow();
}
}
else
{
ModelState.AddModelError(String.Empty, "Only .xlsx and .xls files are allowed");
return View();
}
}
else
{
ModelState.AddModelError(String.Empty, "Not a valid file");
return View();
}
}
db.SaveChanges();
return View();
}
接下来,我想我会尝试再次创建一个视图,以便我可以显示用户上传文件的位置,看看我的方法是否有效,这就是我在 asp.net 中遇到缺乏知识的地方。
因此,我尝试创建一个视图模型,因为我之前创建的模型是一个数据模型,以便我可以使用此视图模型在我的视图页面上显示上传的内容。我的视图模型很简单,是:
public class FileUploadViewModel
{
public HttpPostedFileBase ExcelFile { get; set; }
}
现在,我想为这个视图模型创建一个视图页面,它仍然在处理这个模型有一个实体,并给我一个错误,说它没有键等。我需要一个可以访问包含 Excel 文件的模型的视图页面,但我似乎无法弄清楚如何完成此操作。我已经阅读了视图模型,我知道它们在MVC中的重要性,但是我似乎无法掌握如何使用它们。有人可以帮我了解如何在这里使用吗?
基本上,我想将此视图页面与我的模型或视图模型一起使用:
我有根据的猜测是你被困在"添加视图"窗口中。
您可能正在选择一个需要模型的模板(例如Create
(,选择您的FileUploadViewModel
类作为模型以及您的上下文。
这样做会导致 Visual Studio"向导"尝试在内部将模型映射到上下文,从而导致您看到的错误。
相反,选择Empty (without model)
作为模板,这将使Model
和Data Context
字段变灰。然后,将创建您的视图,而不会出错。
然后,您可以通过在顶部添加以下内容来告诉视图需要您的模型:
@model FileUploadViewModel
确保您完全符合FileUploadViewModel
条件(例如,在前面包含命名空间(。
您的方法现在应使用您在视图顶部指定的模型:
public ActionResult Index()
{
FileUploadViewModel UploadFile = new FileUploadViewModel();
return View(UploadFile);
}
[HttpPost]
public ActionResult Index(FileUploadViewModel UploadFile)
{
}
您不需要此处任何地方的[NotMapped]
属性。