Я пытаюсь отправить значение своего текстового поля на панель инструментов в действие WEB API. Я искал различные онлайн-решения. Однако никто не работает.
На стороне клиента у меня есть "KeyUp" событие в "текстовом поле поиска". После завершения, мне нужно добавить значение к READ.
Я ПОСЫЛ СЛЕДУЮЩИЙ (КЛИЕНТСКАЯ СТОРОНА):
// This Fails
var value = dictionary.elements.txtDeviceSearch.val();
var url = "api/devicedataitem/search?text='" + value + "'";
dictionary.instances.gridDevices.dataSource.options.transport.read.url = url;
dictionary.instances.gridDevices.dataSource.read();
// This Fails
dictionary.instances.gridDevices.dataSource.options.transport.read.data = { text: value };
dictionary.instances.gridDevices.dataSource.read();
// This Fails
dictionary.instances.gridDevices.dataSource.read({ text: 'Work Dammit' });
НАЧАЛЬНЫЙ ПРИЗЫВ РАБОТЫ КАК ОЖИДАЕТСЯ:
Это работает как ожидается...
@(Html.Kendo().Grid<DeviceDataItem>()
.Name("gridDevices")
.DataSource(dataSource => dataSource
.WebApi()
.Model(model =>
{
model.Id(m => m.DeviceId);
model.Field(m => m.DeviceName);
model.Field(m => m.CommunicationTechnicianId);
model.Field(m => m.CommunicationTechnicianFullName);
model.Field(m => m.MeasurementTechnicianId);
model.Field(m => m.MeasurementTechnicianFullName);
})
.Read(read => read.Url("api/devicedataitem/search?text=''").Type(HttpVerbs.Post))
)
.ToolBar(toolbar =>
{
toolbar.Template(@<text>
<div class="input-group pull-right" role="toolbar">
<span class="input-group-addon">
<span class="glyphicon glyphicon-search" aria-hidden="true"></span>
</span>
<input type="text" class="form-control" id='txtDeviceSearch' placeholder="Search for..." />
</div>
</text>);
})
.Deferred(true))
Ну, наконец, я понял, что это было сложно, и это было сложно. Этот конкретный ответ имеет много аспектов:
GET - WEB API:
Это работает, потому что "Attribute Binder Attribute" захватывает объект REQUEST и увлажняет его для вас. Без него REQUEST всегда будет нулевым.
// GET: /api/DeviceDataItem/Search
[HttpGet]
public DataSourceResult Search([ModelBinder(typeof(WebApiDataSourceRequestModelBinder))] DataSourceRequest request, string search)
{
var application = (MyApplication)Application;
var provider = (DeviceDataItemProvider)application.DeviceDataItemProvider;
IQueryable<DeviceDataItem> query = provider.Query();
// No 'Where' needed
if (string.IsNullOrWhiteSpace(search))
return query.ToDataSourceResult(request);
// Where
...your WHERE logic goes here...
return query.ToDataSourceResult(request);
}
GET - MVC.Read:
Обратите внимание, что я имею в виду пользовательский объект " Page Controller
который является общедоступным через окно.
.Read(read => read.Url(Url.HttpRouteUrl("DefaultApi", new { controller = "DeviceDataItem", action="Search"}))
.Type(HttpVerbs.Get)
.Data("window.pageController.on.read.gridDevices"))
GET - JavaScript:
Я использую кеширование своих объектов в Контроллере страниц - вам придется ссылаться на свои объекты (однако они построены).
this.on = {
read: {
gridDevices: function () {
return {
search: dictionary.elements.txtDeviceSearch.val()
}
}
},
search: {
gridDevices: function (e) {
lazyInitGridDevices();
// Clear
dictionary.instances.gridDevices.dataSource.data([]);
dictionary.instances.gridDevices.refresh();
// Read
dictionary.instances.gridDevices.dataSource.read();
}
}
};
СООБЩЕНИЕ:
Согласно Telerik, такой же подход используется для передачи параметров POST-запросам. Однако с помощью Web API второй параметр не может быть добавлен к сигнатуре метода. Одним из возможных способов решения этого сценария является использование JObject для получения всех данных из запроса и последующего создания нового объекта модели с использованием этих данных.
Например:
public HttpResponseMessage Post(JObject jsonData)
{
ProductViewModel product = new ProductViewModel() {
ProductName = (string)jsonData["ProductName"],
UnitPrice = (decimal)jsonData["ProductID"],
UnitsInStock = (int)jsonData["ProductName"],
Discontinued = (bool)jsonData["ProductID"]
};
string searchTerm = (string)jsonData["search"];
.............
}
Теперь мы куда-то попадаем, этот вопрос лучше, чем другой. То, что я собирался сказать тогда, прежде чем отказаться от этого, заключается в том, что в виджете JavaScript есть параметр под названием parameterMap
где вы можете манипулировать данными, которые будут отправляться в запросе API. Как указано в документах, вы можете попробовать:
parameterMap: function (data, type) {
return kendo.stringify($.extend({ "text": $("#txtDeviceText").text() }, data));
}
Но я не знаю, как добавить его к помощнику бритвы, потому что их документы слишком сильно засасывают, и я не могу его проверить. Поэтому вы можете попробовать:
Добавление параметра в инициализацию (что я не уверен, что работает):
DataSource(dataSource => dataSource.ParameterMap("jsFunctionNameHere")
Или что-то типа того;
Установка его в сетку после инициализации:
$("#grid").data("kendoGrid").dataSource.transport.parameterMap = function() {
return { text: $("#txtDeviceText").text() };
};
Я ставлю на 2-й вариант, он должен работать.
Попробуйте:
dictionary.instances.gridDevices.dataSource.type = "aspnetmvc-ajax";
Мы делаем то же самое в нашем приложении, отправляя параметры в действие контроллера в дополнение к объекту DataSourceRequest. При удалении этого параметра типа, я получаю то же поведение, что и вы, с параметрами, полученными с нулевыми значениями.
Источник данных определяется с помощью js, схожих с этим:
this.results = new kendo.data.DataSource({
type: "aspnetmvc-ajax",
transport: {
read: {
url: "Controller/Search",
data: function () {
return {
value: "abc"
};
}
}
}
});
Когда на нем запускается функция read(), он выполняет действие контроллера следующим образом:
public JsonResult Search([DataSourceRequest] DataSourceRequest request, string value)
Так что ничего необычного там, но с удаленным типом, значение не получено. Обратите внимание, что это System.Web.MVC.Controller, а не System.Web.Http.ApiController, хотя я не вижу, как это изменит ситуацию. Также может быть, что тип источника данных может быть эффективно установлен только в момент его установки (поэтому он будет использоваться в определении, не измененном после того факта, который я изначально предложил), но это просто другое предположение. Я чувствую твою боль - такое дело должно работать.