方法返回多个对象
本文关键字:对象 返回 方法 | 更新日期: 2023-09-27 18:35:45
我有一个MVC 4项目,它使用来自Web api 1项目的服务。
在这里,我需要有一个服务方法,在其中我根据操作传递一个 id 和一个名为 action 的字符串 服务应该去从表中获取数据。在这里,我将根据操作有不同的情况。
因此,如果我的操作是人,它应该转到人员表,并根据传递的id返回LIST
列表如果操作是电子邮件,它应该根据传递的 id 从电子邮件表中获取数据,并应返回 LIST
是否可以从单一方法实现,因为我的返回类型在每种情况下都不同?如果是这样,该方法的返回类型是什么?
public Email GetEmail(int id)
{
Email email = db.Emails.Find(id);
if (email == null)
{
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
}
return email;
}
public List<Email> GetEmailByPerson(int personid)
{
List<Email> email = db.Emails.Where(n => n.PersonID == personid).ToList();
if (email == null)
{
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
}
return email;
}
public Person GetPerson(int id)
{
Person person = db.Persons.Find(id);
return person;
}
我的获取服务调用总是调用相同的方法根据评论修改如下
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
控制器操作的代码为:
[ActionName=EmailsByPersonID]
public IEnumerable<Email> GetEmailsByPersonID(int personid)
{
var emails = db.Emails.Where(n => n.Personid == personid).ToList();
if (emails == null)
{
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
}
return emails.AsEnumerable();
}
我已经在web api.config文件中进行了这些更改,并用操作名称:EmailByPerson装饰了我的方法,服务调用是http://localhost:XXXX/ActionApi/Email/EmailsByPersonID/1
我不喜欢这种方法,但你不会要求我们对此发表意见,而是一个具体的问题。问题的答案是肯定的,这是可能的。
您可以使用 HttpResponseMessage 来实现此目的:
public HttpResponseMessage GetXx(string type, int id)
{
switch(type)
{
case "xx":
Type1 obj1 = <your logic>;
return Request.CreateResponse(HttpStatusCode.OK, obj1);
case "yy":
....
}
使用此模板 -
public class MyController : ApiController
{
public string GetName(string id)
{
return id;
}
public string GetNameById(string id)
{
return id;
}
}
GlobalConfiguration.Configuration.Routes.MapHttpRoute
("default","api/{controller}/{action}/{id}",new { id = RouteParameter.Optional });
然后像这样调用 API -
http://localhost:port/api/My/GetName/12
http://localhost:port/api/My/GetNameById/12
至少对我有用。 :)
更新
你也可以这样做——
public class CustomActionInvoker : ApiControllerActionSelector
{
public override HttpActionDescriptor SelectAction(HttpControllerContext controllerContext)
{
if (controllerContext == null)
throw new ArgumentNullException("controllerContext");
var routeData = (string)controllerContext.RouteData.Values["optional"];
if (!string.IsNullOrWhiteSpace(routeData))
{
var actionInfo = controllerContext.ControllerDescriptor.ControllerType
.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly).ToList();
var methodInfo = actionInfo.Where(a => a.Name.Contains(routeData)).FirstOrDefault();
if (methodInfo != null)
{
return new ReflectedHttpActionDescriptor(controllerContext.ControllerDescriptor, methodInfo);
}
}
return base.SelectAction(controllerContext);
}
}
在配置中 -
GlobalConfiguration.Configuration.Routes.MapHttpRoute("default", "api/{controller}/{optional}/{id}", new { id = RouteParameter.Optional });
GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpActionSelector), new CustomActionInvoker());
并将 api 调用更改为 -
http://localhost:port/api/My/Email/12
可能前面的示例完全遵循了这种方法开箱即用。
有几种方法可以解决此问题。
1. You can use [RoutePrefix("api/Service")] for your controller and [Route("User")] and [Route("Email")] ,
你也应该能够调用你的 Web APIapi/service/user (GET,POST,PUT,DELETE) ,同样的事情也适用于您的电子邮件
2. you can create IModel/IResult/SuperClass for your User/Email, and your web api method would be like IEnumerable<IModel> Get(string entityType) or
IModel Get(string entityType,int id)
希望这会起作用。