1控制器操作的参数

控制器操作的参数可以是内置类型也可以是自定义类型,无参也是允许的。

还可以为控制器操作参数提供默认值。

例:

public IHttpActionResult User(int id=1)

{

return Json("id:"+id);

}

2控制器操作返回值

类型

说明

void

操作返回值为void时,Web API返回空HTTP响应,其状态码为204(无内容)

HttpResponseMessage

Web api会将此返回值直接转换为HTTP消息

IHttpActionResult

接口形式

内置类型或自定义类型

 

2.1返回值为HttpResponseMessage

返回值为此类型时,有两种设置方式。

第一种调用HttpResponseMessage的构造函数,实例化一个HttpResponseMessage,并返回。Web API会将其直接转换为HTTP消息。

例:

        public HttpResponseMessage Get()
{
FileStream fs = new FileStream(@"D:\GreatFile.txt",FileMode.Open);//文件流
HttpResponseMessage hrm = new HttpResponseMessage
{
StatusCode = HttpStatusCode.OK,
Content = new StreamContent(fs, )
}; return hrm;
}

第二种方式是调用Request.CreateResponse方法,将自定义类型传递给它。Web API会调用序列化器将其序列化后写入HTTP响应。

        public HttpResponseMessage Get()
{
var publisher = new PublisherModel{Title ="ASP.NET Web API编程实战",Year=};
return Request.CreateResponse<PublisherModel>(HttpStatusCode.OK, publisher);
}

HttpResponseMessage类的定义如下:

public class HttpResponseMessage : IDisposable
{
public HttpResponseMessage();
// 参数: statusCode:HTTP 响应的状态代码。
public HttpResponseMessage(HttpStatusCode statusCode);
// 获取或设置 HTTP 响应消息的内容。
//返回 System.Net.Http.HttpContent。 HTTP 响应消息的内容。
public HttpContent Content { get; set; }
//获取 HTTP 响应标头的集合。
public HttpResponseHeaders Headers { get; }
//获取一个值,该值指示 HTTP 响应是否成功。
//System.Net.Http.HttpResponseMessage.StatusCode。在 200-299 //范围中,则为 true;否则为 false。
public bool IsSuccessStatusCode { get; }
//获取或设置服务器与状态代码通常一起发送的原因短语。
//返回 System.String。 服务器发送的原因词组。
public string ReasonPhrase { get; set; }
//获取或设置导致此响应消息的请求消息。
public HttpRequestMessage RequestMessage { get; set; }
//获取或设置 HTTP 响应的状态代码。
public HttpStatusCode StatusCode { get; set; }
//获取或设置 HTTP 消息版本。默认值为 1.1。
public Version Version { get; set; }
//释放由 System.Net.Http.HttpResponseMessage 使用的非托管资源,并可根据需要释放托管资源。
//参数: 如果为 true,则释放托管资源和非托管资源;如果为 false,则仅释放非托管资源。
protected virtual void Dispose(bool disposing);
//如果 HTTP 响应的 System.Net.Http.HttpResponseMessage.IsSuccessStatusCode 属性//为 false,将引发异常。
public HttpResponseMessage EnsureSuccessStatusCode();
//返回表示当前对象的字符串。
public override string ToString();
}

2.1.1设置响应状态:

可以通过构造函数设置响应状态码,也可以通过StatusCode 属性设置响应状态码。

 

2.1.2设置HTTP消息头

通过HttpResponseMessage.Headers属性设置HTTP消息头,其类型为HttpResponseHeaders,下面是这个类型的定义:

public sealed class HttpResponseHeaders : HttpHeaders
{
//获取 HTTP 请求的 Accept-Ranges 标头的值。
public HttpHeaderValueCollection<string> AcceptRanges { get; } //获取或设置 HTTP 响应的 Age 标头值。
public TimeSpan? Age { get; set; }
//获取或设置 HTTP 响应的 Cache-Control 标头值。
public CacheControlHeaderValue CacheControl { get; set; }
//获取 HTTP 请求的 Connection 标头的值。
public HttpHeaderValueCollection<string> Connection { get; }
//获取或设置指示 HTTP 响应的 Connection 标头是否应包含 Close 的值。
public bool? ConnectionClose { get; set; }
//获取或设置 HTTP 响应的 Date 标头值。
public DateTimeOffset? Date { get; set; }
//获取或设置 HTTP 响应的 ETag 标头值。
public EntityTagHeaderValue ETag { get; set; }
//获取或设置 HTTP 响应的 Location 标头值。
public Uri Location { get; set; }
//获取 HTTP 请求的 Pragma 标头的值。
public HttpHeaderValueCollection<NameValueHeaderValue> Pragma { get; }
//获取 HTTP 请求的 Proxy-Authenticate 标头的值。
public HttpHeaderValueCollection<AuthenticationHeaderValue> ProxyAuthenticate { get; }
//获取或设置 HTTP 响应的 Retry-After 标头值。
public RetryConditionHeaderValue RetryAfter { get; set; }
//获取 HTTP 请求的 Server 标头的值。
public HttpHeaderValueCollection<ProductInfoHeaderValue> Server { get; }
//获取 HTTP 请求的 Trailer 标头的值。
public HttpHeaderValueCollection<string> Trailer { get; }
//获取 HTTP 请求的 Transfer-Encoding 标头的值。
public HttpHeaderValueCollection<TransferCodingHeaderValue> TransferEncoding { get; }
//获取或设置指示 HTTP 响应的 Transfer-Encoding 标头是否应包含 chunked 的值。
public bool? TransferEncodingChunked { get; set; }
//获取 HTTP 请求的 Upgrade 标头的值。
public HttpHeaderValueCollection<ProductHeaderValue> Upgrade { get; }
//获取 HTTP 请求的 Vary 标头的值。
public HttpHeaderValueCollection<string> Vary { get; }
//获取 HTTP 请求的 Via 标头的值。
public HttpHeaderValueCollection<ViaHeaderValue> Via { get; }
//获取 HTTP 请求的 Warning 标头的值。
public HttpHeaderValueCollection<WarningHeaderValue> Warning { get; }
//获取 HTTP 请求的 WWW-Authenticate 标头的值。
public HttpHeaderValueCollection<AuthenticationHeaderValue> WwwAuthenticate { get; }
}

对部分属性的解析

1)可通过属性AcceptRanges来设置HTTP 请求的 Accept-Ranges 标头,当浏览器发现Accept-Range头时,可以尝试继续中断了的下载,而不是重新开始。设置为none表示不支持范围请求。设置为bytes表示支持范围请求。通过设置此表头,以支持断点续传机制。

例:

            HttpResponseMessage hrm = new HttpResponseMessage
{
//其他设置
};
hrm.Headers.AcceptRanges.Add("bytes");

2)使用属性Location获取或设置重定向地址。

浏览器收到此类响应时会跳转到指定的地址。

例:

public class ValuesController : ApiController
{
public HttpResponseMessage Get(int id)
{
HttpResponseMessage hrm = new HttpResponseMessage
{
//其他设置
};
var controller = this.Request.GetRouteData().Values["controller"];
var uri = new Uri(this.Url.Link("DefaultApi", new { controller = controller, id = id }));
hrm.Headers.Location = uri;
return hrm;
}
}

2.1.3设置消息内容

使用HttpResponseMessage.Content属性设置消息内容。

HttpResponseMessage.Content属性的类型为HttpContent,其定义如下:

public abstract class HttpContent : IDisposable
{
//其他代码略
//根据 RFC 2616 中的定义,获取内容标头。
public HttpContentHeaders Headers { get; }
//其他代码略
}

HttpContent.Headers 属性

其的定义如下:

public sealed class HttpContentHeaders : HttpHeaders
{
//获取 HTTP 响应上的 Content-Disposition 内容标头值。
public ContentDispositionHeaderValue ContentDisposition { get; set; }
//获取 HTTP 响应的 Content-Encoding 内容标题的值。
public ICollection<string> ContentEncoding { get; }
//获取或设置 HTTP 响应上的 Content-Length 内容标头值。
public long? ContentLength { get; set; }
//获取或设置 HTTP 响应上的 Content-Range 内容标头值。
public ContentRangeHeaderValue ContentRange { get; set; }
//获取或设置 HTTP 响应上的 Content-Type 内容标头值。
public MediaTypeHeaderValue ContentType { get; set; }
//其他代码略
}

解析:

1)Content-Disposition 内容标头值

在HTTP场景中,第一个参数或者是inline(默认值,表示回复中的消息体会以页面的一部分或者整个页面的形式展示),或者是attachment(意味着消息体应该被下载到本地;大多数浏览器会呈现一个“保存为”的对话框,将filename的值预填为下载后的文件名,假如它存在的话)。

例:

HttpResponseMessage response = new HttpResponseMessage() ;
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
//设置文件名
response.Content.Headers.ContentDisposition.FileName =”TextFile.txt”;

2)Content-Length,指明发送给接收方的消息主体的大小

例:

HttpResponseMessage response = new HttpResponseMessage();
response.Content.Headers.ContentLength = ;

3)Content-Range,一个数据片段在整个文件中的位置

例:

HttpResponseMessage response = new HttpResponseMessage();
new ContentRangeHeaderValue(, , );

4)Content-Type,用于指示资源的MIME类型

例:

HttpResponseMessage response = new HttpResponseMessage();
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");

根据实际的需要可以使用以下几种类型:StreamContentPushStreamContentByteArrayContentStringContent。

使用StreamContent“拉”模式将数据放入响应

例如:

FileStream fileStream = new FileStream(@"D:\testfile.txt", FileMode.Open);
HttpResponseMessage hrm = new HttpResponseMessage
{
//其他设置
};
hrm.Content = new StreamContent(fileStream, );

使用PushStreamContent“推”模式将数据放入响应。

推模式的有点是,可以将数据一块一块地写入响应中,而不是一下子将数据先放入缓存中,然后全部发送出去。虽然StreamContent也可以,但只能将FileStream流赋给HttpResponseMessage.Content才能实现流传输,以达控制内存的目的,对于byte[]类型的数据就无能为力了。

例如:

    public class DiskFileStream
{
private readonly string filename; public DiskFileStream(string filename)
{
this.filename = filename;
} public async Task WriteToStream(Stream outputStream, HttpContent httpContent, TransportContext transportContext)
{
try
{
var buffer = new byte[]; using (var file = File.Open(filename, FileMode.Open, FileAccess.Read))
{
var length = (int)file.Length;
var bytesRead = ; while (length > && bytesRead > )
{
bytesRead = file.Read(buffer, , Math.Min(length, buffer.Length));
await outputStream.WriteAsync(buffer, , bytesRead);
length -= bytesRead;
}
}
}
catch (HttpException ex)
{
return;
}
finally
{
outputStream.Close();
}
}
} //控制器
public class DownLoadController:ApiController
{
public HttpResponseMessage Get(string filename)
{
var file = new DiskFileStream(filename); var response = Request.CreateResponse();
Func<Stream, HttpContent, TransportContext,Task> onStreamAvailable = file.WriteToStream;
response.Content = new PushStreamContent(onStreamAvailable, new MediaTypeHeaderValue("application/octet-stream")); return response;
}
}

使用StringContent

在基类控制器使用StringContent,以便返回Json类型的数据。如下定义了一个泛型方法,指定类型T为class。

例如:

public class BaseController : ApiController
{
public HttpResponseMessage ToJson<T>(T model) where T : class
{
string str = JsonConvert.SerializeObject(model);
return new HttpResponseMessage { Content = new StringContent(str, Encoding.GetEncoding("UTF-8"), "application/json") };
}
}

也可以不使用泛型方法,而对传入类型检测,但是需要做类型检查,不过可以序列化匿名类型。

        public HttpResponseMessage ToJson(Object obj)
{
String str = string.Empty;
if (obj is String || obj is Char)
{
str = obj.ToString();
}
else
{
str = JsonConvert.SerializeObject(obj);
}
return new HttpResponseMessage { Content = new StringContent(str, Encoding.GetEncoding("UTF-8"), "application/json") };
}

2.1.4设置原因短语ReasonPhrase

使用ReasonPhrase属性可以设置消息短语,用于解释状态码代表的含义。消息短语应尽可能地简洁扼要,尽量使用英文。

例:

HttpResponseMessage hrm = new HttpResponseMessage
{
StatusCode = (HttpStatusCode),
ReasonPhrase = "Unable to find the user" //其他设置
};

2.2返回值为IHttpActionResult

IHttpActionResult是一个接口,只有一个返回值为Task<System.Net.Http.HttpResponseMessage> 的异步方法ExecuteAsync。

当控制器操作返回此类型时,Web API会调用ExecuteAsync方法创建类型为HttpResponseMessage的实例,然后将这个实例转换为HTTP消息。

例:

实现IHttpActionResult

public class CustomActionResult : IHttpActionResult
{
private object param;
private HttpRequestMessage request;
public CustomActionResult(object param,HttpRequestMessage request)
{
this.param = param;
this.request = request;
}
public System.Threading.Tasks.Task<HttpResponseMessage> ExecuteAsync(System.Threading.CancellationToken cancellationToken)
{
var response = new HttpResponseMessage
{
Content = ......,
RequestMessage = ......
};
}
}

使用CustomActionResult

        public IHttpActionResult GetOther()
{
object param = ......
return CustomActionResult(param,Request);
}

注意;CustomActionResult 构造函数的参数为object类型,实际项目并不一定如此,这里只是举个例子而已。

System.Web.Http.ApiController提供了几个方法返回值类型都继承自IHttpActionResult

仅举几个常用的方法:

protected internal JsonResult<T> Json<T>(T content);返回值JsonResult继承自IHttpActionResult,可将泛型参数T的实例序列化后写入HTTP响应中。

protected internal virtual NotFoundResult NotFound();返回NotFoundResult,创建一个状态码为404的空响应。

protected internal virtual OkResult Ok();返回值为OkResult ,创建一个状态码为200的空响应。

protected internal virtual OkNegotiatedContentResult<T> Ok<T>(T content);返回值为OkNegotiatedContentResult,创建一个状态码为200的响应,并将参数content实例序列化写入响应消息体中。

2.3返回值为内置类型或自定义类型

返回值为内置类型或自定义类型时,Web API使用格式化器序列化返回值,并将其写入HTTP消息中,响应的状态码为200。

例:

        public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}

3修饰控制器及操作

使用特性修饰控制器及其操作。

HTTP动词特性

包括:HttpGet、HttpPost、HttpPut、HttpDelete,HttpHead,HttpPatch,HttpOptions只能用来修饰操作。

HttpGet:使操作只能处理HTTP GET请求,用于获取资源且不对数据进行修改的操作。

HttpPost:使操作只处理HTTP POST请求,用于传输数据实体或者对数据进行修改的操作。

HttpPut:使操作只处理HTTP PUT请求,用于新增资源或者使用请求中的有效负载替换目标资源的表现形式。

HttpDelete:使操作只处理HTTP DELETE请求,一般使用DELETE请求删除请求URL所指定的资源。

HttpHead:使操作只处理HTTP HEADER请求,使用HEADER请求要求服务器的响应只返回首部,而不返回实体的主体部分。

HttpPatch:使操作只处理HTTP PATCH请求,对资源执行部分修改。

HttpOptions:使操作只处理HTTP OPTIONS请求,用于向服务器询问其支持的方法。

PUT与POST方法的区别在于,PUT方法是幂等的:调用一次与连续调用多次是等价的(即没有副作用),而连续调用多次POST方法可能会有副作用,比如将一个订单重复提交多次。

例:限定操作只支持post请求。

        [HttpPost]
public IHttpActionResult ListALL()
{
//具体实现
return Ok();
}

AcceptVerbs特性

使用AcceptVerbs特性可设置允许多种HTTP方法调用,且支持非标准的HTTP方法。

例:

支持多种方法

        [AcceptVerbs("DELETE", "POST")]
public void Delete(int id)
{
}

支持自定义方法,这种方式比较少用,大多数情况下,HTTP标准方法足够用

        [AcceptVerbs("LALL")]
public IHttpActionResult ListALL()
{
//具体实现
return Ok();
}

为Action重命名

使用ActionName特性为Action重命名。

阻止方法被调用

使用NonAction特性标记Action,阻止其被调用。

使用路由特性

使用RouteAttribute和RoutePrefix可以设置路由值。具体见路由一节。

参考:

1.https://docs.microsoft.com/en-us/aspnet/web-api/

2.https://developer.mozilla.org/zh-CN/docs/Web

转载与引用请注明出处。

时间仓促,水平有限,如有不当之处,欢迎指正。

asp.net web api 控制器的更多相关文章

  1. ASP.NET Web API 控制器执行过程(一)

    ASP.NET Web API 控制器执行过程(一) 前言 前面两篇讲解了控制器的创建过程,只是从框架源码的角度去简单的了解,在控制器创建过后所执行的过程也是尤为重要的,本篇就来简单的说明一下控制器在 ...

  2. ASP.NET Web API 控制器创建过程(二)

    ASP.NET Web API 控制器创建过程(二) 前言 本来这篇随笔应该是在上周就该写出来发布的,由于身体跟不上节奏感冒发烧有心无力,这种天气感冒发烧生不如死,也真正的体会到了什么叫病来如山倒,病 ...

  3. ASP.NET Web API 控制器创建过程(一)

    ASP.NET Web API 控制器创建过程(一) 前言 在前面对管道.路由有了基础的了解过后,本篇将带大家一起学习一下在ASP.NET Web API中控制器的创建过程,这过程分为几个部分下面的内 ...

  4. ASP.NET Web API 控制器执行过程

    http://www.cnblogs.com/jin-yuan/p/3952605.html

  5. ABP文档 - Web Api 控制器

    文档目录 本节内容: 简介 AbpApiController 基类 本地化 其它 过滤 审计日志 授权 防伪造过滤 工作单元 结果包装和异常处理 结果缓存 验证 模块绑定器 简介 通过Abp.Web. ...

  6. ABP理论学习之Web API控制器(新增)

    返回总目录 本篇目录 介绍 AbpApiController基类 本地化 审计日志 授权 工作单元 其他 介绍 ABP通过Abp.Web.ApiNuget包集成了 ASP.NET Web API控制器 ...

  7. ASP.NET Web API中的依赖注入

    什么是依赖注入 依赖,就是一个对象需要的另一个对象,比如说,这是我们通常定义的一个用来处理数据访问的存储,让我们用一个例子来解释,首先,定义一个领域模型如下: namespace Pattern.DI ...

  8. Web Api 控制器

    Web Api 控制器 文档目录 本节内容: 简介 AbpApiController 基类 本地化 其它 过滤 审计日志 授权 防伪造过滤 工作单元 结果包装和异常处理 结果缓存 验证 模块绑定器 简 ...

  9. ABP官方文档翻译 5.1 Web API控制器

    ASP.NET Web API控制器 介绍 AbpApiController基类 本地化 其他 过滤器 审计日志 授权 反伪造过滤器 工作单元 结果包装和异常处理 结果缓存 校验 模型绑定器 介绍 A ...

随机推荐

  1. 严格次小生成树(Bzoj1977:[Beijing2010组队]次小生成树)

    非严格次小生成树 很简单,先做最小生成树 然后枚举没加入的边加入,替换掉这个环内最大的边 最后取\(min\) 严格次小生成树 还是一样的 可以考虑维护一个严格次大值 最大值和枚举的边相同就替换次大值 ...

  2. [BZOJ1046] [HAOI2007] 上升序列 (dp)

    Description 对于一个给定的S={a1,a2,a3,…,an},若有P={ax1,ax2,ax3,…,axm},满足(x1 < x2 < … < xm)且( ax1 < ...

  3. 小程序 for循环 报错 Cannot read property 'total' of undefined

    for循环一直报错  Cannot read property 'total' of undefined,但total在起初是有定义的,后来找到了问题,是i<=的问题,改为<不报错了. i ...

  4. hadoop2.x源码编译

    转载请标明出处: http://blog.csdn.net/zwto1/article/details/50733753: 介绍 本篇主要会涉及以下内容: 学会编译hadoop2.x源码 编译hado ...

  5. Memcached修改默认端口

    windows下修改memcached服务的端口号(默认端口:11211)如果不是作为服务启动memcached的话,memcached -p 端口号就可以了. 通过修改注册表可以简单实现 运行:re ...

  6. DIY福音:Firefox菜单及右键菜单ID大全

    每一个折腾Firefox的Diyer都是上辈子折翼的天使,致自己! 打磨Firefox界面的时候最多的就隐藏一些平常根本用不上的一些菜单,常规的做法就是安装DOM Inspector扩展右键查找大法寻 ...

  7. Django数据模型——数据库字段类型

    字段 一个模型最重要也是唯一必需的部分,是它定义的数据库字段 字段名称限制 1.字段名不能是python保留字,这样会导致python语法错误 2.字段不能包含连续一个以上的下划线,这样会和Djang ...

  8. Linux最佳的云存储服务分析

    什么样的云服务才适合作为 Linux 下的存储服务?兄弟连www.itxdl.cn来帮大家分析一下! 大量的免费空间.毕竟,个人用户无法支付每月的巨额款项. 原生的 Linux 客户端.以便你能够方便 ...

  9. NGUI_slider

    十一.进度条UISlider 1.一般按以下规律使用进度条; 如果某一钟值,他有最大值,需要表达当前的值得占比,则可以使用不可拖动的进度条 如果某一值,他有最大值,需要玩家记性滑动设置,则可以使用可拖 ...

  10. 用IDEA在Tomcat上部署项目

    其实每次在需要运行的jsp页面右键=>run也是可以运行的,但是会出现下面这样 正常应该Run==>Edit Con-- 这时候将看到这个页面,千万不要在Defaults中招Tomcat配 ...