麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

MVC4 WebAPI(二)——Web API工作方式

2019-11-17 01:53:46
字體:
供稿:網(wǎng)友

MVC4 WebAPI(二)——Web API工作方式

在上篇文章中和大家一起學(xué)習(xí)了建立基本的WebAPI應(yīng)用,立刻就有人想到了一些問題:1.客戶端和WebService之間文件傳輸2.客戶端或者服務(wù)端的安全控制要解決這些問題,要了解一下WebAPI的基本工作方式。

(一)WebAPI中工作的Class

在MVC中大家都知道,獲取Request和Response使用HttPRequest和HttpResponse兩個(gè)類,在WebAPI中使用兩外兩個(gè)類:HttpRequestMessage 和HttpResponseMessage,分別用于封裝Requset和Response。除了這兩個(gè)類之外,還有一個(gè)常見的抽象 類:HttpMessageHandler,用于過濾和加工HttpRequestMessage和HttpResponseMessage

(二)解決第一個(gè)問題

其 實(shí)第一個(gè)問題之所以被提出來應(yīng)該是和客戶端有關(guān),如果客戶端的請(qǐng)求是我們手寫提交的,比如使用HttpClient封裝的請(qǐng)求,則要傳遞文件之前,我們一 般會(huì)進(jìn)行一次序列化,轉(zhuǎn)化為二進(jìn)制數(shù)組之類的,在網(wǎng)絡(luò)上傳輸。這樣的話,在Controller中的Action參數(shù)里,我們只需要接收這個(gè)二進(jìn)制數(shù)組類 型的對(duì)象就可以了。但是如果客戶端是Web Form呢,比如我們提交一個(gè)Form到指定的Controller的Action中,這個(gè)Action要接收什么類型的參數(shù)呢?或者我們問另外一個(gè)問題,如果我將Web Form提交到一個(gè)WebAPI的Action中 ,我要怎么去取出這個(gè)表單中的數(shù)據(jù)呢?其 實(shí)我們應(yīng)該想到:我們的Action設(shè)置的參數(shù)之所以能夠被賦值,是因?yàn)閃ebAPI的架構(gòu)中在調(diào)用Action時(shí)將HTTP請(qǐng)求中的數(shù)據(jù)解析出來分別賦 值給Action中的參數(shù),如果真是這樣的話,我們只需要在Action中獲取到HTTP請(qǐng)求,然后直接獲取請(qǐng)求里面的數(shù)據(jù),就能解決上面的問題。這 種想法是正確的,只不過,此時(shí)的HTTP請(qǐng)求已經(jīng)不是最原始的HTTP Request,而是已經(jīng)被轉(zhuǎn)化成了HttpRequestMessage,在Action中,我們可以直接調(diào)用base.Requet來得到這個(gè) HttpRequestMessage實(shí)例,通過這個(gè)實(shí)例我們就可以隨心所欲的取出HTTP請(qǐng)求中想要的數(shù)據(jù)。

2.1從RequestMessage中獲取普通表單數(shù)據(jù)

這里的普通表單是指不包含F(xiàn)ile的表單,也就是說表單的enctype值不是multipart/form-data,這時(shí),表單的數(shù)據(jù)默認(rèn)情況下是以Json來傳遞的如下頁面

復(fù)制代碼
<form name="form" action="~/api/FormSubmit?key=11234" method="post">    <input type="text" name="key" id="txtKey" />    <br />    <input type="text" name="value" id="txtValue" />    <br />        <input type="submit" id="btnSubmit" value="Submit" />     </form>
復(fù)制代碼

捕獲到的請(qǐng)求為

提交到對(duì)應(yīng)的Action為:

復(fù)制代碼
        [HttpPost]        public async void submitForm()        {            StringBuilder sb = new StringBuilder();            HttpContent content = Request.Content;            JsonObject jsonValue = await content.ReadAsOrDefaultAsync<JsonObject>();            foreach (var x in jsonValue)            {                sb.Append(x.Key);                string va ;                if (x.Value.TryReadAs<string>(out va))                {                    sb.Append(va);                }            }        }
復(fù)制代碼

這樣最后可以得到 Json的值:{"key":"123","value":"123"} sb處理后的值為:key123value123

注:在該action中使用到了關(guān)鍵字async和await,這些在4.5中新提出的關(guān)鍵字主要是用于進(jìn)行多線程取值的,在MVCAPI的設(shè)計(jì)中,大部分的方法都被設(shè)計(jì)成類似于下面的方法

public static Task<T> ReadAsOrDefaultAsync<T>(this HttpContent content);

返 回值是一個(gè)Task,這種返回新線程的方法雖然可以提高系統(tǒng)的響應(yīng)能力,但是多線程取值會(huì)給編碼帶來不便,所以新出的關(guān)鍵字await用于阻塞當(dāng)前線程并 獲取目標(biāo)線程的返回值,在方法體中使用await關(guān)鍵字后要求將方法聲明為async用來表示該方法是異步的,并且返回值必須為void或者將返回者封裝 在一個(gè)Task中當(dāng)然,如果你不喜歡這種寫法,上面的action也可以寫為:

            Task readTask = content.ReadAsOrDefaultAsync<JsonObject>().ContinueWith((task) => { jsonValue = task.Result; });            readTask.Wait();

2.2從RequestMessage中獲取multipart表單數(shù)據(jù)將view頁面改寫為

復(fù)制代碼
<form name="form" action="~/api/FormSubmit?key=11234" method="post" enctype="multipart/form-data" >    <input type="text" name="key" id="txtKey" />    <br />    <input type="text" name="value" id="txtValue" />    <br />    <input type="file" name="file" id="upFile" />    <br />    <input type="submit" id="btnSubmit" value="Submit" /></form>
復(fù)制代碼

此時(shí)捕獲到得請(qǐng)求是

這里的文件內(nèi)容被捕獲軟件解析成字符串,當(dāng)然如果我上傳的是其他的非文本格式的文件,文件會(huì)被轉(zhuǎn)化為二進(jìn)制數(shù)組這時(shí)如果我們不更改action,而直接調(diào)用,會(huì)發(fā)生錯(cuò)誤,原因很明顯,這個(gè)HTTP的報(bào)文內(nèi)容是無法被轉(zhuǎn)換為JSON的,這時(shí)我們需要將表單的報(bào)文解析成另外一種格式

復(fù)制代碼
                IEnumerable<HttpContent> bodyparts = await content.ReadAsMultipartAsync();                foreach (var bodypart in bodyparts)                {                    string name;                    name = bodypart.Headers.ContentDisposition.Name;                    sb.Append(name + ":");                    if (bodypart.Headers.Contains("filename"))                    {                        Stream stream = await bodypart.ReadAsStreamAsync();                        StreamReader reader = new StreamReader(stream);                        sb.Append(reader.ReadToEnd());                        sb.Append("----");                    }                    else                    {                        string val = await bodypart.ReadAsStringAsync();                        sb.Append(val);                        sb.Append("----");                    }                }
復(fù)制代碼

得到的處理后的sb值為:

{"key":123----"value":123----"file":******{文件的內(nèi)容}*****----}整合后的Action為

復(fù)制代碼
        [HttpPost]        public async void submitForm()        {            StringBuilder sb = new StringBuilder();            HttpContent content = Request.Content;            if (content.IsMimeMultipartContent())            {                IEnumerable<HttpContent> bodyparts = await content.ReadAsMultipartAsync();                foreach (var bodypart in bodyparts)                {                    string name;                    name = bodypart.Headers.ContentDisposition.Name;                    sb.Append(name + ":");                    if (bodypart.Headers.Contains("filename"))                    {                        Stream stream = await bodypart.ReadAsStreamAsync();                        StreamReader reader = new StreamReader(stream);                        sb.Append(reader.ReadToEnd());                        sb.Append("----");                    }                    else                    {                        string val = await bodypart.ReadAsStringAsync();                        sb.Append(val);                        sb.Append("----");                    }                }            }            else            {                JsonObject jsonValue = await content.ReadAsOrDefaultAsync<JsonObject>();                foreach (var x in jsonValue)                {                    sb.Append(x.Key);                    string va;                    if (x.Value.TryReadAs<string>(out va))                    {                        sb.Append(va);                    }                }            }        }
復(fù)制代碼

(三)WebAPI工作方式

要想解決第二個(gè)問題就沒這么容易了,我們需要更深入的理解WebAPI的工作方式。其實(shí)對(duì)于WebAPI來說,它最初被設(shè)計(jì)為和WCF一樣的:客戶端、服務(wù)端兩套結(jié)構(gòu),我們到現(xiàn)在之所以還沒有提到客戶端,是因?yàn)槲覀兊恼?qǐng)求別的方式來封裝成HTTP請(qǐng)求或接收HTTP相應(yīng)的,比如Ajax和Form表單提交。在這里先給出一個(gè)服務(wù)端的響應(yīng)工作流,讓大家有個(gè)大體上的認(rèn)識(shí)aspDfAAAAAAAAcgPyGwAAAAAAQG5AfgMAAAAAAMgNyG8AAAAAAAC5AfkNAAAAAAAgNyC/AQAAAAAA5AbkNwAAAAAAgNyA/AYAAAAAAJAbkN8AAAAAAAByA/IbAAAAAABAbsij/BZJTOZGAAAAAAAA9iAv8lskEgmHw+FwOBQKBewz/tlepgL2mWAwGAqFwuFw8gzGPMu0EAqFAgvD241srDAtMI3I+boAAAAAACCvqDy/xUOX32XzNX5AXXned/U7/js/YMp39TveM1+nao4HHPPxFCdsIRKJhEKhYDBIDT+k7v7Ie+brvlsvxRuhLj5F3TxENf/B77IlagQAAAAAACB9qs1v8dwVoLa8ncW+q98N6i9GLJ30qplTtrFgdzF1+Tmq4ZTf6w6FQuwTcUz8CwaD1GgtdeX5QNXb4dGHtG2M10jY1BRsP0tdec7bcSFAbfEaAQAAAAAAkES257f4hYtCSTjspHf5PJve8p8Hmz6ILAzSq6YkFdRfpO78kFpfCgaDTOPRE3d+P9XwW3/lWxGLPnkLtG000Hzad+271OpsvBGZNxcAAAAAAKhYluY39vfNgj6P39xCNf/Bd/dH1N0f+e7+iNL+wW9uCWw5Rb+6tn3SbGPNd/vl0HDZDrkrVuGJGt/tI9750UAgEAwGmRa8d34Y1GtSbIFeNUUs+ngjiHAAAAAAACChbMxv22fPFsepsje8Z77uL3sj2H4mPFrJVLD9jL/sDercP1N3f+RbHI+f7IqnvmAw6HW7fLdfDhsb6BVj6hWZ0fluHtxanvZ6vZ5Np+/2y+HRyl21QK8YI9Ye/91XPXMjiHAAAAAAAGzaPhepcJG+AGtaSNPsIhWuoiXFepVDsiu/bV+1uDbnrXjL

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 91成人免费在线观看 | 亚洲电影在线观看高清免费 | 99亚洲伊人久久精品影院红桃 | 日韩av电影免费在线观看 | 欧美亚州 | 久久久久久久一区二区三区 | 福利免费在线 | 中文字幕在线亚洲精品 | 九草网 | 免费观看黄视频 | 少妇一级淫片高潮流水电影 | 艹男人的日日夜夜 | 欧美日韩在线看片 | 91精品国产91久久久久久 | 亚洲电影免费观看国语版 | 国产免费一区二区三区在线能观看 | 国产欧美日韩视频在线观看 | 国产大片中文字幕在线观看 | 自拍偷拍999| 黄色网址免费进入 | 久久影院免费观看 | 久久成人免费网站 | 免费在线观看国产精品 | 轻点插视频| 中文字幕免费在线看 | 99视频网址 | 成人午夜视频免费 | gril hd| 久久亚洲一区二区三区成人国产 | 91午夜视频| 在线播放免费播放av片 | 中文字幕极速在线观看 | 免费啪视频在线观看 | 成人激情在线观看 | 99欧美视频 | 精品国产一区二区三区久久久蜜月 | 91精品国产福利尤物免费 | 国产精品一区二区三区在线看 | 日本在线观看视频网站 | 在线播放免费视频 | 欧美18—19sex性护士中国 |