Я использую веб-API.Net MVC4 для (надеюсь) реализации RESTful api. Мне нужно передать несколько параметров в систему и выполнить какое-либо действие, а затем вернуть список объектов в качестве результатов. В частности, я прохожу через две даты и возвращая записи, которые находятся между ними. Я также отслеживаю возвращаемые записи, чтобы последующие вызовы не перерабатывались в системе.
Я рассмотрел несколько подходов:
-
Сериализация параметров в одну строку JSON и выделение ее в API.
http://forums.asp.net/t/1807316.aspx/1 -
Передайте параметры в строке запроса.
Каков наилучший способ передать несколько параметров запроса в restful api? -
Определение параметров на маршруте:
API/контроллер/date1/дата2 -
Использование POST, который по сути позволяет мне передать объект с параметрами.
-
Исследование ODATA, поскольку веб-API (в настоящее время) поддерживает его. Я еще не много сделал с этим, поэтому я не очень хорошо знаком с ним.
Кажется, что правильные методы REST указывают, когда данные тянутся, вы должны использовать GET. Однако GET также должен быть нулевым (не вызывает побочных эффектов), и мне интересно, нарушает ли моя конкретная реализация это, поскольку я отмечаю записи в системе API, поэтому я создаю побочные эффекты.
Это также привело меня к вопросу поддержки переменных параметров. Если список входных параметров изменится, было бы утомительно повторить определение вашего маршрута для выбора 3, если это произойдет очень часто. И что может произойти, если параметры определены во время выполнения…
В любом случае, для моей конкретной реализации, какой выбор (если есть) лучше всего?
Что означает эта маркировка записи? Если это используется только для целей регистрации, я бы использовал GET и отключил бы все кэширование, так как вы хотите регистрировать каждый запрос для этих ресурсов. Если у маркировки записи есть другая цель, POST – путь. Пользователь должен знать, что его действия влияют на систему, а метод POST является предупреждением.
Я думаю, что самый простой способ – просто использовать AttributeRouting
.
В вашем контроллере очевидно, почему вы хотите это в своем глобальном файле WebApiConfig
?
Пример:
[Route("api/YOURCONTROLLER/{paramOne}/{paramTwo}")]
public string Get(int paramOne, int paramTwo)
{
return "The [Route] with multiple params worked";
}
Названия {}
должны соответствовать вашим параметрам.
Простым образом, теперь у вас есть отдельный GET
, который обрабатывает несколько параметров в этом экземпляре.
Просто добавьте новый маршрут в записи WebApiConfig
.
Например, для вызова:
public IEnumerable<SampleObject> Get(int pageNumber, int pageSize) { ..
добавить:
config.Routes.MapHttpRoute(
name: "GetPagedData",
routeTemplate: "api/{controller}/{pageNumber}/{pageSize}"
);
Затем добавьте параметры в HTTP-вызов:
GET //<service address>/Api/Data/2/10
Мне просто нужно было выполнить RESTfull api, где мне нужно передать параметры. Я сделал это, передав параметры в строке запроса в том же стиле, как описано в первом примере “api/controller? Start = date1 & end = date2”
В контроллере я использовал подсказку из URL-адреса, разделенного на С#?
// uri: /api/courses
public IEnumerable<Course> Get()
{
NameValueCollection nvc = HttpUtility.ParseQueryString(Request.RequestUri.Query);
var system = nvc["System"];
// BL comes here
return _courses;
}
В моем случае я вызывал WebApi через Ajax, как:
$.ajax({
url: '/api/DbMetaData',
type: 'GET',
data: { system : 'My System',
searchString: '123' },
dataType: 'json',
success: function (data) {
$.each(data, function (index, v) {
alert(index + ': ' + v.name);
});
},
statusCode: {
404: function () {
alert('Failed');
}
}
});
Надеюсь, это поможет…
Я нашел отличное решение на http://habrahabr.ru/post/164945/
public class ResourceQuery
{
public string Param1 { get; set; }
public int OptionalParam2 { get; set; }
}
public class SampleResourceController : ApiController
{
public SampleResourceModel Get([FromUri] ResourceQuery query)
{
// action
}
}
Использование GET или POST ясно объясняется @LukLed. Что касается способов передачи параметров, я бы предложил перейти со вторым подходом (я тоже мало знаю об ODATA).
1. Сериализация параметров в одну строку JSON и выделение ее в API. http://forums.asp.net/t/1807316.aspx/1
Это не дружелюбный к пользователю и оптимизированный для SEO
2. Настройте параметры в строке запроса. Каков наилучший способ передать несколько параметров запроса для спокойного api?
Это обычный предпочтительный подход.
3. Определение параметров на маршруте: api/controller/date1/date2
Это определенно не очень хороший подход. Это заставляет чувствовать, что один date2
является вспомогательным ресурсом date1
, и это не так. Оба параметра date1
и date2
являются параметрами запроса и находятся на одном уровне.
В простом случае я бы предложил URI, как это,
api/controller?start=date1&end=date2
Но мне лично нравится шаблон ниже URI, но в этом случае мы должны написать некоторый код для сопоставления параметров.
api/controller/date1,date2
Используйте привязку параметров, как описано здесь полностью: http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api
[Route("api/controller/{one}/{two}")]
public string Get(int One, int Two)
{
return "both params of the root link({one},{two}) and Get function parameters (one, two) should be same ";
}
Оба параметра корневой ссылки ({one}, {two}) и параметров функции Get (one, two) должны быть одинаковыми
Я знаю, что это действительно старый, но я недавно хотел то же самое, и вот что я нашел…
public HttpResponseMessage Get([FromUri] string var, [FromUri] string test) {
var retStr = new HttpResponseMessage(HttpStatusCode.OK);
if (var.ToLower() == "getnew" && test.ToLower() == "test") {
retStr.Content = new StringContent("Found Test", System.Text.Encoding.UTF8, "text/plain");
} else {
retStr.Content = new StringContent("Couldn't Find that test", System.Text.Encoding.UTF8, "text/plain");
}
return retStr;
}
Так что теперь в ваш адрес /URI/…
HTTP (s)://myURL/API/myController/вар = getnew & тест = тест
Результат: “Найден тест”
HTTP (s)://myURL/API/myController/вар = getnew & тест = ничего
Результат: “Не удалось найти этот тест”
public HttpResponseMessage Get(int id,string numb)
{
//this will differ according to your entity name
using (MarketEntities entities = new MarketEntities())
{
var ent= entities.Api_For_Test.FirstOrDefault(e => e.ID == id && e.IDNO.ToString()== numb);
if (ent != null)
{
return Request.CreateResponse(HttpStatusCode.OK, ent);
}
else
{
return Request.CreateErrorResponse(HttpStatusCode.NotFound, "Applicant with ID " + id.ToString() + " not found in the system");
}
}
}
Теперь вы можете сделать это, просто используя
public string Get(int id, int abc)
{
return "value: " + id + " " + abc;
}
это вернет: “значение: 5 10”
если вы называете это с https://yourdomain/api/yourcontroller?id=5&abc=10