所以,我已经转移到了MVC3,总的来说我觉得这很棒;我也非常喜欢codefirst方法。
我今天遇到了一些麻烦,而在MVC2下,我能够添加记录并编辑它们,我现在无法这样做。
我知道这是一个模糊的开始,所以请允许我进行阐述。
以下是我的某个模特的示例
namespace ESF_ResourceManager.Models
{
public class FileList
{
[Key]
public int FileListID { get; set; }
[DisplayName("File title: ")]
[Required(ErrorMessage = "Please set a unique title for the file")]
// TODO: Need to add remote validation - must be unique
public string FileTitle { get; set; }
[DisplayName("Choose a File")]
[FileExtensions(Extensions = "txt, zip, pdf, ppt, xls, doc, docx, xlsx, pptx", ErrorMessage = "Please choose a valid file of type txt, zip, pdf, ppt, xls, doc, docx, xlsx or pptx")]
public HttpPostedFileBase FileUrl { get; set; }
}
}
然后是相应的控制器:
namespace ESF_ResourceManager.Controllers
{
public class FileListController : ResourceManagerController
{
//
// GET: /FileList/
public ActionResult Index()
{
var fileList = from fl in DBContext.FileLists
where fl.FileListID > 0
select fl;
return View(fileList.ToList());
}
//
// GET: /FileList/Create
[HttpGet]
public ActionResult Create()
{
return View();
}
//
// POST: /FileList/Create
[HttpPost]
public ActionResult Create(FileList fileDetail)
{
if (ModelState.IsValid)
{
// test the file - size only - the file type should have been checked via Extensions as par tof the model definition
if (fileDetail.FileUrl.ContentLength > 0 && fileDetail.FileUrl.ContentLength < 1048576)
{
string fileName = Path.GetFileName(fileDetail.FileUrl.FileName);
string path = Path.Combine(Server.MapPath("~/App_Data/uploads/documents"), fileName);
fileDetail.FileUrl.SaveAs(path);
DBContext.FileLists.Add(fileDetail);
DBContext.SaveChanges();
return RedirectToAction("Index");
}
}
return View(fileDetail);
}
//
// GET: /FileList/Edit/5
[HttpGet]
public ActionResult Edit(int id)
{
var fileDetail = from fl in DBContext.FileLists
where fl.FileListID == id
select fl;
return View(fileDetail.Single());
}
//
// POST: /FileList/Edit/5
[HttpPost]
public ActionResult Edit(int id, FileList fileDetail)
{
if (ModelState.IsValid)
{
var fileEdited = DBContext.FileLists.Find(id);
UpdateModel(fileEdited);
DBContext.SaveChanges();
return RedirectToAction("Index");
}
return View();
}
//
// GET: /FileList/Delete/5
public ActionResult Delete(int id)
{
var fileDetail = from fl in DBContext.FileLists
where fl.FileListID == id
select fl;
return View(fileDetail.Single());
}
//
// POST: /FileList/Delete/5
[HttpPost]
public ActionResult Delete(int id, FileList fileDetail)
{
try
{
DBContext.FileLists.Remove(DBContext.FileLists.Find(id));
DBContext.SaveChanges();
return RedirectToAction("Index");
}
catch
{
return View();
}
}
}
}
Razor的视图是(用于创建):
@model ESF_ResourceManager.Models.FileList
@{
ViewBag.Title = "File List";
Layout = "~/Views/Shared/_Layout.cshtml";
}
@using (Html.BeginForm("Create", "FileList", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
@Html.ValidationSummary(true)
<fieldset>
<legend>File List</legend>
<div class="editor-label">
@Html.LabelFor(model => model.FileTitle)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.FileTitle)
@Html.ValidationMessageFor(model => model.FileTitle)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.FileUrl)
</div>
<div class="editor-field">
@Html.TextBoxFor(model => model.FileUrl, new { type = "file" })
@Html.ValidationMessageFor(model => model.FileUrl)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
因此,我可以加载视图并查看表单以输入数据,但是当我单击“创建”按钮时,我收到以下消息:
值不能为空。参数名称:key
我已经查看了调试器中的对象,并且进入create post函数的对象上没有任何内容为null。键是0,我希望(可能是错误的)这个为1。
所以我的第一个问题是我错过了什么?我需要做些什么才能让它适合我?
第二个问题更为笼统 - 我的数据在哪里?我读过的教程表明,无论是在某个地方创建了SQLExpress数据库,还是在App_Data中创建了一个SqlCE。我都找不到,所以我很困惑这是什么。
对此的任何帮助将不胜感激。
非常感谢 nathj07
修改
感谢您的到来,我仍在学习在提问时提供哪些内容会有所帮助。所以,这是请求的项目:
数据背景
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
namespace ESF_ResourceManager.Models
{
public class ResourceManagerContext : DbContext
{
public DbSet<Resource> Resources { get; set; }
public DbSet<ResourceType> ResourceTypes { get; set; }
public DbSet<User> Users { get; set; }
public DbSet<FileList> FileLists { get; set; }
}
}
的Web.Config
<?xml version="1.0"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=152368
-->
<configuration>
<appSettings>
<add key="webpages:Version" value="1.0.0.0"/>
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.0">
<assemblies>
<add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
</assemblies>
</compilation>
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" timeout="2880" />
</authentication>
<pages>
<namespaces>
<add namespace="System.Web.Helpers" />
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="System.Web.WebPages"/>
</namespaces>
</pages>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
最后 -
查看/ Web.config中
<?xml version="1.0"?>
<configuration>
<configSections>
<sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
</sectionGroup>
</configSections>
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
</namespaces>
</pages>
</system.web.webPages.razor>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<add path="*" verb="*" type="System.Web.HttpNotFoundHandler"/>
</httpHandlers>
<!--
Enabling request validation in view pages would cause validation to occur
after the input has already been processed by the controller. By default
MVC performs request validation before a controller processes the input.
To change this behavior apply the ValidateInputAttribute to a
controller or action.
-->
<pages
validateRequest="false"
pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<controls>
<add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" namespace="System.Web.Mvc" tagPrefix="mvc" />
</controls>
</pages>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<handlers>
<remove name="BlockViewHandler"/>
<add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
</handlers>
</system.webServer>
</configuration>
如果还有其他什么你需要看,那么我会高兴地发布它。
由于 nathj07
编辑2 我现在尝试手动添加SQLExpress数据库并更新web.config文件中的连接字符串。
<connectionStrings>
<remove name="LocalSqlServer"/>
<add name="LocalSqlServer" connectionString="Data Source=.\SQLExpress;Integrated Security=True;AttachDBFilename=|DataDirectory|DB_ESF_ResourceManager.mdf;User Instance=true" />
</connectionStrings>
这给我留下了同样的错误 - 完全没有区别。我完全失去了这个,并且不知道下一步该去哪里。还有其他建议吗?
由于 nathj07
答案 0 :(得分:1)
似乎EF没有将您的密钥标记为标识列。如果类型为int
,short
或long
,且名称为<classname>Id
,则实体框架会将属性标记为主键。在您的模型上,“ID”部分为大写。您有两种可能的解决方案:
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
置于您的财产之上,以表明它实际上是一个标识列FileListID
重命名为FileListId
。如果你选择这个解决方案,你可能不再需要[Key]
属性。如果您选择第一个解决方案,您的财产将如下所示:
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int FileListID { get; set; }
答案 1 :(得分:0)
你需要为mvc make bind添加FileListID
@Html.HiddenFor(model => model.FileListID)
答案 2 :(得分:0)
你的第二个问题:
因为web.config文件中没有任何连接字符串,所以如果数据库不存在,Entity Framework 4.1将尝试在SQL Server Express实例中创建新数据库。此数据库的名称是 Namespace.DerivedContextName ,因此在您的情况下应该是: ESF_ResourceManager.Models.ResourceManagerContext 。
您可以使用SQL Server Management Studio或Visual Studio通过服务器资源管理器查看数据库。
你的第一个问题:
您收到错误的一个可能原因是数据库中与模型中的键属性FileListID
对应的键列未标记为标识列,即作为自动生成其自身值的列当您插入新行时。您的模型配置假定该列是标识(默认情况下,您没有将其关闭)。因此,当您插入新对象时,EF不会向数据库发送FileListID
的值,因为它假定数据库将创建一个值。如果数据库中的列不是标识,则它不会创建值,您将获得异常。
因此,您应该在数据库中检查FileListID
是否为标识列,如果不是,请将其打开。