WebApi(二)-重新封装返回结果
如果不想写代码直接使用nuget安装笔者已经封装好的就可以马上实现(nuget搜索ZetaWebApi)选择>=1.0.1版本-----不懂使用nuget的请查看笔者的nuget系列文章
如果习惯自己写代码请继续往下看
先创建要返回的结果类型:
/// <summary> /// 返回类型 /// </summary> public class ApiResultModel { private HttpStatusCode statusCode; private object data; private string errorMessage; private bool isSuccess; /// <summary> /// 状态代码 /// </summary> public HttpStatusCode StatusCode { get { return statusCode; } set { statusCode = value; } } /// <summary> /// 返回的数据 /// </summary> public object Data { get { return data; } set { data = value; } } /// <summary> /// 错误消息 /// </summary> public string ErrorMessage { get { return errorMessage; } set { errorMessage = value; } } /// <summary> /// 是否成功 /// </summary> public bool IsSuccess { get { return isSuccess; } set { isSuccess = value; } } }
然后创建重写ActionFilterAttribute下的OnActionExecuted(执行action之后):
先建一个类名字随意如:ApiResultAttribute继承于System.Web.Http.Filters.ActionFilterAttribute详细代码如下:
以下代码需注意要引用using System.Net.Http否则ReadAsAsync不能使用
public class ApiResultAttribute : System.Web.Http.Filters.ActionFilterAttribute { public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) { base.OnActionExecuted(actionExecutedContext); ApiResultModel result = new ApiResultModel(); // 取得由 API 返回的状态代码 result.StatusCode = actionExecutedContext.ActionContext.Response.StatusCode; // 取得由 API 返回的资料 result.Data = actionExecutedContext.ActionContext.Response.Content.ReadAsAsync<object>().Result; //请求是否成功 result.IsSuccess = actionExecutedContext.ActionContext.Response.IsSuccessStatusCode; //结果转为自定义消息格式 HttpResponseMessage httpResponseMessage = JsonHelper.toJson(result); // 重新封装回传格式 actionExecutedContext.Response = httpResponseMessage; } }
上面的JsonHelper.toJson()是事先写好的代码如下:创建类JsonHelper
public static HttpResponseMessage toJson(Object obj) { String str; if (obj is String || obj is Char)//如果是字符串或字符直接返回 { str = obj.ToString(); } else//否则序列为json字串 { JavaScriptSerializer serializer = new JavaScriptSerializer(); str = serializer.Serialize(obj); } HttpResponseMessage result = new HttpResponseMessage { Content = new StringContent(str, Encoding.GetEncoding("UTF-8"), "application/json") }; return result; }
建完之后在WebApiConfig下注册:
config.Filters.Add(new ApiResultAttribute());//重新包装结果
完成以上步骤即可使用。
补充:
特殊情况不需要封装返回结果,解决方法:
1创建一个自定义属性
假设自定义类名为NoPackageResult继承Attribute
public class NoPackageResult : Attribute { }
2,修改上面的ApiResultAttribute类里的OnActionExecuted方法
在方法里加一个判断是否有属性有的情况下就不做封装的步骤
var noPackage = actionExecutedContext.ActionContext.ActionDescriptor.GetCustomAttributes<NoPackageResult>(); if (!noPackage.Any()) { //执行封装 }
3在不需要封装的接口上添加属性NoPackageResult如下:
ApiResultAttribute类完整代码:
public class ApiResultAttribute : System.Web.Http.Filters.ActionFilterAttribute { public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) { base.OnActionExecuted(actionExecutedContext); // 不包裹返回值 var noPackage = actionExecutedContext.ActionContext.ActionDescriptor.GetCustomAttributes<NoPackageResult>(); if (!noPackage.Any()) { //初始化返回结果 ApiResultModel result = new ApiResultModel(); if (actionExecutedContext.Exception != null) { result.Code = "sys_error"; result.Success = false; result.Message = actionExecutedContext.Exception.Message; } else { // 取得由 API 返回的状态代码 result.Code = actionExecutedContext.ActionContext.Response.StatusCode.ToString(); var a = actionExecutedContext.ActionContext.Response.Content.ReadAsAsync<object>(); if (!a.IsFaulted) { // 取得由 API 返回的资料 result.Data = actionExecutedContext.ActionContext.Response.Content.ReadAsAsync<object>().Result; } //请求是否成功 result.Success = actionExecutedContext.ActionContext.Response.IsSuccessStatusCode; } //结果转为自定义消息格式 HttpResponseMessage httpResponseMessage = CustomerHttpResponseMessage.toJson(result); // 重新封装回传格式 actionExecutedContext.Response = httpResponseMessage; } } }
有梦想一定要去做
但是未必一定要实现