Web API+Entity Framework分享


1、 webapi允許跨域的增刪改查要在web.config中加入以下文字

<system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <modules runAllManagedModulesForAllRequests="true">
      <remove name="WebDAVModule" />
    </modules>
    <handlers>
      <remove name="WebDAV" />
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <remove name="OPTIONSVerbHandler" />
      <remove name="TRACEVerbHandler" />
      <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
      <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept" />
        <add name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS, PUT, DELETE" />
      </customHeaders>
    </httpProtocol>
  </system.webServer>

2、webapi支持特性路由,即在action上可以加上類似 [Route("RoleRights/{id}")]的特性路由,前提條件是要支持特性路由,即在WebApiConfig.cs的register的方法中添加MapHttpAttributeRoutes().這樣訪問該action的時候就會無視路由表中的路由,訪問該路由的正確格式為:網站名稱/RoleRights/9.--9表示id。

3、ModelState.IsValid,該屬性可以判斷當客戶端傳送實體字段格式不正確時會顯示為false.比如action中有參數實體A,A中b字段是整形,你傳實體調用action,b你傳了個“”,此時該屬性值回味false.

4、注意添加webapi時生成的return BadRequest和return Notfound(),返回給web客戶端時是做為異常處理的,即調用失敗,如果使用jquery會調用error函數。返回的錯誤也比較明確.省去了自定義格式.

5、有時候我們只是對數據庫中的某條已有記錄做修改,那可以針對要修改的字段設置如下:

db.FunctionInfoes.Attach(functionInfoNew);
db.Entry(functionInfoNew).Property(x => x.FunctionName).IsModified = true;
db.Entry(functionInfoNew).Property(x => x.FunctionType).IsModified = true;
db.Entry(functionInfoNew).Property(x => x.ParentId).IsModified = true;
db.Entry(functionInfoNew).Property(x => x.FunctionPath).IsModified = true;
db.Entry(functionInfoNew).Property(x => x.Description).IsModified = true;
db.Entry(functionInfoNew).Property(x => x.LastUpdateBy).IsModified = true;
db.Entry(functionInfoNew).Property(x => x.LastUpdate).IsModified = true;
try
{
db.SaveChanges();
}

  

其中ismodified=true表示做save的時候要修改此字段.修改ismodufied之前一定要記得增加db.FunctionInfoes.Attach(functionInfoNew);否則會報錯.

6、注意db.FunctionInfoes.RemoveRange(childEntityInfo);和 db.FunctionInfoes.Where(item => item.OwnerId == id).Delete();

的區別,前者不會影響到數據庫記錄,除非增加db.SaveChanges(),后者的修改直接回影響到數據庫記錄而不需要做db.SaveChanges().

7、記得每個control要增加一個Options空方法,否則做刪除回提示not allowe this method。

public string Options()
{
return null; // HTTP 200 response with empty body

}

 

8、事務包裹是使用using(var dbContextTransaction = db.Database.BeginTransaction())

                     {....

                       ....}

經查詢對於一個context的  db.SaveChanges(),其實已經放在一個事務里邊了,具體的可以通過sql profile去跟蹤,對於分布式context的可能就要使用scope了.

9、使用entity framework table first的好處就是可對於數據庫字段的更改,通過在edmx上右鍵Update model from database及時更新到程序model上.

對於實體序列化返回的屬性,可以使用工具Newtonsoft.Json,自定義返回的名稱。比如說實體A中有屬性

public string Title { get; set; },,但是渴望序列化后返回的屬性名是小寫的,那么可以在該屬性上加上特性[JsonProperty("title")],即

[JsonProperty("title")]
public string Title { get; set; }

 

10、Linq to Entity

linq to entity,當有空值時會報錯,所以程序里邊需要判斷是否存在空值,如果存在null必須賦值,此代碼賦值“”

from a in db.RoleInfoes
join b in db.UserInfoes
on a.LastUpdateBy equals b.UserId into temp
from tt in temp.DefaultIfEmpty()
select new
{
    a.RoleId,
    a.RoleName,
    FirstName = tt.FirstName ?? "",
    LastName = tt.LastName ?? "",
    a.RoleDescription,
    LastUpdate=a.LastUpdate.ToString()
};

 

11、因為 DbContext 繼承自IDisposable 所以你需要釋放資源在使用完dbcontext,如果使用了using就不用以下

方法了.

protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }

 

12.API action可以針對多個實體采用一個Jobject類型的參數來接收對象,然后再分別在服務端取出,大家可以搜索Json.net的Jobject對象的使用.但是在實際angular調用服務端的過程中會發現,如果使用Get方法來調用Web API的get方法,傳過來的JObject參數值是空的,此時可以使用Post的方式來傳遞,此時就會是有值的了.

相關文章:

13、 WebApi中如果某個action要不受具體actinFilterattribute限制(即不執行該attribute中的具體方法,在做權限控制的時候特別有用),可以給該action增加屬性OverrideActionFilters,如下例:

       
 [OverrideActionFilters]
      public IHttpActionResult GetDataPoint()

     {

     } 

 

14、 WEBAPI能否提供統一接口提供異常呢,避免異常描述滿天飛,答案當然是有的,可以自定義異常屬性類並繼承ExceptionFilterAttribute,並覆寫

OnException 方法,然后就可以捕獲各種異常了,如下代碼

public override void OnException(HttpActionExecutedContext actionExecutedContext)
        {
            //this exception is DbEntityValidationException
            if (actionExecutedContext.Exception is DbEntityValidationException)
            {
                DbEntityValidationException validationException = actionExecutedContext.Exception as DbEntityValidationException;
                StringBuilder sb = new StringBuilder();
                foreach (DbEntityValidationResult item in validationException.EntityValidationErrors)
                {
                    foreach(var itemerror in item.ValidationErrors)
                    {
                        sb.AppendLine(itemerror.ErrorMessage);
                    }
                }
                actionExecutedContext.Response=APIResponseMessage.Create(CommonMessage.Error, message: sb.ToString());
            }
            else
            {
                actionExecutedContext.Response = APIResponseMessage.Create(CommonMessage.Error, message: actionExecutedContext.Exception.Message);
            }
        }

 

那么什么時候會觸發該WebApiExceptionFilterAttribute類中的OnException方法呢,答案就是如果你在action中如果不定義任何捕獲異常的邏輯,當

程序運行時出現異常會自動被該方法捕獲,如果你在action中有用catch捕獲了異常,那么並自行處理了,那么就不會觸發該方法。當然,你如果有用 throw ex

來拋出了異常,那么OnException也會捕獲到該異常.
 相關參考鏈接大家可以參考一下文章:

http://www.cnblogs.com/aehyok/p/3446863.html 

http://blog.jobbole.com/99858/ 

 16、大家猜一下以下的結果會不會是一樣的,其中db是DbContext,DataLensDataPoint是表對應model.

db.DataLensDataPoint.Where(item => item.Name.Equals(dataPoint.Name,StringComparison.CurrentCultureIgnoreCase)) 

db.DataLensDataPoint.Where(item=>item.Name.ToUpper()== dataPoint.Name.ToUpper())

,可能你會說一樣,但是其實不一樣,第一句中StringComparison.CurrentCultureIgnoreCase根本沒起作用,也就是沒有忽略大小寫,但是第二句使用了ToUpper()確實忽略了大小寫,不知道是否與DBA設置database為大小寫敏感了有沒有關系,還是這是一個bug呢?歡迎大家探討.

 17、在對EF框架中的數據做tracking log的時候可以覆寫SaveChangesAsync或者SaveChanges,當時要明白一點:db.DataLensDataPointAFS.Where(item => item.DataPointId == dataPoint.DataPointId).Delete()和

await db.DataLensDataPointUniverseValidationCheck.Where(item => dataPointUniverseId.Contains(item.DataPointUniverseId)
).DeleteAsync();這樣的方法數據的改變不會被SaveChangesAsync或者SaveChanges方法中捕捉到,因為這兩個方法是Entity Framework的擴展類EntityFramework.Extended中的方法,本身有對數據庫直接更改的能力,而不需要SaveChangesAsync或者SaveChanges.

 18、當在進行類型轉換的時候,發現一個問題,當T時dynami類型時如果使用Type type = typeof(T)來獲取類型之后,然后使用type.GetProperties()來獲取屬性,獲取屬性就會失效.這時候只能使用真實類型.

 

restful標准描述

http://www.cnblogs.com/artech/p/restful-web-api-02.html

webapi分頁

微軟Odata 技術

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM