方法返回多个对象

本文关键字:对象 返回 方法 | 更新日期: 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)

希望这会起作用。