方法返回多个对象

时间:2016-02-23 10:23:42

标签: c# asp.net-mvc asp.net-mvc-4 asp.net-web-api asp.net-mvc-routing

我有一个MVC 4项目,该项目使用来自web api 1项目的服务。

这里我需要一个服务方法,我根据动作传递一个id和一个名为 action 的字符串         该服务应该从表中获取数据。在这里,我会根据行动有不同的案例。

因此,如果我的操作是人员,则应该转到人员表并根据传递的ID返回LIST

IF操作是电子邮件,它应根据传递的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;
}

我的get服务调用总是调用相同的方法 根据评论修改如下

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

3 个答案:

答案 0 :(得分:1)

我不喜欢这种做法,但你不要求我们对此提出意见,而是提出具体问题。问题的答案是肯定的。这是可能的。

您可以将HttpResponseMessage用于此目的:

class AsynctaskMovie extends AsyncTask<String, String, ArrayList<Movie>> {

    JSONParser jsonParser = new JSONParser();
    private static final String SEARCH_URL = "http://www.omdbapi.com/?";


    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        movieArrayList = new ArrayList();
        Log.i(getActivity().getCallingPackage(), "onPreExecute");
    }

    @Override
    protected ArrayList<Movie> doInBackground(String... args) {
        Log.i(getActivity().getCallingPackage(),"doInBackground");

        HashMap<String, String> params = new HashMap<>();
        params.put("s", args[0]);
        params.put("r", "json");
        JSONObject json = jsonParser.makeHttpRequest(SEARCH_URL, "GET", params);
        Log.i(getActivity().getCallingPackage(), json.toString());
        if (json != null) {
            try {
                if (json.getString("Response").equals("False")) {
                    return movieArrayList;
                }
            } catch (JSONException e) {
            }
            try {
                JSONArray jsonArray = json.getJSONArray("Search");
                for (int i = 0; i < jsonArray.length(); i++) {
                    JSONObject jsonObject = (JSONObject) jsonArray.get(i);
                    String movieid = jsonObject.getString(App.getInstance().IMDBimdbID);
                    if (!movieid.equals("null")) {
                        Movie movie = new Movie(movieid);
                        movieArrayList.add(movie);
                    }
                }
                jsonArray = new JSONArray();

                for (Movie movie : movieArrayList) {
                    params = new HashMap<>();
                    params.put("i", movie.getMovieid());
                    params.put("plot", "short");
                    params.put("r", "json");
                    JSONObject jsongetfullinfo = jsonParser.makeHttpRequest(SEARCH_URL, "GET", params);
                    if (jsongetfullinfo != null) {
                        jsonArray.put(jsongetfullinfo);
                        Log.i("", jsongetfullinfo.toString());
                    }
                }
                for (int i = 0; i < jsonArray.length(); i++) {
                    JSONObject jObject = jsonArray.getJSONObject(i);
                    movieArrayList.get(i).updateFromIMDB(jObject);
                }
                for (Movie movie : movieArrayList) {
                    movie.setMovieposter(LoadFromUrl(movie.getPosterURL()));
                }
                return movieArrayList;
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        return movieArrayList;
    }

    @Override
    protected void onPostExecute(ArrayList<Movie> movieArrayList) {
        Log.i("ronen", "list size: " + movieArrayList.size());

        if (movieArrayList.size() > 0) {
            listView.setAdapter(new MovieAdapter(getActivity(), movieArrayList));
            listView.setVisibility(View.VISIBLE);
        } else {
            Toast.makeText(getActivity().getApplicationContext(), "No found", Toast.LENGTH_SHORT).show();
        }
    }

    private Bitmap LoadFromUrl(String theurl) {
        URL url = null;
        Bitmap bmp = null;
        try {
            url = new URL(theurl);
            bmp = BitmapFactory.decodeStream(url.openConnection().getInputStream());
        } catch (IOException e) {
        }
        return bmp;
    }
}

答案 1 :(得分:0)

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

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

你应该也可以打电话给你的网络API api / 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)

希望这会奏效。

答案 2 :(得分:0)

使用此模板 -

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

可能是前面的例子,正是这种方法开箱即用。