Здесь много чего нужно распаковать, но некоторая информация отсутствует, см. Также мои комментарии по вашему вопросу. В вашем вопросе есть части, на которые можно ответить, но все далеко не оптимально.
Если я правильно понимаю, вам нужно следующее:
- Конечная точка API, которая принимает запросы GET с строка запроса, состоящая полностью из строки XML.
- В этом методе действия передайте строку XML в SQL пользовательскую функцию.
- Эта функция анализирует XML, выполняет свою задачу и возвращает ноль или более записей .
- Эти записи затем возвращаются вызывающему абоненту в виде списка.
Итак, обо всем по порядку, вы должны прочитать это XML. В вашей строке запроса нет ключей (она начинается с ?<xml...>
). Это намеренно или из-за упущения при создании этого вопроса? Вы действительно уверены, что хотите прочитать XML из строки запроса, или можете изменить этот дизайн?
Если вы можете его изменить, то идиоматическим c способом будет использование параметров строки запроса, которые затем привязываются к параметрам вашего метода действия:
// GET .../StockOrder?param1=42¶m2=Foo¶m3=Bar
public IHttpActionResult StockOrder(string param1, string param2, string param3) { ... }
Предполагая, что вы действительно хотите считайте необработанную строку запроса как XML, а не как один параметр:
// GET .../StockOrder?xmlString=<xml...>
public IHttpActionResult StockOrder(string xmlString) { ... }
Тогда вам вообще не нужны параметры:
// GET .../StockOrder?<xml...>
public IHttpActionResult StockOrder()
{
string xmlString = this.Request.RequestUri.Uri.Query.Value;
...
}
Итак, теперь у вас есть XML строка, и вы передадите ее пользовательской функции в своей базе данных. Хотя Entity Framework упаковывает его в параметр SQL, по крайней мере, вы будете защищены от инъекции SQL здесь:
// GET .../StockOrder?<xml...>
public IHttpActionResult StockOrder()
{
string xmlString = this.Request.RequestUri.Uri.Query.Value;
if (xmlString?.Length > 0)
{
// Remove the question mark from the start
xmlString = xmlString.Substring(1);
}
var results = sd.fn_ProcessOrder(xmlString).ToList();
...
}
Но это все еще далеко от оптимального! Вызывающий может передать неверный XML, который будет обнаружен только SQL сервером, что слишком поздно в процессе. Или, что еще хуже, это может быть специально созданный XML, которым сервер SQL подавился бы (как бомба XML), или хуже (выполнение произвольного кода, содержащегося в XML). Поэтому я бы не был сторонником отправки пользовательского ввода в форме XML непосредственно на SQL сервер, номер
Оптимальный способ будет выглядеть так:
public class GetStockOrderModel
{
[Required]
public string Param1 { get; set; }
[Required]
public string Param2 { get; set; }
[Required]
public string Param3 { get; set; }
}
// GET .../StockOrder?param1=42¶m2=Foo¶m3=Bar
public IHttpActionResult StockOrder([FromUri] GetStockOrderModel model)
{
if (!ModelState.IsValid)
{
// ...
}
var records = sd.fn_ProcessOrder(model.Param1, model.Param2, model.Param3).ToList();
var models = records.Select(o => new
{
FieldToReturn = o.Field1,
OtherField = o.Field2,
// ...
}).ToList();
return Ok(models);
}
Здесь у вас есть модель для привязки и выполнения проверки, функция базы данных изменена, чтобы принимать фактические параметры вместо XML, и возвращается модель, отделенная от базы данных.
Теперь, если вы скажете, что вы не может изменить функцию, потому что другие приложения вызывают ее, вы все еще можете это сделать. Вызываемая вами функция состоит из двух частей: одна, которая считывает параметры из XML, а другая выполняет запрос с использованием этих параметров.
Таким образом, вы сохраняете исходную функцию и позволяете ей вызывать новую после извлечения параметров. Затем вы также можете вызвать эту новую функцию, используя параметры, которые у вас есть в коде.
И действительно, вы не хотите передавать пользователя XML на свой сервер базы данных. Конечно, вызовут только доверенные лица, скажете вы. Но можно ли доверять всем на этих вечеринках? И разве они никогда не ошибаются?
Итак, если вы действительно не хотите ничего менять ни в конечной точке, ни в функции, и вы собираетесь использовать этот четвертый (или второй) блок кода, по адресу по крайней мере, прочтите строку XML в вашем контроллере, проанализируйте ее, извлеките параметры, проверьте их и перестройте XML из безопасной строки шаблона или что-то в этом роде.
Потому что для ASP. NET, этот XML рассматривается как простая старая строка, поэтому у вас нет никаких мер проверки или безопасности.