你的位置:首页 > ASP.net教程

[ASP.net教程]Web API与文件操作


前段时间,一直有练习ASP.NET MVC与Web API交互,接下来,Insus.NET再做一些相关的练习,Web API与文件操作,如POST文件至Web API,更新或是删除等。

不管怎样,先在数据库创建一张表,用来存储上传的文件。本实例中是把文件存储过数据库的。



CREATE TABLE ApiFileDemo(  [Afd_nbr] INT IDENTITY(1,1) PRIMARY KEY NOT NULL,  [Picture] [image] NULL,  [PictureType] [nvarchar](30) NULL,  [FileExtension] [nvarchar](10) NULL)GOCREATE PROCEDURE [dbo].[usp_ApiFileDemo_Insert](    @Picture IMAGE,  @PictureType NVARCHAR(30),  @FileExtension NVARCHAR(10))ASINSERT INTO [dbo].[ApiFileDemo] ([Picture],[PictureType],[FileExtension]) VALUES (@Picture,@PictureType,@FileExtension)GOCREATE PROCEDURE [dbo].[usp_ApiFileDemo_Update](  @Afd_nbr INT,  @Picture IMAGE,  @PictureType NVARCHAR(30),  @FileExtension NVARCHAR(10))ASUPDATE [dbo].[ApiFileDemo] SET [Picture] = @Picture,[PictureType] = @PictureType,[FileExtension] = @FileExtension WHERE [Afd_nbr] = @Afd_nbrGOCREATE PROCEDURE [dbo].[usp_ApiFileDemo_Delte](  @Afd_nbr INT)ASDELETE FROM [dbo].[ApiFileDemo] WHERE [Afd_nbr] = @Afd_nbrGO

Source Code


写到这里,发现少了一个存储过程,就是获取某一张图片的:


CREATE PROCEDURE [dbo].[usp_ApiFileDemo_GetByPrimarykey](  @Afd_nbr INT)ASSELECT [Afd_nbr],[Picture],[PictureType],[FileExtension] FROM [dbo].[ApiFileDemo] WHERE [Afd_nbr] = @Afd_nbrGO

Source Code

 
接下来,我们可以设计Web API接口,待完成了,发布至网上,其它客户端就可以操作了。

根据数据库表,可以在API项目中,创建Model:


using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace Insus.NET.Models{  public class File  {    public int Afd_nbr { get; set; }    public byte[] Picture { get; set; }    public string PictureType { get; set; }    public string FileExtension { get; set; }  }}

Source Code


写好model之后,还需要为API写一个实体,这个对象只是让程序与数据库进行交互。获取与存储等操作:


using Insus.NET.DataBases;using Insus.NET.Models;using System;using System.Collections.Generic;using System.Data;using System.Linq;using System.Text;using System.Threading.Tasks;using Insus.NET;namespace Insus.NET.Entities{  public class FileEntity  {    BizSP sp = new BizSP();    public DataTable GetFileByPrimarykey(File f)    {      List<Parameter> param = new List<Parameter>() {                  new Parameter("@Afd_nbr", SqlDbType.Int,4,f.Afd_nbr)      };      sp.ConnectionString = DB.ConnectionString;      sp.Parameters = param;      sp.ProcedureName = "usp_ApiFileDemo_GetByPrimarykey";      return sp.ExecuteDataSet().Tables[0];    }    public void Insert(File f)    {      List<Parameter> param = new List<Parameter>() {                  new Parameter("@Picture", SqlDbType.Image,-1,f.Picture),                  new Parameter("@PictureType",SqlDbType.NVarChar,-1,f.PictureType),                  new Parameter("@FileExtension",SqlDbType.NVarChar,-1,f.FileExtension)      };      sp.ConnectionString = DB.ConnectionString;      sp.Parameters = param;      sp.ProcedureName = "usp_ApiFileDemo_Insert";      sp.Execute();    }    public void Update(File f)    {      List<Parameter> param = new List<Parameter>() {                  new Parameter("@Afd_nbr", SqlDbType.Int,4,f.Afd_nbr),                  new Parameter("@Picture", SqlDbType.Image,-1,f.Picture),                  new Parameter("@PictureType",SqlDbType.NVarChar,-1,f.PictureType),                  new Parameter("@FileExtension",SqlDbType.NVarChar,-1,f.FileExtension)      };      sp.ConnectionString = DB.ConnectionString;      sp.Parameters = param;      sp.ProcedureName = "usp_ApiFileDemo_Update";      sp.Execute();    }    public void Delete(File f)    {      List<Parameter> param = new List<Parameter>() {                  new Parameter("@Afd_nbr", SqlDbType.Int,4,f.Afd_nbr)      };      sp.ConnectionString = DB.ConnectionString;      sp.Parameters = param;      sp.ProcedureName = "usp_ApiFileDemo_Delte";      sp.Execute();    }  }}

Source Code

 

下面的控制器FileController,即是为客户端访问的接口,这个类别,它是继承了ApiController。

 

using Insus.NET.Entities;using Insus.NET.ExtendMethods;using Insus.NET.Models;using System;using System.Collections.Generic;using System.Linq;using System.Net;using System.Net.Http;using System.Web.Http;namespace Insus.NET.Controllers{  public class FileController : ApiController  {    // GET: File    FileEntity fe = new FileEntity();    // GET: ApiFileDemo    [HttpGet]    public string Get(int id)    {      File f = new File();      f.Afd_nbr = id;      return fe.GetFileByPrimarykey(f).ToJson();    }    [HttpPost]    public void Post(File f)    {      fe.Insert(f);    }    [HttpPut]    public void Put(File f)    {      fe.Update(f);    }    [HttpDelete]    public void Delete(File f)    {      fe.Delete(f);    }    [HttpDelete]    public void Delete(int id)    {      File f = new File();      f.Afd_nbr = id;      fe.Delete(f);    }  }}

Source Code

 
Web API完成,我们需要把它发布至IIS中去,如何发布,可以参考《创建与使用Web API》http://www.cnblogs.com/insus/p/5019088.html......


Ok,接下来,我们开发客户端的程序,尝试上Web API上传一些文件。

在客户端的项目中,创建一个mode:


using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace Insus.NET.Models{  public class File  {    public int Afd_nbr { get; set; }    public byte[] Picture { get; set; }    public string PictureType { get; set; }    public string FileExtension { get; set; }  }}

Source Code

 

ASP.NET MVC的控制器中,创建2个Action:

 

 public ActionResult Upload()    {      return View();    }    [HttpPost]    public ActionResult Upload(IEnumerable<HttpPostedFileBase> files)    {      foreach (var file in files)      {        if (file.ContentLength > 0)        {          Insus.NET.Models.File f = new Insus.NET.Models.File();          f.PictureType = file.ContentType;          string fn = Path.GetFileName(file.FileName);          f.FileExtension = fn.Substring(fn.LastIndexOf('.'));          using (Stream inputStream = file.InputStream)          {            MemoryStream memoryStream = inputStream as MemoryStream;            if (memoryStream == null)            {              memoryStream = new MemoryStream();              inputStream.CopyTo(memoryStream);            }            f.Picture = memoryStream.ToArray();          }          HttpClient client = new HttpClient();          string ff = f.ToJson();          HttpContent httpcontent = new StringContent(ff, System.Text.Encoding.UTF8, "application/json");          client.PostAsync("http://localhost:9001/api/file", httpcontent)            .ContinueWith((postTask) =>            {              postTask.Result.EnsureSuccessStatusCode();            });        }      }      return RedirectToAction("Upload");    }

Source Code

 

在视图中,可以这样做:

 

程序运行:


 

 图片上传成功之后,现在我们需要把图片显示出来。
由于存储的是二进制的数据流,显示图片时,需要处理一下,需要写一个自定义的Result,如:PictureResult,它需要继承ContentResult:


using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Web;using System.Web.Mvc;namespace Insus.NET.Results{  public class PictureResult : ContentResult  {    public byte[] _Picture { get; set; }    public string _PictureType { get; set; }    public PictureResult(byte[] sourceStream, String contentType)    {      _Picture = sourceStream;      _PictureType = contentType;    }    public override void ExecuteResult(ControllerContext context)    {      var response = context.HttpContext.Response;      response.Clear();      response.Cache.SetCacheability(HttpCacheability.NoCache);      response.ContentType = ContentType;      if (_Picture != null)      {        var stream = new MemoryStream(_Picture);        stream.WriteTo(response.OutputStream);        stream.Dispose();      }    }  }}

Source Code


接下来,我们在控制器创建视图的Action:

 

 public ActionResult ShowPhoto()    {      return View();    }        public ActionResult ShowPicture(int id)    {      var files = ApiUtility.Get<Insus.NET.Models.File>("http://localhost:9001/api/file/" + id);      var model = files.FirstOrDefault();      PictureResult pictureResult = new PictureResult(model.Picture, model.PictureType);      return pictureResult;    }

Source Code

 
客户端程序运行,可以看到图片显示的效果:


在Web API的接口还有更新,删除的接口,看官们可以继续完成。方法在Insus.NET博客上也有相似或是相关的功能......