我有一个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
答案 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
可能是前面的例子,正是这种方法开箱即用。