如何将整个 http URL 传递给 asp.net API 中的存储过程?
How do I pass the whole http URL to a stored procedure in an asp.net API?
我的任务是创建一个 asp.net API 其中:
- 用户向我的 APi 端点发帖 XML
- API 将整个 XML 直接传递给存储过程
- 存储过程returns一些XML返回给用户API
对 api 的调用示例:
https://localhost:44308/api/OrderProcessing?<?xml version="1.0"encoding="utf-8"?><Param1>abc123</Param1><Param2>5</Param2><Param3>123456</Param3>etc.. etc
我发现了很多从 asp.net 调用过程的示例,所有示例都显示 XML 节点被解析为参数以传递给存储过程:
usp_myproc @param1 =abc123, @param2 =5, @param3 =123456 etc.
我找不到如何将 xml 作为单个字符串传递,如下所示 EG
usp_myproc @param1 =xml version="1.0"encoding="utf-8"?><Param1>abc123</Param1><Param2>5</Param2><Param3>123456</Param3>etc.. etc
到目前为止,我有以下代码,其中当然只是传递了第一个参数,例如。 usp_myproc @param1
不是整个字符串
namespace OrderProcessingApp.Controllers
{
public class OrderProcessingController : ApiController
{
[HttpGet]
public IHttpActionResult StockOrder(string param1)
{
StockFinderEntities sd = new StockFinderEntities();
var results = sd.fn_ProcessOrder(param1).ToList();
}
}
}
非常感谢收到的任何帮助
这里有很多内容需要解压缩,并且缺少一些信息,另请参阅我对您的问题的评论。虽然你的问题中有可以回答的部分,但情况远非最佳。
如果我没说错,你想要这个:
- 一个 API 端点,它接受查询字符串完全由 XML 字符串组成的 GET 请求。
- 在此操作方法中,将 XML 字符串传递给 SQL 用户定义函数。
- 此函数解析 XML,执行其操作,returns 零个或多个记录。
- 然后将这些记录作为列表返回给调用者。
首先,您必须阅读 XML。您的查询字符串似乎没有键(它直接以 ?<xml...>
开头)。这是故意的,还是在创建这个问题时的疏忽?您真的确定要从查询字符串中读取 XML 吗,或者您可以更改此设计吗?
如果您可以更改它,惯用的方法是使用查询字符串参数,然后将其绑定到您的操作方法参数:
// 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 被视为普通的旧字符串,所以您有 none 的验证或安全措施。
我的任务是创建一个 asp.net API 其中:
- 用户向我的 APi 端点发帖 XML
- API 将整个 XML 直接传递给存储过程
- 存储过程returns一些XML返回给用户API
对 api 的调用示例:
https://localhost:44308/api/OrderProcessing?<?xml version="1.0"encoding="utf-8"?><Param1>abc123</Param1><Param2>5</Param2><Param3>123456</Param3>etc.. etc
我发现了很多从 asp.net 调用过程的示例,所有示例都显示 XML 节点被解析为参数以传递给存储过程:
usp_myproc @param1 =abc123, @param2 =5, @param3 =123456 etc.
我找不到如何将 xml 作为单个字符串传递,如下所示 EG
usp_myproc @param1 =xml version="1.0"encoding="utf-8"?><Param1>abc123</Param1><Param2>5</Param2><Param3>123456</Param3>etc.. etc
到目前为止,我有以下代码,其中当然只是传递了第一个参数,例如。 usp_myproc @param1
不是整个字符串
namespace OrderProcessingApp.Controllers
{
public class OrderProcessingController : ApiController
{
[HttpGet]
public IHttpActionResult StockOrder(string param1)
{
StockFinderEntities sd = new StockFinderEntities();
var results = sd.fn_ProcessOrder(param1).ToList();
}
}
}
非常感谢收到的任何帮助
这里有很多内容需要解压缩,并且缺少一些信息,另请参阅我对您的问题的评论。虽然你的问题中有可以回答的部分,但情况远非最佳。
如果我没说错,你想要这个:
- 一个 API 端点,它接受查询字符串完全由 XML 字符串组成的 GET 请求。
- 在此操作方法中,将 XML 字符串传递给 SQL 用户定义函数。
- 此函数解析 XML,执行其操作,returns 零个或多个记录。
- 然后将这些记录作为列表返回给调用者。
首先,您必须阅读 XML。您的查询字符串似乎没有键(它直接以 ?<xml...>
开头)。这是故意的,还是在创建这个问题时的疏忽?您真的确定要从查询字符串中读取 XML 吗,或者您可以更改此设计吗?
如果您可以更改它,惯用的方法是使用查询字符串参数,然后将其绑定到您的操作方法参数:
// 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 被视为普通的旧字符串,所以您有 none 的验证或安全措施。