我正在开发一个MVC 5 Web应用程序。我有以下几层: -
现在我有以下要求: -
在一些操作方法中,我希望我的应用程序向第三方应用程序发送一些API调用(使用WebClient()
)。
除Description
参数外,所有操作方法的API调用几乎相同。现在我可以在我的存储库类中拥有这个共享逻辑,并从我的操作方法中引用它。但据我所知,存储库类不应公开或引用WebClient()
或类似的Web类,因为存储库应仅处理数据库和模型类。
所以我不确定管理共享WebClient
来电的最佳位置是什么?所以从动作方法我只调用共享类并传递描述字段?
例如,以下是直接包含Web客户端的操作方法示例: -
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Server s)
{
if (ModelState.IsValid)
{
try
{
//code goes here....
XmlDocument doc = new XmlDocument();
using (var client = new WebClient())
{
var query = HttpUtility.ParseQueryString(string.Empty);
query["username"] = System.Web.Configuration.WebConfigurationManager.AppSettings["ApiUserName"];
query["password"] = System.Web.Configuration.WebConfigurationManager.AppSettings["ApiPassword"];
query["assetType"] = controllername;
query["operation"] = "UpdateAsset";
query["assetName"] = s.RESOURCENAME;
query["description"] = s.DESCRIPTION;
//code goes here
var url = new UriBuilder(apiurl);
url.Query = query.ToString();
try
{
string xml = client.DownloadString(url.ToString());
doc.LoadXml(xml);
updatestatus = doc.SelectSingleNode("/operation/operationstatus").InnerText;
}
catch (WebException ex)
{
ModelState.AddModelError(string.Empty, "Error occurred:" + ex.InnerException.Message);
}
}
}
}
}
现在我不想在多个动作方法上添加相同的WebClient
方法,而是在共享类上使用WebClient(),并从相关的动作方法中引用它。
答案 0 :(得分:1)
代码示例会有所帮助,但总的来说,我认为您已经走上了正确的道路。
但是我知道存储库类不应该公开或引用 WebClient()或类似的Web类,作为存储库应处理的 仅限数据库和模型类
它不只是关于数据库。我的感觉是存储库处理"数据源"和外部服务属于这一点。关于这一点没有绝对的规则。在你的情况下有什么意义?
所以我不确定管理共享WebClient的最佳位置是什么 打电话?
我认为存储库很好。根据您的架构,它还适合哪里?您可以随时添加WebApi部分,但它可能不会添加任何值,只会使事情变得复杂。
所以从action方法我只调用共享类并传递 描述字段?
对我来说看起来像个计划。您还可以跳过控制器/操作方法调用,并通过ajax调用直接从您的视图转到服务
答案 1 :(得分:1)
您可以创建一个操作过滤器来管理此API调用...因此您无需使用此代码来调用您的操作o调用其他类。
如果描述在每个动作中都是静态的,你甚至可以将描述放在装饰器本身。
[Httppost]
[ValidateAntiForgeryToken]
[MyApiFilter(Description="theDescription")]
public ActionResult Create(Server s)
{
//Your action code
}
如果你不能将描述放在装饰器中并需要更动态的东西,你可以在动作代码中设置一些参数,在运行时由过滤器设置。
[Httppost]
[ValidateAntiForgeryToken]
[MyApiFilter]
public ActionResult Create(Server s)
{
//Your action code
this.SetAdditionalInfo(myDescription)
}
在 BaseController :
中public void SetAdditionalInfo(string description)
{
this.APICallDescription = description;
}
基础ActionFilterAttribute
类具有以下可以覆盖的方法:
OnActionExecuting
- 在控制器操作之前调用此方法 被执行。
OnActionExecuted
- 在控制器操作后调用此方法 被执行。
OnResultExecuting
- 在控制器操作之前调用此方法 结果被执行。
OnResultExecuted
- 在控制器操作后调用此方法 结果被执行。