现在移动设备端的需求越来越大,要满足其数据要求的一种方式就是实现Restful,脱离具体的后台支持方式。在微软的实现方式中,我们需要利用VS建立web API项目,利用 System.Web.Http就可以实现将自己的控制发布出来。
public class OutValuesController : ApiController
{
// GET api/values
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/values/5
public string Get(int id)
{
return "value";
}
// POST api/values
public void Post([FromBody]string value)
{
}
// PUT api/values/5
public void Put(int id, [FromBody]string value)
{
}
// DELETE api/values/5
public void Delete(int id)
{
}
}
这种实现方式下需要继承ApiController,这个在很多已经有很多Service的系统中难以实现,另外对controller、Service有限制。
介绍两种利用MVC、Unity以及反射 实现的对Service的进行Restful。
第一种修改Microsoft.Web.Mvc实现;
首先利用一个Controller实现Restful,修改它的ActionInvoker来将调用拦截下来。
public class ApiHelperController : Controller
{
//微软的ControllerActivator激活Controller时,执行的就是无参数的构造函数!
public ApiHelperController()
{
base.ActionInvoker = new MyActionInvoker();
}
}
然后,下面比较乱了,总体就是从Controllercontext中获取Controller、method的名称,利用Unity根据Controller的名称来取得实例,利用反射直接调用invoke,将result 用Json来实现。
public override bool InvokeAction(ControllerContext controllerContext, string controllerName)
{
//根据action名称去找Action并执行,其中包括了 View的呈现 以及 应用在Action上的各种特性的执行
//return false; //执行失败
// return true; //执行成功
//return base.InvokeAction(controllerContext, actionName);
Type mappedType;
mappedType = UnityConfig.GetConfiguredContainer().Registrations.SingleOrDefault(n => n.Name == controllerName).MappedToType;
object service = UnityConfig.GetConfiguredContainer().Resolve(mappedType, new Microsoft.Practices.Unity.ResolverOverride[] { });
//object service =UnityConfig.GetTargetService(controllerName);
string methodName = controllerContext.RequestContext.RouteData.GetRequiredString("id");
MethodInfo method = service.GetType().GetMethod(methodName);
NameValueCollection c = controllerContext.RequestContext.HttpContext.Request.QueryString;
string[] targetParams = new string[c.Count];
c.CopyTo(targetParams, 0);
//得到指定方法的参数列表
ParameterInfo[] paramsInfo = method.GetParameters();
HttpResponseBase response = controllerContext.HttpContext.Response;
JavaScriptSerializer serializer = new JavaScriptSerializer();
if (paramsInfo.Length != c.Count)
{
response.Write("参数不匹配!");
return true;
}
object[] finalParams = new object[c.Count];
for (int i = 0; i < c.Count; i++)
{
Type tType = paramsInfo[i].ParameterType;
//如果它是值类型,或者String
if (tType.Equals(typeof(string)) || (!tType.IsInterface && !tType.IsClass))
{
//改变参数类型
finalParams[i] = Convert.ChangeType(targetParams[i], tType);
}
else if (tType.IsClass)//如果是类,将它的json字符串转换成对象
{
finalParams[i] = Newtonsoft.Json.JsonConvert.DeserializeObject(targetParams[i], tType);
}
}
object data = method.Invoke(service, finalParams);
response.Write(serializer.Serialize(data));
return true;
}