对于当前项目,我试图了解如何有效地利用Knockout 2.1.0,Upshot 1.0.0.2,ASP.NET MVC4和Entity Framework 4.3.有许多基本的架构问题似乎没有现成的答案.我列举了我的几个问题(在单独的帖子中),希望有人能够在我们尝试在实际应用程序中实现这种组合时为自己和他人提供合理的指导.
在史蒂夫桑德森在二月淘汰赛和Upshot.js在TechDays荷兰真棒演讲,他提到的结果可以容纳连接到服务器的多种方法.(如果您还没有看过演示文稿,那么值得观看.您可以在http://channel9.msdn.com/Events/TechDays/Techdays-2012-the-Netherlands/2159查看.)
不幸的是,他没有时间详细说明这些通信机制是什么或推荐的是什么以及在什么情况下.
根据Denver Developer在他的博客文章"挖掘到Upshot.js"(http://denverdeveloper.wordpress.com/2012/03/07/digging-into-upshot-js/)的说法,有三个数据提供者被公开Upshot.js.这些是:
•默认值为DataProvider(),并使用/ Submit方法和您提供的操作来使用jQuery的$ .ajax方法获取数据.(AG注意:我认为这通常与WebAPI公开的DbDataController对象有关,但我不确定它们的确有什么限制.)
•下一个是riaDataProvider() - 与第一个类似,但它使用/ json/SubmitChanges方法和/ json/{your opertion}来获取数据
•最后我们还有odataDataProvider() - 这个是完全不同的,因为它目前不支持更新数据 - 它是只读的.
关于选择典型用途的提供者,自然会出现许多密切相关的问题.
在相关的说明中,关于互联网上的结果的文档似乎很少.除了在upshot.js中浏览4700多行代码之外,这个库还有其他合适的文档来源吗?
到目前为止,我所查看的资源包括以下内容(以及更多内容).
来自Steve Sanderson的SPA演示的源代码(可从http://blog.stevensanderson.com/2012/03/06/single-page-application-packages-and-samples/获得).
Bart Jolling在他的文章"使用ASP.NET MVC4构建单页应用程序"(第1-4部分)中对Steve Sanderson的SPA演示应用程序的变化.http://bartjolling.blogspot.com/2012/04/building-single-page-apps-with-aspnet.html
来自ASP.NET站点的Big Shelf SPA演示代码 - http://www.asp.net/single-page-application/spa-samples/sample-bigshelf-application
Microsoft ASP.NET"A Tour through SPA"(主要关注结果样本) http://www.asp.net/single-page-application/spa-samples.
经过长时间的研究,我们决定使用Web API,EF + ASP.NET MVC 4 + Knockout + Breeze为我们的项目.但我们找不到Breeze的任何工作网格.我们希望将breeze实体绑定到网格,并能够在某些情况下编辑网格上的数据.
我们几乎每天尝试新的网格,但仍然没有运气,例如,我们尝试了jqxGrid(来自jqWidgets),但它在绑定数据时抛出异常(可能是因为实体之间的循环引用).如果我们不使用breeze实体并选择匿名类型它可以正常工作.
你有什么建议吗?
提前致谢.
如果我使用NorthindModel运行以下查询,来自breeze示例的NorthwindDataContext只会显示第一个导航属性.所有其他返回null:
var query = EntityQuery.from("OrderDetails")
.where("OrderID", "==", 11069)
.expand("Order.Customer", "Order.Employee");
manager.executeQuery(query).then(querySucceeded).fail(queryFailed);
function querySucceeded(data){
var customer = data.results[0].Order().Customer();
var employee = data.results[0].Order().Employee(); // returns null!!!!!
}
Run Code Online (Sandbox Code Playgroud)
如果我更改扩展参数列表中的顺序,而不是将customer设置为null:
var query = EntityQuery.from("OrderDetails")
.where("OrderID", "==", 11069)
.expand("Order.Employee", "Order.Customer");
manager.executeQuery(query).then(querySucceeded).fail(queryFailed);
function querySucceeded(data){
var customer = data.results[0].Order().Customer(); // returns null!!!!!
var employee = data.results[0].Order().Employee(); }
Run Code Online (Sandbox Code Playgroud)
这有什么问题?
不知道这是故意还是错误,但下面的代码使用BeforeSaveEntity只会修改新创建的记录的实体(EntityState =已添加),并且不能用于修改,这是正确的吗?
protected override bool BeforeSaveEntity(EntityInfo entityInfo)
{
var entity = entityInfo.Entity;
if (entity is User)
{
var user = entity as User;
user.ModifiedDate = DateTime.Now;
user.ModifiedBy = 1;
}
...
Run Code Online (Sandbox Code Playgroud) 我很难理解如何将Enum值转换为它的相应名称.我的模型如下:
public class CatalogRule
{
public int ID { get; set; }
[Display(Name = "Catalog"), Required]
public int CatalogID { get; set; }
[Display(Name = "Item Rule"), Required]
public ItemType ItemRule { get; set; }
public string Items { get; set; }
[Display(Name = "Price Rule"), Required]
public PriceType PriceRule { get; set; }
[Display(Name = "Value"), Column(TypeName = "MONEY")]
public decimal PriceValue { get; set; }
[Display(Name = "Exclusive?")]
public bool Exclude { get; set; }
}
public enum …
Run Code Online (Sandbox Code Playgroud) 我有一个使用Breeze的Angular应用程序,它有一个共享的EntityManager用于我的不同控制器.可以在不执行查询的情况下访问我的一些控制器,以预先填充EntityManager的MetadataStore.我已经找到了一个开始方向有点的在这里说,在应用程序的启动来获取元数据.我的项目基于Angular-Breezejs模板,当我尝试执行以下操作时,我会收到错误,因为在使用datacontext之前,promise没有完全解析.
app.factory('datacontext',
['breeze', 'Q', 'model', 'logger', '$timeout',
function (breeze, Q, model, logger, $timeout) {
logger.log("creating datacontext");
configureBreeze();
var manager = new breeze.EntityManager("/api/app");
manager.enableSaveQueuing(true);
var datacontext = {
metadataStore: manager.metadataStore,
saveEntity: saveEntity,
getUsers: getUsers,
getUser: getUser,
createUser: createUser,
deleteUser: deleteUser
};
return manager.fetchMetadata()
.then(function () {
model.initialize(datacontext);
return datacontext;
})
.fail(function (error) {
console.log(error);
return error;
});
//Function definitions
Run Code Online (Sandbox Code Playgroud)
在元数据提取完成之前,阻止的正确方法是什么?因为似乎没有必要在每个非查询函数(包括实体创建)之前检查元数据是否存在,就像上面链接的问题的原始海报一样.
题:
当我需要在WebAPI中为每个实体实现自己的POST/PUT/GET端点时,breeze提供了什么价值?
背景:
这似乎是服务器端Breeze控制器的常见实现:
[BreezeController]
public class TodosController : ApiController {
readonly EFContextProvider<TodosContext> _contextProvider =
new EFContextProvider<TodosContext>();
// ~/breeze/todos/Metadata
[HttpGet]
public string Metadata() {
return _contextProvider.Metadata();
}
// ~/breeze/todos/Todos
// ~/breeze/todos/Todos?$filter=IsArchived eq false&$orderby=CreatedAt
[HttpGet]
public IQueryable<TodoItem> Todos() {
return _contextProvider.Context.Todos;
}
// ~/breeze/todos/SaveChanges
[HttpPost]
public SaveResult SaveChanges(JObject saveBundle) {
return _contextProvider.SaveChanges(saveBundle);
}
// other miscellaneous actions of no interest to us here
}
Run Code Online (Sandbox Code Playgroud)
我正在构建一个RESTish API,到目前为止,它具有以下端点:
GET /api/todo/1
PUT /api/todo
POST /api/todo
Run Code Online (Sandbox Code Playgroud)
似乎Breeze要求端点更简单(无论好坏) - 只是一堆GETS和一个SaveChanges POST端点.
这让我觉得Breeze使用单个Web客户端进行快速开发,轻而易举......但是只要您拥有匿名客户端,就必须强制它们进入您在客户端创建的任何微风界面约定,这似乎打败了RESTful API设计的目的.是这样的吗?
我只想弄清楚在Breeze中保存更改时我需要在服务器端实现多少安全性.特别是,我正在考虑恶意用户如何手动破解SaveChanges请求或破解客户端中的javascript,以绕过我的正常业务规则 - 例如,恶意更改我的实体上的外键ID.
我想准确理解我需要关注安全工作的重点; 我不想浪费时间实现不需要的安全层.
我在服务器端使用Breeze和.net以及Entity Framework.
这是一个简单的例子.ObjectA
有一个参考ObjectB
,ObjectA
并由一个特定的所有User
.所以,我的数据库看起来像这样:
ObjectA:
Id ObjectB_Id SomeField User_Id
1 1 Alice's ObjectA 1
2 2 Bob's ObjectA 2
ObjectB:
Id SomeOtherField
1 Foo
2 Bar
User:
Id Name
1 Alice
2 Bob
Run Code Online (Sandbox Code Playgroud)
从这个模型,我的安全问题是:
ObjectA
ObjectA
鲍勃的ObjectB
.User_Id
他的ObjectA
爱丽丝.(1)的解决方案是微不足道的; 我将确保我的SaveChanges方法具有[Authorize]
属性.
我可以轻松地使用Fiddler构建一个SaveChanges请求来重现问题2到4 - 例如,我可以构建一个请求,它将Alice
ObjectA 更改为指向Bob的ObjectB
.这就是消息内容的样子:
"entities":
[
{
"Id":1,
"ObjectB_Id":2,
"SomeField":"Alice's ObjectA", …
Run Code Online (Sandbox Code Playgroud) 由于本文档,我能够在服务器端使用WebApiOdata和EntityFramework以及客户端的Breeze创建OData(v3)服务.
现在我想对OData规范的第4版做同样的事情.但有一个问题.EdmBuilder
Breeze提供的类依赖于与版本3相关的'Microsoft.Data.Edm'.
在EdmBuilder
这两行中阻止了项目的建立:
using Microsoft.Data.Edm.Csdl;
using Microsoft.Data.Edm.Validation;
Run Code Online (Sandbox Code Playgroud)
这是正常的,因为我的项目引用了'Microsoft.OData.Edm'(对于v4)而不是'Microsoft.Data.Edm'(对于v3).
所以我用这个替换了2个using
语句:
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Csdl;
using Microsoft.OData.Edm.Validation;
Run Code Online (Sandbox Code Playgroud)
现在项目可以构建,但在运行时它会抛出此异常
"解析EDMX文档时遇到以下错误:UnexpectedXmlElement:根元素的元素'Edmx'是意外的.根元素应该是Edmx.:( 1,40)"
从EdmBuilder
此时类:
using (var reader = XmlReader.Create(stream))
{
return EdmxReader.Parse(reader);
}
Run Code Online (Sandbox Code Playgroud)
有什么方法可以解决这个问题吗?就像EdmBuilder
我可以在某处下载的新课程一样?:)
谢谢.
PS:我使用代码首次迁移和此代码在'WebApiConfig'中配置OData路由:
config.MapODataServiceRoute(
routeName: "ODataRoute",
routePrefix: "OData",
model: EdmBuilder.GetEdm<MyDbContext>(),
batchHandler: new DefaultODataBatchHandler(GlobalConfiguration.DefaultServer));
Run Code Online (Sandbox Code Playgroud) 我只是想知道如何在单独的数据层项目中实现breeze的EFContextProvider.此外,由于该项目是一个类库而不是MVC 4应用程序,我应该如何将它包含在我的项目中?我真的不需要Breeze NuGet包中的整套技巧,只需要EFContextProvider的东西.我想使用EFContextProvider DbContext包装器实现一个工作单元模式,就像John Papa在他精彩的复数课程中所做的那样.有没有人这样做过?有小费吗?
谢谢