asp.net mvc 4.0常见的几个问题
看书的时候遇到很多不知所云的错误,都是在网上找到的解决方法,没办法,从asp.net到mcv很多的新技术,没有一点思路,只能在网上搜罗了。
1.更新产品不成功
更新产品的时候一直不能更新成功,但是很奇怪的是添加是没问题的,看到网上说再更新的时候要通知EF当前执行的是更新动作,加上context.Entry(product).State = System.Data.EntityState.Modified;这句,这不扯淡么,我添加的时候也没有要通知EF要Add呀,下面是代码。最后在删除的时候也加上context.Entry(product).State = System.Data.EntityState.Deleted;。
例子是书里的一个SportsStore实例,更新的方法在AdminController里
代码:
[HttpPost]
public ActionResult Edit(Product product,HttpPostedFileBase image)
{
if (ModelState.IsValid)
{
if (image != null)
{
product.ImageMimeType = image.ContentType;
product.ImageData = new byte[image.ContentLength];
image.InputStream.Read(product.ImageData, 0, image.ContentLength);
}
try
{
repository.SaveProduct(product);
}
catch (Exception ex)
{
throw ex;
}
TempData["message"] = string.Format("{0} has been saved", product.Name);
return RedirectToAction("Index");
}
else
{
return View(product);
}
}
这段代码没有问题,有问题的是下面这段代码:
public class EFProductRepository : IProductsRespository
{
private EFDbContext context = new EFDbContext(); public IQueryable<Product> Products
{
get { return context.Products; }
} public void SaveProduct(Product product)
{
if (product.ProductID == 0)
{
context.Products.Add(product);
context.Entry(product).State = System.Data.EntityState.Added;
}
//else
// {
// context.Entry(product).State = System.Data.EntityState.Modified;
// } context.SaveChanges();
} #region IProductsRespository 成员 public void DeleteProduct(Product product)
{
context.Products.Remove(product);
context.SaveChanges();
} #endregion
}
书中的代码是没有注释的那几行的,因为Product没有改变,数据库因此没有更新。必须去掉注释行,告诉context,Product的内容已经发生改变,才能正常地更新到数据库里。
2.这里讲到登陆
作者为了偷懒,没有将账号密码存放到数据库中,而是在web.config里面添加了以下节点,意思是暂时用admin这个账号应付一下,结果使用bool result = FormsAuthentication.Authenticate(username, password);这句来验证的时候老是验证失败,擦!书上命名就是这么写的,后来去官网看看FormsAuthentication.Authenticate这个方法,看到人家添加这个节点的时候再credentials这里加了一个passwordFormat="SHA1",是加密方式,我这里没有加密,难道需要声明一下,于是照葫芦画瓢加了一个<credentials passwordFormat="Clear">就是不加密的意思吧,结果果然可以验证通过,各位屌丝程序员有幸看到这里不妨模仿一下,没办法,谁叫我是小白呢。
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" timeout="2880" >
<credentials>
<user name="admin" password="secret"/>
</credentials>
</forms>
</authentication>
3.书中讲到给Product添加两个字段的时候要更新SportsStore.edmx这个文件,这不扯淡么 , 我向上全文搜索没有什么地方提到这个文件,后来在http://www.cnblogs.com/r01cn/archive/2012/06/20/2555348.html这篇博客中看到博友说道下面的话,恍然大悟,这书的作者大概糊涂了,又或者不是同一个人写的。
注:本小节是多余的,在SportsStore应用程序中不需要做这部分工作。而且,如果做了,会出现错误 — 译者注
4.上传图片
这里想上传一个图片但是作者定义数据类型public byte ImageData { get; set; },先不说在数据库里面存文件怎么样,但是这样一个byte存不下一张图片吧,应该是
public byte[] ImageData { get; set; }。到返回产品数据的时候就麻烦了因为不能直接从二进制数组中读出图片来需要专门写一个获取图片的方法,返回类型是FileContentResult,这是不是找抽呢,返回的产品过多时会很慢的呢,所以说叫教材就是教材,要照这上面的方法做项目,肯定是做不成了。
public FileContentResult GetImage(int productId)
{
Product prod = repository.Products.FirstOrDefault(p => p.ProductID == productId);
if (prod != null)
{
return File(prod.ImageData, prod.ImageMimeType);
}
else
{
return null;
}
}
5.我擦!
又遇到这个问题了The model backing the 'EFDbContext' context has changed since the database was created. Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269).这个需要删除数据库重新建。
网上说这个需要在Globa.asax.cs中的Application_Start()方法下添加Database.SetInitializer<EFDbContext>(null);这个方法,无奈加进去之后提示找不到Database这个类,还需要在SportsStore.WebUI这个项目中添加EntityFramework,但是我使用Nugget工具添加后显示版本不对,得知SportsStore.Domain这个里面已经添加了EntityFramework但是版本是4.0的,没办法还是通过Nugget将已有的都删掉,然后再下载最新的,在SportsStore.WebUI,SportsStore.Domain两个项目中都执行这个操作,最后搞定了,有点蛋疼啊。
最后来看看这个方法的原型:
//
// 摘要:
// Sets the database initializer to use for the given context type. The database
// initializer is called when a the given System.Data.Entity.DbContext type
// is used to access a database for the first time. The default strategy for
// Code First contexts is an instance of System.Data.Entity.CreateDatabaseIfNotExists<TContext>.
//
// 参数:
// strategy:
// The initializer to use, or null to disable initialization for the given context
// type.
//
// 类型参数:
// TContext:
// The type of the context.
public static void SetInitializer<TContext>(IDatabaseInitializer<TContext> strategy) where TContext : DbContext;
参数为null的时候不再实例化上下文。可以这么理解么?
6.路由
一定要在Global.asax里面定义一个路由,要不然整个MVC程序都不知道如何找到控制器,方法进而访问页面。mvc中会有多个路由模型,请求的时候用url去匹配,第一个符合的就返回。
我们可以给一个路由默认值,默认的controller和action,记住这两个单词是不能错的,如下。
routes.MapRoute("MyRoute", "{controller}/{action}", new { controller = "Home", action = "Index" });
还有一个很有意思的地方
routes.MapRoute("", "X{controller}/{action}");
routes.MapRoute("MyRoute", "{controller}/{action}", new { controller = "Home", action = "Index" });
routes.MapRoute("MyRoute1", "Public/{controller}/{action}");
假设有上面三个路由模式,只要有一个路由模式提供了默认值其他的模式都可以访问
http://localhost/UrlsAndRoutes可以访问,因为第二个提供了默认值,http://localhost/UrlsAndRoutes/Public/Home/Index可以,http://localhost/UrlsAndRoutes/XHome/Index这个也可以,因为第二个路由模式已经提供了默认值。
7.传参
这个是我一直比较好奇的一个东西,mvc里面没有request.querystring,request.form这些东西,怎么接受参数了,看到这里有一个使用路由模式定义参数的方法,有点不灵活。
routes.MapRoute("MyRoute", "{controller}/{action}/{name}/{id}", new { controller = "Home", action = "Index"});比如这个路由模式定义了两个参数name和id注意这里参数不再是?key1=value1&key2=value2... 这样的方式了,而是使用/来间隔,注意不能使用controller,action,area这样的关键字来定义参数名字,很显然他们已经有特别的意义了啊。
http://localhost/UrlsAndRoutes/home/index/asdfas/asdfas这里我传了两个参数,在home控制器里面可以使用RouteData.Values[""]这样的变量来接受参数,这个倒是和request.form很相像。如下:
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.name = RouteData.Values["name"];
ViewBag.id = RouteData.Values["id"];
return View();
}
}
在视图里面可以直接使用ViewBag.name和ViewBag.id这样的变量来进一步接受数据,这里还用接受数据这个称呼,在我看来最终要把这个数据展示出来,都是接受数据,最后在视图里面展示,
@{
ViewBag.Title = "Home Page";
}
<h2>@ViewBag.name @ViewBag.id</h2>
<p>
</p>
然后我们在页面就可以看到这两个变量了。这个过程倒是可以理解。
有个疑问呢,如果第一个name不想传递该怎么办了,?? 这不是很傻比么,有人会说给自定义值,就在那个路由模式里面给,是个好方法,但是每次都去改这个路由模式么?UrlParameter.Optional这个选项给出了答案,在定义默认值的时候可以使用这个选项来告诉mvc这个参数可以不传的哦。
这里又讲到直接把参数传递给action方法,只要action方法中的参数名字和路由模式里面定义的参数名字一致就可以。例如路由里面定义第一个参数叫namea
routes.MapRoute("MyRoutea", "{controller}/{action}/{namea}/{id}");
只有参数名字不一样,为了和上面的区分所以我又定义了一个action
public ActionResult Indexa(string namea, string id)
{
//ViewBag.name = RouteData.Values["name"];
//ViewBag.id = RouteData.Values["id"];
ViewBag.name = namea;
ViewBag.id = id;
return View();
}
这回参数名字用namea,访问路径http://localhost/UrlsAndRoutes/home/Indexa/sssss/aaaa得到结果如下:
这句解释了原理:
The MVC Framework compares the list of segment variables with the list of action method parameters, and if the names match, passes the values from the URL to the method.
8.传参,碎碎念
如果传递的参数过多的话是不是会很烦人呢,路由中可以定义任意长度参数,简单点说就是把多个参数放在一个字符串里,得到之后自己再分割。如此种种我们定义了一个新的路由模式routes.MapRoute("", "x{controller}/{action}/{id}/{*catchall}", new { id = "DefaultId" });,这里使用了静态片段x,然后action方法定义了
public ActionResult Index(string name, string id, string catchall)
{
//ViewBag.name = RouteData.Values["name"];
//ViewBag.id = RouteData.Values["id"];
ViewBag.name = name;
ViewBag.id = id;
ViewBag.cactchall = catchall;
return View();
}
asp.net mvc 4.0常见的几个问题的更多相关文章
- ASP.NET MVC 4.0中选择Windows 验证默认出错拒绝访问的原因和解决方案
在VS 2012或者2013 中,根据模板创建一个ASP.NET MVC 4.0的应用程序,选择下面的模板 然后选择Intranet Application 不对源代码做任何修改,直接按下F5调试,会 ...
- 安装了VS2010 sp1 后再安装ASP.NET MVC 3.0的问题
安装了VS2010 sp1 后再安装ASP.NET MVC 3.0的问题(Final Result: Installation failed with error code: (0x80070643) ...
- (转)ASP.NET Mvc 2.0 - 1. Areas的创建与执行
转自:http://www.cnblogs.com/terrysun/archive/2010/04/13/1711218.html ASP.NET Mvc 2.0 - 1. Areas的创建与执行 ...
- 返璞归真 asp.net mvc (13) - asp.net mvc 5.0 新特性
[索引页][源码下载] 返璞归真 asp.net mvc (13) - asp.net mvc 5.0 新特性 作者:webabcd 介绍asp.net mvc 之 asp.net mvc 5.0 新 ...
- ASP.NET MVC 3.0 Controller基础
ASP.NET MVC 3.0 Controller基础 1.Controller类与方法 Controller(控制器)是ASP.NET MVC的核心,负责处理浏览器请求,并作出响应.Cotro ...
- 从零开始学习ASP.NET MVC 1.0
转自:http://www.cnblogs.com/zhangziqiu/archive/2009/02/27/ASPNET-MVC-1.html <从零开始学习ASP.NET MVC 1.0& ...
- ASP.NET MVC 4.0的Action Filter
有时候你想在调用action方法之前或者action方法之后处理一些逻辑,为了支持这个,ASP.NET MVC允许你自定义创建action过滤器.Action过滤器是自定义的Attributes,用来 ...
- 安装了VS2010 sp1 后再安装ASP.NET MVC 3.0的问题(Final Result: Installation failed with error code: (0x80070643), "安装时发生严重错误 " (Ela)
原文:安装了VS2010 sp1 后再安装ASP.NET MVC 3.0的问题(Final Result: Installation failed with error code: (0x800706 ...
- 返璞归真 asp.net mvc (7) - asp.net mvc 3.0 新特性之 Controller
原文:返璞归真 asp.net mvc (7) - asp.net mvc 3.0 新特性之 Controller [索引页][源码下载] 返璞归真 asp.net mvc (7) - asp.net ...
随机推荐
- 【ES6】var、let、const三者的区别
首先,一个常见的问题是,ECMAScript 和 JavaScript 到底是什么关系? ECMAScript是一个国际通过的标准化脚本语言.JavaScript由ECMAScript和DOM.BOM ...
- Java入门系列-20-异常
为什么要进行异常处理 下面这段代码能否正常执行 public class DemoCalc { public static void main(String[] args) { int a=0; in ...
- Codeforces 543E. Listening to Music
Description 题面 Solution 分块套分块,分别对时间和位置进行分块 差不多是一个定期保存信息的方法 对于询问我们不妨求出 \(>=x\) 的答案,然后用 \(m-(>=x ...
- out参数
out参数: 参数在方法的内部必须为其赋值:可以同时返回不同类型的值: 在Main方法里定义,在方法里赋值: 输 ...
- .net core 第二篇控制台程序项目初步学习
1. 使用vscode 创建一个控制台程序 创建项目默认创建的项目名称为父级文件夹名称 后面学习下创建的命令各个参数说明 运行项目dotnet run 其他命令SDK 命令:add 将包或引用添加到 ...
- 《MySQL 基础课程》笔记整理(进阶篇)(未完)
一.MySQL服务安装及命令使用 安装过程就不写了,毕竟百度经验一大把 MySQL 官方文档 MySQL 参考手册中文版 1.MySQL简介 RDBMS(Relational Database M ...
- Java---工欲善其事必先利其器(准备篇)
Java API 1.7链接:http://pan.baidu.com/s/1cKUaKY 密码:116m Eclispse链接:http://pan.baidu.com/s/1mh6MoL6 密码: ...
- 一、linux下安装redis(单机)
1.下载redis,http://download.redis.io/releases/redis-3.2.7.tar.gz 2.linux我用的是centos6.5 3.把redis上传到cento ...
- 基于easyUI实现权限管理系统(三)——角色管理
此文章是基于 EasyUI+Knockout实现经典表单的查看.编辑 一. 相关文件介绍 1. role.jsp:角色管理界面 <!DOCTYPE html PUBLIC "-//W3 ...
- TCP keepalive长连接心跳保活
比如:客户端与服务端进行握手时,经常无法握手成功,收不到回复: 需要建立保活机制. 1. 服务端Linux服务器新增系统内核参数配置. 在/etc/sysctl.conf文件中再添加如: #允许的持续 ...