方法returns 多个对象

Method returns multiple object

我有一个 MVC 4 项目,它使用来自网络的服务 api 1 个项目。

这里我需要一个服务方法,我根据操作传递一个 id 和一个名为 action 的字符串 该服务应该去从 table 获取数据。在这里,我将根据操作有不同的情况。

所以如果我的动作是人,它应该去人 table 并且根据传递的 id 它应该 return LIST

如果操作是电子邮件,它应该根据传递的 id 从电子邮件 table 中获取数据,并且应该 return LIST

是否可以通过单一方法实现,因为我的 return 类型在每种情况下都不同?如果是这样,我的 return 类型的方法是什么?

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();
}

我在网络 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":
             ....
}

有几种方法可以解决这个问题。

  1. You can use [RoutePrefix("api/Service")] for your controller and [Route("User")] and [Route("Email")] , 

你应该也可以调用你的网站 api api/service/user (GET,POST,PUT,删除), 同样的事情也适用于您的电子邮件

 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)

希望这会奏效。

使用此模板 -

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

可能是前面的示例完全遵循了这种开箱即用的方法。