從壹開始前后端分離【 .NET Core2.0 +Vue2.0 】框架之十三 || DTOs 對象映射使用衫贬,項目打包部署Windows+Linux

代碼已上傳Github+Gitee德澈,文末有地址

番外:時間真快,今天終于到了系統(tǒng)打包的日子固惯,雖然項目還是有很多問題梆造,雖然后邊還有很多的內(nèi)容要說要學(xué),但是想著初級基本的.Net Core 用到的基本至少就這么多了(接口文檔缝呕,項目框架澳窑,持久化ORM,依賴注入供常,AOP摊聋,分布式緩存,CORS跨域等等)栈暇,中高級的麻裁,比如在Linux高級發(fā)布,Nginx代理源祈,微服務(wù)煎源,Dockers等等,這個在以后的更新中會慢慢提到香缺,不然的話手销,Vue就一直說不到了 [哭笑哈哈],其實我還有很多要總結(jié)的图张,比如 Power BI系列(沒用過的點擊看看)锋拖,比如C#7.0系列等文章,都在慢慢醞釀中祸轮,希望能堅持下來兽埃,不過這兩個系列目前還不會寫到,如果有需要用或?qū)W微軟Power BIhttps://docs.microsoft.com/zh-cn/power-bi/sample-customer-profitability)的适袜,可以加QQ群聯(lián)系我柄错,我在微軟項目中已經(jīng)用到了。還是打算從下周一開始轉(zhuǎn)戰(zhàn)Vue的文章苦酱,當然后端也會一直穿插著售貌,這里要說下,我們的QQ群已經(jīng)有一些小伙伴了疫萤,每天可以一起交流心得和問題趁矾,感覺還是很不錯的,如果你有什么問題给僵,或者其他技術(shù)上的需要討論,咱們的群是可以試試喲,我和其他小伙伴會一直在線給大家解答(咋感覺像一個廣告哈哈帝际,大家隨意哈)蔓同。

正傳:好啦,書接上文蹲诀,昨天說到了《從壹開始前后端分離【 .NET Core2.0 +Vue2.0 】框架之十二 || 三種跨域方式比較斑粱,DTOs(數(shù)據(jù)傳輸對象)初探》,因為下午時間的問題脯爪,只是講解了四種跨域方法则北,沒有講解完DTO,其實這個東西很簡單痕慢,說白了尚揣,就是把兩個實體類進行轉(zhuǎn)換,不用人工手動去一一賦值掖举,今天呢快骗,就簡單說下常見DTO框架AutoMapper的使用,然后做一個打包處理塔次,發(fā)布到我的windows服務(wù)器里方篮,今天剛剛買了一個Ubuntu Linux服務(wù)器,因為如果開發(fā).Net Core励负,一定會接觸到Linux服務(wù)器藕溅,等各種,因為它跨域了继榆,就是醬紫巾表。但是還沒有配置好,所以會在下邊留下位置裕照,慢慢補充在Ubuntu部署的講解攒发。

零、今天完成右下角的深藍色部分

image

一晋南、在項目中使用添加一個案例使用AutoMapper

1惠猿、在接口 IBlogArticleServices.cs和 類BlogArticleServices.cs中,添加GetBlogDetails()方法负间,返回類型是BlogViewModels

請看這兩個類

   /// <summary>
    /// 博客文章實體類 /// </summary>
    public class BlogArticle
    { /// <summary>
        /// 
        /// </summary>
        public int bID { get; set; } /// <summary>
        /// 創(chuàng)建人 /// </summary>
        public string bsubmitter { get; set; } /// <summary>
        /// 博客標題 /// </summary>
        public string btitle { get; set; } /// <summary>
        /// 類別 /// </summary>
        public string bcategory { get; set; } /// <summary>
        /// 內(nèi)容 /// </summary>
        public string bcontent { get; set; } /// <summary>
        /// 訪問量 /// </summary>
        public int btraffic { get; set; } /// <summary>
        /// 評論數(shù)量 /// </summary>
        public int bcommentNum { get; set; } /// <summary> 
        /// 修改時間 /// </summary>
        public DateTime bUpdateTime { get; set; } /// <summary>
        /// 創(chuàng)建時間 /// </summary>
        public System.DateTime bCreateTime { get; set; } /// <summary>
        /// 備注 /// </summary>
        public string bRemark { get; set; }
    } -------------------------------------------------
   /// <summary>
    /// 博客信息展示類 /// </summary>
    public class BlogViewModels
    { /// <summary>
        /// 
        /// </summary>
        public int bID { get; set; } /// <summary>/// 創(chuàng)建人
        /// </summary>
        public string bsubmitter { get; set; } /// <summary>/// 博客標題
        /// </summary>
        public string btitle { get; set; } /// <summary>/// 摘要
        /// </summary>
        public string digest { get; set; } /// <summary>
        /// 上一篇 /// </summary>
        public string previous { get; set; } /// <summary>
        /// 上一篇id /// </summary>
        public int previousID { get; set; } /// <summary>
        /// 下一篇 /// </summary>
        public string next { get; set; } /// <summary>
        /// 下一篇id /// </summary>
        public int nextID { get; set; } /// <summary>/// 類別
        /// </summary>
        public string bcategory { get; set; } /// <summary>/// 內(nèi)容
        /// </summary>
        public string bcontent { get; set; } /// <summary>
        /// 訪問量 /// </summary>
        public int btraffic { get; set; } /// <summary>
        /// 評論數(shù)量 /// </summary>
        public int bcommentNum { get; set; } /// <summary>/// 修改時間
        /// </summary>
        public DateTime bUpdateTime { get; set; } /// <summary>
        /// 創(chuàng)建時間 /// </summary>
        public System.DateTime bCreateTime { get; set; } /// <summary>/// 備注
        /// </summary>
        public string bRemark { get; set; }
    }

兩個實體類字段還基本可以偶妖,不是很多,但是我曾經(jīng)開發(fā)一個旅游網(wǎng)站的系統(tǒng)政溃,有一個表字段都高達30多個趾访,當然還有更多的,額董虱,如果我們一個個賦值是這樣的

            BlogViewModels models = new BlogViewModels()
            {
                bsubmitter=blogArticle.bsubmitter,
                btitle = blogArticle.btitle,
                bcategory = blogArticle.bcategory,
                bcontent = blogArticle.bcontent,
                btraffic = blogArticle.btraffic,
                bcommentNum = blogArticle.bcommentNum,
                bUpdateTime = blogArticle.bUpdateTime,
                bCreateTime = blogArticle.bCreateTime,
                bRemark = blogArticle.bRemark,
            }; 

所以這個方法的全部代碼是:

接口層也要添加:

   public interface IBlogArticleServices :IBaseServices<BlogArticle> {
        Task<List<BlogArticle>> getBlogs();
        Task<BlogViewModels> getBlogDetails(int id);
    }
image
/// <summary>
        /// 獲取視圖博客詳情信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<BlogViewModels> getBlogDetails(int id)
        {
            var bloglist = await dal.Query(a => a.bID > 0, a => a.bID);
            var idmin = bloglist.FirstOrDefault() != null ? bloglist.FirstOrDefault().bID : 0;
            var idmax = bloglist.LastOrDefault() != null ? bloglist.LastOrDefault().bID : 1;
            var idminshow = id;
            var idmaxshow = id;

            BlogArticle blogArticle = new BlogArticle();

            blogArticle = (await dal.Query(a => a.bID == idminshow)).FirstOrDefault();

            BlogArticle prevblog = new BlogArticle();


            while (idminshow > idmin)
            {
                idminshow--;
                prevblog = (await dal.Query(a => a.bID == idminshow)).FirstOrDefault();
                if (prevblog != null)
                {
                    break;
                }
            }

            BlogArticle nextblog = new BlogArticle();
            while (idmaxshow < idmax)
            {
                idmaxshow++;
                nextblog = (await dal.Query(a => a.bID == idmaxshow)).FirstOrDefault();
                if (nextblog != null)
                {
                    break;
                }
            }


            blogArticle.btraffic += 1;
            await dal.Update(blogArticle, new List<string> { "btraffic" });

            BlogViewModels models = new BlogViewModels()
            {
                bsubmitter=blogArticle.bsubmitter,
                btitle = blogArticle.btitle,
                bcategory = blogArticle.bcategory,
                bcontent = blogArticle.bcontent,
                btraffic = blogArticle.btraffic,
                bcommentNum = blogArticle.bcommentNum,
                bUpdateTime = blogArticle.bUpdateTime,
                bCreateTime = blogArticle.bCreateTime,
                bRemark = blogArticle.bRemark,
            };

            if (nextblog != null)
            {
                models.next = nextblog.btitle;
                models.nextID = nextblog.bID;
            }

            if (prevblog != null)
            {
                models.previous = prevblog.btitle;
                models.previousID = prevblog.bID;
            }
            return models;

        }

想了想這才是一個方法扼鞋,一般的系統(tǒng)都會有少則幾十申鱼,多則上百個這樣的方法,這還不算云头,大家肯定遇到過一個情況捐友,如果有一天要在頁面多顯示一個字段,噗溃槐!不是吧匣砖,首先要存在數(shù)據(jù)庫,然后在該實體類就應(yīng)該多一個昏滴,然后再在每一個賦值的地方增加一個猴鲫,而且也沒有更好的辦法不是,一不小心就少了一個谣殊,然后被產(chǎn)品測試說咱們不細心拂共,心塞喲,別慌蟹倾!神器來了匣缘,一招搞定。

2鲜棠、先來引入DTO講解肌厨,以及它的原理

在學(xué)習(xí)EF的時候我們知道了ORM(Object Relational Mapping)映射,是一種對象關(guān)系的映射豁陆,對象-關(guān)系映射(ORM)系統(tǒng)一般以中間件的形式存在柑爸,主要實現(xiàn)程序?qū)ο蟮疥P(guān)系數(shù)據(jù)庫數(shù)據(jù)的映射。

而Automapper是一種實體轉(zhuǎn)換關(guān)系的模型盒音,AutoMapper是一個.NET的對象映射工具表鳍。主要作用是進行領(lǐng)域?qū)ο笈c模型(DTO)之間的轉(zhuǎn)換、數(shù)據(jù)庫查詢結(jié)果映射至實體對象祥诽。

下邊的是基本原理譬圣,大家喵一眼就行:

? 什么是DTO?
  數(shù)據(jù)傳輸對象(DTO)(DataTransfer Object),是一種設(shè)計模式之間傳輸數(shù)據(jù)的軟件應(yīng)用系統(tǒng)雄坪。數(shù)據(jù)傳輸目標往往是數(shù)據(jù)訪問對象從而從數(shù)據(jù)庫中檢索數(shù)據(jù)厘熟。數(shù)據(jù)傳輸對象與數(shù)據(jù)交互對象或數(shù)據(jù)訪問對象之間的差異是一個以不具有任何行為除了存儲和檢索的數(shù)據(jù)(訪問和存取器)。

? 為什么用维哈?
  它的目的只是為了對領(lǐng)域?qū)ο筮M行數(shù)據(jù)封裝绳姨,實現(xiàn)層與層之間的數(shù)據(jù)傳遞。為何不能直接將領(lǐng)域?qū)ο笥糜跀?shù)據(jù)傳遞阔挠?因為領(lǐng)域?qū)ο蟾⒅仡I(lǐng)域飘庄,而DTO更注重數(shù)據(jù)。不僅如此购撼,由于“富領(lǐng)域模型”的特點跪削,這樣做會直接將領(lǐng)域?qū)ο蟮男袨楸┞督o表現(xiàn)層谴仙。

需要了解的是,數(shù)據(jù)傳輸對象DTO本身并不是業(yè)務(wù)對象碾盐。數(shù)據(jù)傳輸對象是根據(jù)UI的需求進行設(shè)計的狞甚,而不是根據(jù)領(lǐng)域?qū)ο筮M行設(shè)計的。比如廓旬,Customer領(lǐng)域?qū)ο罂赡軙恍┲T如FirstName, LastName, Email, Address等信息。但如果UI上不打算顯示Address的信息谐腰,那么CustomerDTO中也無需包含這個 Address的數(shù)據(jù)”孕豹。

? 什么是領(lǐng)域?qū)ο螅?br>   領(lǐng)域模型就是面向?qū)ο蟮模嫦驅(qū)ο蟮囊粋€很重要的點就是:“把事情交給最適合的類去做”十气,即:“你得在一個個領(lǐng)域類之間跳轉(zhuǎn)励背,才能找出他們?nèi)绾谓换ァ薄T谖覀兊南到y(tǒng)中Model(EF中的實體)就是領(lǐng)域模型對象砸西。領(lǐng)域?qū)ο笾饕敲鎸I(yè)務(wù)的叶眉,我們是通過業(yè)務(wù)來定義Model的。

以上的這些大家簡單看看原理即可芹枷,意思大家肯定都懂衅疙,下邊開始講解如何使用

3、在Blog.Core.Services項目中引用Nuget包鸳慈,AutoMapper 和 AutoMapper.Extensions.Microsoft.DependencyInjection

AutoMapper.Extensions.Microsoft.DependencyInjection饱溢,這個是用來配合依賴注入的,看名字也能看的出來吧走芋,大家回憶下绩郎,整個項目中,都是使用的依賴注入翁逞,所以盡量不要用new 來實例化肋杖,導(dǎo)致層耦合。

4挖函、基于上邊原理状植,在接口層Blog.Core 中,添加文件夾AutoMapper挪圾,然后添加映射配置文件 CustomProfile.cs浅萧,用來匹配所有的映射對象關(guān)系

     public class CustomProfile : Profile
    { /// <summary>
        /// 配置構(gòu)造函數(shù),用來創(chuàng)建關(guān)系映射 /// </summary>
        public CustomProfile()
        {
            CreateMap<BlogArticle, BlogViewModels>();
        }
    }

大家看下F12這個CreateMap方法

public IMappingExpression<TSource, TDestination> CreateMap<TSource, TDestination>();

第一個參數(shù)是原對象哲思,第二個是目的對象洼畅,所以,要想好棚赔,是哪個方向轉(zhuǎn)哪個帝簇,當然可以都寫上徘郭,比如

CreateMap<BlogArticle, BlogViewModels>();

CreateMap<BlogViewModels, BlogArticle>();

5、修改上邊服務(wù)層BlogArticleServices.cs 中g(shù)etBlogDetails 方法中的賦值丧肴,改用AutoMapper残揉,并用構(gòu)造函數(shù)注入

最終的代碼是

IBlogArticleRepository dal;
        IMapper IMapper; public BlogArticleServices(IBlogArticleRepository dal, IMapper IMapper)
        { this.dal = dal; base.baseDal = dal; this.IMapper = IMapper;
        } public async Task<BlogViewModels> getBlogDetails(int id)
        { var bloglist = await dal.Query(a => a.bID > 0, a => a.bID); var idmin = bloglist.FirstOrDefault() != null ? bloglist.FirstOrDefault().bID : 0; var idmax = bloglist.LastOrDefault() != null ? bloglist.LastOrDefault().bID : 1; var idminshow = id; var idmaxshow = id;

            BlogArticle blogArticle = new BlogArticle();

            blogArticle = (await dal.Query(a => a.bID == idminshow)).FirstOrDefault();

            BlogArticle prevblog = new BlogArticle(); while (idminshow > idmin)
            {
                idminshow--;
                prevblog = (await dal.Query(a => a.bID == idminshow)).FirstOrDefault(); if (prevblog != null)
                { break;
                }
            }

            BlogArticle nextblog = new BlogArticle(); while (idmaxshow < idmax)
            {
                idmaxshow++;
                nextblog = (await dal.Query(a => a.bID == idmaxshow)).FirstOrDefault(); if (nextblog != null)
                { break;
                }
            }

            blogArticle.btraffic += 1; await dal.Update(blogArticle, new List<string> { "btraffic" }); //注意就是這里
            BlogViewModels models = IMapper.Map<BlogViewModels>(blogArticle); if (nextblog != null)
            {
                models.next = nextblog.btitle;
                models.nextID = nextblog.bID;
            } if (prevblog != null)
            {
                models.previous = prevblog.btitle;
                models.previousID = prevblog.bID;
            } return models;

        }

6、老規(guī)矩芋浮,還是在Startup中抱环,注入服務(wù)

services.AddAutoMapper(typeof(Startup));//這是AutoMapper的2.0新特性

7、修改BlogController.cs中的 Get(int id)方法纸巷,運行項目镇草,斷點調(diào)試,發(fā)現(xiàn)已經(jīng)成功了瘤旨,是不是很方便梯啤,你也可以反過來試一試

 [HttpGet("{id}", Name = "Get")] 
    public async Task<object> Get(int id)
        { 
            var model = await blogArticleServices.getBlogDetails(id);//調(diào)用該方法 
            var data = new { success = true, data = model }; return data;
        }
image

8、好啦存哲,DTOs就到這里了因宇,我們的ConfigureServices也基本告一段落了,主要有這些

image

二祟偷、Blog.Core項目打包發(fā)布在IIS

1察滑、在項目Blog.Core中,右鍵肩袍,發(fā)布杭棵,選擇文件,相信大家都會氛赐,不會的可以聯(lián)系我

image

注意: 這里有一個坑魂爪,還記得我們用swagger中使用的兩個xml文件么,編譯的時候有艰管,但是.net core官方限制了在發(fā)布的時候包含xml文件滓侍,所以我們需要處理下

在項目工程文件WebApplication1.csproj中,增加

<PropertyGroup>
  <GenerateDocumentationFile>true</GenerateDocumentationFile>

</PropertyGroup>


當然我們還可以基于CLI的Publish命令進行發(fā)布牲芋,只需切換到Light.API根目錄下撩笆,輸入以下命令即可:

dotnet publish --framework netcoreapp1.1 --output "E:\Publish" --configuration Release

framework表示目標框架,output表示要發(fā)布到的目錄文件夾缸浦,configuration表示配置文件夕冲,等同于和上面我們通過管理器來發(fā)布的操作

具體的大家可以自行實驗

2、一定要在服務(wù)器中安裝.Net Core SDK (已安裝則跳過):

  地址:https://www.microsoft.com/net/download

在CMD命令窗口下裂逐,輸入 dotnet 查看

image

3歹鱼、安裝WindowsHosting(已安裝則跳過)

IIS安裝服務(wù)器上安裝DotNetCore.X.X.X-WindowsHosting安裝成功后重啟IIS服務(wù)器。根據(jù)版本選擇下載

下載地址:https://www.microsoft.com/net/download/windows

4卜高、安裝AspNetCoreModule托管模塊(已安裝則跳過),

  下載地址:點擊我下載

image

5弥姻、應(yīng)用池配置為無托管代碼

(網(wǎng)上解釋:ASP.NET Core不再是由IIS工作進程(w3wp.exe)托管南片,而是使用自托管Web服務(wù)器(Kestrel)運行,IIS則是作為反向代理的角色轉(zhuǎn)發(fā)請求到Kestrel不同端口的ASP.NET Core程序中庭敦,隨后就將接收到的請求推送至中間件管道中去疼进,處理完你的請求和相關(guān)業(yè)務(wù)邏輯之后再將HTTP響應(yīng)數(shù)據(jù)重新回寫到IIS中,最終轉(zhuǎn)達到不同的客戶端(瀏覽器秧廉,APP伞广,客戶端等)。而配置文件和過程都會由些許調(diào)整疼电,中間最重要的角色便是AspNetCoreModule赔癌,它是其中一個的IIS模塊,請求進入到IIS之后便立即由它轉(zhuǎn)發(fā)澜沟,并迅速重定向到ASP.NET Core項目中,所以這時候我們無需設(shè)置應(yīng)用程序池來托管我們的代碼峡谊,它只負責轉(zhuǎn)發(fā)請求而已)

image

6茫虽、如果需要讀寫根目錄權(quán)限,要更改應(yīng)用池 ApplicationPoolIdentity

7既们、如果沒有出現(xiàn)正常的頁面濒析,你可以打開錯誤日志

在發(fā)布的時候,會有一個web.config出現(xiàn)啥纸,通過修改web.config 啟用錯誤日志查看詳細錯誤信息

將stdoutLogEnabled的修改為 true号杏,并在應(yīng)用程序根目錄添加 logs 文件夾

一定要手動添加logs文件,不然會不出現(xiàn)

image

8斯棒、只要本地能通過盾致,常見的錯誤就是生成的文件不全導(dǎo)致的,大家可以自行看看荣暮,如果有問題庭惜,也可以大家一起解決

9、在IIS中啟動項目穗酥,或者直接輸入服務(wù)器IP地址护赊,加端口調(diào)試

注意:這里有一個小問題,因為發(fā)布以后砾跃,默認啟動頁是在開發(fā)環(huán)境中重定向到了swagger骏啰,但是在服務(wù)器部署以后,不能跳轉(zhuǎn)抽高,大家打開后會這樣判耕,404找不到,不要怕厨内,

只需要在后邊加上Swagger就行了

image

三祈秕、項目在Liunx Ubuntu中部署(簡單版渺贤,慢慢完善)

1、在騰訊云購買Ubuntu服務(wù)器后请毛,登陸志鞍,然后進入命令頁面

image

2、部署Linux系統(tǒng)中的微軟環(huán)境

繼續(xù)執(zhí)行下面的命令

Register the trusted Microsoft signature key:

curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg

繼續(xù)

sudo mv microsoft.gpg /etc/apt/trusted.gpg.d/microsoft.gpg

根據(jù)系統(tǒng)版本方仿,執(zhí)行下面的命令

sudo sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-ubuntu-xenial-prod xenial main" > /etc/apt/sources.list.d/dotnetdev.list'

好了固棚,環(huán)境部署完畢,下面我們安裝 SDK

3仙蚜、部署.Ne Core 環(huán)境

sudo apt-get install apt-transport-https
sudo apt-get update
sudo apt-get install dotnet-sdk-2.1.4

安裝成功后此洲,輸入命令 dotnet

image

證明安裝成功啦

4、安裝代碼上傳工具委粉,F(xiàn)illzila或者winSCP都可以呜师,(我用的是winSCP)

軟件下好打開后界面是這樣的,我們需要填的就是主機名(你服務(wù)器的公網(wǎng)IP)贾节、用戶名(服務(wù)器的用戶名)汁汗、密碼(你買服務(wù)器時設(shè)置的密碼)博脑,那個文件協(xié)議就是SFTP谷浅,不用改變

image

5奖亚、登陸進去默認是 /Home/ubuntu 文件夾悬襟,我們都在這里操作

image

6梢什、下面我們在服務(wù)器新建一個控制臺項目測試一下

<pre style="color: rgb(0, 0, 0); font-family: "Courier New"; font-size: 12px; margin: 5px 8px; padding: 5px;">dotnet new console -o myApp
</pre>

image

然后就在winSCP發(fā)現(xiàn)多了一個項目

image

** 7速警、然后運行我們剛剛創(chuàng)建的項目**

cd myApp
dotnet run

image

代碼一起正常专筷!

8死相、把我們的項目發(fā)布上去

未完待續(xù)中...

四忿墅、結(jié)語

今天暫時就先寫到這里扁藕,我們學(xué)到了如何用AutoMapper來實現(xiàn)DTO數(shù)據(jù)對象映射,也學(xué)會了在windows下的IIS中發(fā)布項目疚脐,最后就是Linux系統(tǒng)中纹磺,搭建環(huán)境和運行.net core 。但是還沒有完成亮曹,我會慢慢補充上來橄杨,除了繼續(xù)發(fā)布以外,還包括如何桌面話Linux系統(tǒng)照卦,Nginx代理等等式矫,大家拭目以待吧

五、CODE

https://github.com/anjoy8/Blog.Core

https://gitee.com/laozhangIsPhi/Blog.Core

QQ群:
867095512 (blod.core)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末役耕,一起剝皮案震驚了整個濱河市采转,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖故慈,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件板熊,死亡現(xiàn)場離奇詭異,居然都是意外死亡察绷,警方通過查閱死者的電腦和手機干签,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拆撼,“玉大人容劳,你說我怎么就攤上這事≌⒍龋” “怎么了竭贩?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長莺禁。 經(jīng)常有香客問我留量,道長,這世上最難降的妖魔是什么哟冬? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任肪获,我火速辦了婚禮,結(jié)果婚禮上柒傻,老公的妹妹穿的比我還像新娘。我一直安慰自己较木,他們只是感情好红符,可當我...
    茶點故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著伐债,像睡著了一般预侯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上峰锁,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天萎馅,我揣著相機與錄音,去河邊找鬼虹蒋。 笑死糜芳,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的魄衅。 我是一名探鬼主播峭竣,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼晃虫!你這毒婦竟也來了皆撩?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤哲银,失蹤者是張志新(化名)和其女友劉穎扛吞,沒想到半個月后呻惕,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡滥比,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年亚脆,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片守呜。...
    茶點故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡型酥,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出查乒,到底是詐尸還是另有隱情弥喉,我是刑警寧澤,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布玛迄,位于F島的核電站由境,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏蓖议。R本人自食惡果不足惜虏杰,卻給世界環(huán)境...
    茶點故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望勒虾。 院中可真熱鬧纺阔,春花似錦、人聲如沸修然。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽愕宋。三九已至玻靡,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間中贝,已是汗流浹背囤捻。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留邻寿,地道東北人蝎土。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像绣否,于是被迫代替她去往敵國和親瘟则。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,925評論 2 344