3

目標 我的目標是向實體Product發送一些額外的(未定義的)屬性。例如,在AngularJs列表視圖中,我需要顯示一些產品作爲鏈接(可訪問),而其他產品則根據從當前用戶(我從會話中獲得)計算的權限'data和productId顯示不可訪問。通過ViewModel的Microsoft Odata api在PATCH中存在問題

什麼迫使我有這個問題

現在的OData不允許我在發送一個IQueryable的結果是這樣的添加額外的屬性。

public IQueryable<Product> GET() 
{ 
    return db.Products.AsQueryable<Product>(); 
} 

只是因爲返回類型產品,增加額外的屬性會讓別的東西,如果我嘗試像這樣

var result = db.Products.Select(p => new Product 
{ 
    ID = p.ID, 
    Accessible = (code for permission checks), 
    [other properties...] 
} 

溶液接近

我有一個走近它解決方案,使OdataController的一個新類型OdataProduct已定義屬性,我需要發送一個列表權限感知。 (你有什麼想法如何使列表的權限知道,除了我這個解決方案?)

public class OdataProduct 
{ 
    public Product product { get; set; } 
    public OdataProduct(Product product) 
    { 
     this.product = product; 
    } 
    // 
    public void setPermissions(User user, string controller) 
    { 
     if (user == null) return; 
     isAllowed = [permission check code]; 
    } 
    public bool isAllowed { get; set; } 
} 

我試圖繼承這個OdataProduct形式Product但在向下轉換的OdataProductProduct當接收到POST請求所面臨的問題保存到數據庫中。 Db.Products.Add();

現在,使用此ViewModel和此類型的控制器,我已成功發送權限感知結果,這些結果取決於會話中的當前用戶對列表中的所有產品都是這樣。

public class OdataProductController : ODataController 
{ 
    private OfferAssistantDbContext db = new OfferAssistantDbContext(); 

    // GET api/OdataProduct 
    public IQueryable<OdataProduct> GET() 
    { 
     var result = db.Products.AsQueryable<Product>(); 
     var OResult = new List<OdataProduct>(); 
     var currentUser = (User)HttpContext.Current.Session["LoggedUser"]; 
     OdataProduct OProduct; 
     foreach (var item in result) 
     { 
      OProduct = new OdataProduct(item); 
      OProduct.setPermissions(currentUser, "Product"); 
      OResult.Add(OProduct); 
     } 

     return OResult.AsQueryable<OdataProduct>(); 
    } 
    //other methods of the controller below... 
} 

問題,我想爲

  1. 解決方案時,我送一個PATCH請求OdataProduct控制器,我得到了Delta對象不是產品,如果我在Payload發送產品和也相應地修改Odata參數PATCH方法來接收Product而不是OdataProduct它被接收爲空,而在默認情況下我不能運行這個命令到PATCHProduct的真實實體,而不是ViewModel。下面。

    var dbProduct = db.Products.Find(key); oDataProduct.Patch((數據庫產品); // OdataProduct不是數據庫產品類型 的什麼是溶液

  2. 另一個問題我面對的是在設置OdataProduct的權限上述

    OProduct.setPermissions(currentUser? ,「Product」); //步入異常行的方法是 this.Childs = product.DependantProducts.Where(dp => dp.ParentID == product.ID)。計數();

它說DataReader已經打開。雖然這不是主要問題,但請在這裏提供一些信息。

回答

2

的第一個問題就可以解決這種方式,首先,定義視圖Moodel ODataProduct其中包含了型號後加IsAllowed所需要的特性:

public class ODataProduct 
{ 
    public int ID { get; set; } 
    public string Title { get; set; } 
    public bool IsAllowed { get; set; } 
} 

然後創建一個新的EntitySet其元素類型是ODataProduct。

private static IEdmModel GetModel() 
{ 
    ODataModelBuilder modelBuilder = new ODataConventionModelBuilder(); 
    var odataProductsEntitySet = modelBuilder.EntitySet<ODataProduct>("ODataProducts"); 
    return modelBuilder.GetEdmModel(); 
} 

最後一步是更新ODataProductController以執行GET,POST,PATCH等。

public class ODataProductsController : ODataController 
{ 
    private ProductsContext db = new ProductsContext(); 

    public IHttpActionResult Get() 
    { 
     var Products = db.Products.Select(m => new ODataProduct() 
     { 
      ID = m.ID, 
      Title=m.Title, 
      // Other properties 
      IsAllowed = true, 
     }); 
     return Ok(Products); 
    } 

    public ODataProduct Patch(int key, Delta<ODataProduct> odataProduct) 
    { 
     var dbProduct = db.Products.Single(m => m.ID == key); 
     foreach (string propertyName in odataProduct.GetChangedPropertyNames()) 
     { 
      if ("IsAllowed" == propertyName) 
      { 
       continue; 
      } 
      object propertyValue; 
      if (odataProduct.TryGetPropertyValue(propertyName, out propertyValue)) 
      { 
       var propertyInfo = typeof(Product).GetProperty(propertyName); 
       propertyInfo.SetValue(dbProduct, propertyValue); 
      } 
     } 
     db.SaveChanges(); 
     ODataProduct odataProductReturn = new ODataProduct() 
     { 
      ID = dbProduct.ID, 
      Title=dbProduct.Title, 
      // other properties 
     }; 
     odataProductReturn.IsAllowed = true;// or false according to your business logic 
     return odataProductReturn; 
    } 
} 
+0

所以你的想法是在現有的產品控制器上應用PATCH,並通過新的OdataProduct控制器提供權限感知列表。對? – ahmadalibaloch

+0

不,我的意思是在ODataProductsController中做GET/PATCH/PUT/POST。 –

+0

如何使用產品修補ODataProduct視圖模型。這是我在問題中提出的主要問題!!!!!!!!! – ahmadalibaloch