在Professional ASP.NET MVC 1.0的NerdDinner示例中,有一种方法可以创建一个新的晚餐,如下所示(免费的NerdDinner版本的第89页).
在那里它检查ModelState.IsValid为true.它似乎检查模型是否对数据库有效(即,它捕获数据类型转换,例如具有无效格式但不是业务规则的日期).真的吗?
提交表单时,如果日期中有错误,ModelState.IsValid将为false并且您将返回错误,但仅限于日期,因为从未执行过AddRuleViolations.如果您完全删除对ModelState.IsValid的检查,那么您将获得所有错误(由于异常),包括无效日期中的标记.那么,为什么要检查ModelState.IsValid呢?我错过了什么吗?
//
// POST: /Dinners/Create
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(Dinner dinner) {
if (ModelState.IsValid) {
try {
dinner.HostedBy = "SomeUser";
dinnerRepository.Add(dinner);
dinnerRepository.Save();
return RedirectToAction("Details", new {id = dinner.DinnerID });
} catch {
ModelState.AddRuleViolations(dinner.GetRuleViolations());
}
}
return View(dinner);
}
Run Code Online (Sandbox Code Playgroud) 我正在寻找使用ASP.NET MVC NerdDinner教程学习ASP.NET MVC和OpenId.
我想将NerdDinner中的身份验证系统替换为仅OpenId.我已经下载了最新的DotNetOpenAuth库,但我不知道如何将它们放在一起.任何人都可以帮助快速一步一步的教程吗?
这是否像在库中删除一样简单,还是应用程序需要进行重大更改?
我正在使用ASP.NET MVC设计一个网站,对于存储库的确切性质可能有点困惑.
在NerdDinner示例之后,我的站点应该有一个存储库,根据需要提供实体.但是,我也听说你应该有不同的存储库来处理特定的相关实体集....
在我的网站的情况下,将有许多实体(大约15个表)但大多数都是相关的.有一个存储库包含拉动/更新/删除等所需的所有方法,或者我应该将它们拆分,这是否可取/可取?
尝试实现分页支持后,我收到此错误.
我正在进行 html教程的这一步:http://nerddinnerbook.s3.amazonaws.com/Part8.htm
考虑一个处理依赖注入的初学者.我们正在分析NerdDinner中的两个相关类.
来自应用程序的DinnerRepository:

来自测试的FakeDinnerRepository:

它们实现了不同的逻辑,这当然是必要的,因为这里的关键思想是实现IDinnerRepository,并提供不同的实现和私有成员.
我理解测试是针对控制器的,但我担心数据访问逻辑有两种不同的实现.考虑使用任何类型的ORM,ADO.NET,SubSonic或任何您喜欢的数据访问类型的项目.是的,您可以设置您的假存储库以匹配真实的存储库.
我担心的是,随着时间的推移,真正的回购中的实施细节会发生变化.也许打字错误,或查询中的一些其他重要的实现细节更改.这导致模型中的假设与真实仓库之间的逻辑可能不匹配.担心的是真正的repo和test repo的实现变得不同步.
问题:
unit-testing dependency-injection inversion-of-control nerddinner
题
创建假货时如何处理只读字段?
背景
我正处于使用ASP.Net MVC的初学阶段,我正在使用Steven Sanderson的体育用品店和Scott Gu的书呆子晚餐作为例子.我刚刚遇到的一个小问题是如何在做假货时使用只读属性.我正在使用LINQToSQL.
我的界面是:
public interface IPersonRespository
{
Person GetPerson(int id);
}
Run Code Online (Sandbox Code Playgroud)
而我的假装变成了
public class FakePersonRepository
{
public Person GetPerson(int id)
{
return new Person {id="EMP12345", name="John Doe", age=47, ssn=123-45-6789, totalDrWhoEpisodesWatched=42};
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的问题.字段id,ssn和totalDrWhoEpisodesWatched是只读的,因此上面的代码实际上不起作用.但是,我不知道如何创建假新人并设置只读属性.我确信有一个解决方案,但我在搜索中还没有遇到过它.
更新:继承+属性隐藏为潜在的解决方案?
我还没有决定解决这个问题.我不喜欢为了创造假货而修改我的Domain类的概念.对我来说,为了进行测试而向域类添加标记是一种额外的耦合形式 - 与测试的实现相结合.我现在正在研究另一种可能性,即创建一个继承自Person的FakePerson类,但使用新的读写属性隐藏属性.
public class FakePerson: Person
{
public new int age { get; set; }
public new string ssn { get; set; }
public new int totalDrWhoEpisodesWatched { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,这个解决方案就是我的倾向.它确实打破了Liskov替换原则,但是这并没有在测试项目中给我带来太多麻烦.我很高兴听到任何批评和/或反馈作为解决方案.
获奖者:模拟框架
Moq似乎完成了这项工作.事实上,我通过继承隐藏属性的最后一个解决方案确实有效,但是通过使用Moq,我获得了一组更易于维护的标准化功能.我假设其他模拟框架具有此功能,但我没有检查.据说Moq开始模拟写作更直接,我现在肯定是这样.
在Microsoft的MVC教程NerdDinners的代码中:
公共类DinnerRepository {
Run Code Online (Sandbox Code Playgroud)private NerdDinnerDataContext db = new NerdDinnerDataContext(); // // Query Methods public IQueryable<Dinner> FindAllDinners() { return db.Dinners; } public IQueryable<Dinner> FindUpcomingDinners() { return from dinner in db.Dinners where dinner.EventDate > DateTime.Now orderby dinner.EventDate select dinner; } public Dinner GetDinner(int id) { return db.Dinners.SingleOrDefault(d => d.DinnerID == id); } // // Insert/Delete Methods public void Add(Dinner dinner) { db.Dinners.InsertOnSubmit(dinner); } public void Delete(Dinner dinner) { db.RSVPs.DeleteAllOnSubmit(dinner.RSVPs); db.Dinners.DeleteOnSubmit(dinner); } // // Persistence public void Save() { db.SubmitChanges(); }}
什么: …
NerdDinner.csproj不会在带有.net 3.5 sp1的vs2008 sp1中加载.我不是最新的这些工具或东西?它抱怨此安装不支持此项目类型.
我正在阅读NerDinner免费教程 http://nerddinnerbook.s3.amazonaws.com/Intro.htm
我到了第5步的某个地方,它说要使代码更清晰,我们可以创建一个扩展方法.我查看完成的代码,并使用扩展方法:
catch
{
ModelState.AddModelErrors(dinner.GetRuleViolations());
return View(new DinnerFormViewModel(dinner));
}
Run Code Online (Sandbox Code Playgroud)
然后这作为扩展方法的定义.
namespace NerdDinner.Helpers {
public static class ModelStateHelpers {
public static void AddModelErrors(this ModelStateDictionary modelState, IEnumerable<RuleViolation> errors) {
foreach (RuleViolation issue in errors) {
modelState.AddModelError(issue.PropertyName, issue.ErrorMessage);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试按照教程所说的结合代码包含的内容,但收到预期的错误,即没有AddModelErrors方法只接受1个参数.
我显然在这里缺少一些非常重要的东西.它是什么?
我正在学习ASP.NET MVC,我喜欢它.但是,我对使用命名空间模型的正确方法感到非常困惑.
在剖析NerdDinner示例应用程序时,我注意到Models文件夹中的所有内容都属于Models命名空间.数据映射类,存储库,错误规则管理等属于相同的命名空间级别.
据我所知,这个文件夹的灵感来自像Rails和朋友这样的框架,并且需要证明MVC标题中的M是合理的; 自动模型命名空间是否会破坏编写可在不同系统和实现中分离和移植的业务逻辑的任何机会?
我应该将我的业务逻辑命名为此Model命名空间下面还是应该完全忽略它并以更加框架独立的方式对我的类进行分类?
是否有任何复杂和良好的ASP.NET MVC示例应用程序可以证明这一点?
nerddinner ×10
asp.net-mvc ×7
.net ×1
c# ×1
lambda ×1
repository ×1
tdd ×1
unit-testing ×1
validation ×1