C# 在我的asp.net mvc中管理对第三方应用程序的共享API调用的最佳位置

C# 在我的asp.net mvc中管理对第三方应用程序的共享API调用的最佳位置,c#,asp.net-mvc,asp.net-mvc-5,C#,Asp.net Mvc,Asp.net Mvc 5,我正在开发一个MVC5Web应用程序。我有以下几层:- 观点 控制器类 存储库类,这些类在控制器类中被引用 模型分类 实体框架数据库上下文 现在我有以下要求:- 在某些操作方法中,我希望我的应用程序向第三方应用程序发送一些API调用(使用WebClient()) 其中,除了Description参数外,所有操作方法的API调用几乎相同。现在,我可以在我的存储库类中拥有这个共享逻辑,并从我的操作方法中引用它。但正如我所知,repository类不应该公开或引用WebClient()或类似的web类

我正在开发一个MVC5Web应用程序。我有以下几层:-

  • 观点
  • 控制器类
  • 存储库类,这些类在控制器类中被引用
  • 模型分类
  • 实体框架数据库上下文
  • 现在我有以下要求:-

    在某些操作方法中,我希望我的应用程序向第三方应用程序发送一些API调用(使用
    WebClient()

    其中,除了
    Description
    参数外,所有操作方法的API调用几乎相同。现在,我可以在我的存储库类中拥有这个共享逻辑,并从我的操作方法中引用它。但正如我所知,repository类不应该公开或引用
    WebClient()
    或类似的web类,因为repository应该只处理数据库和模型类。 因此,我不确定管理共享
    WebClient
    呼叫的最佳位置是什么?那么从action方法中,我只调用共享类并传递description字段

    例如,下面是一个直接包含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(),并从相关的操作方法中引用它。

    代码示例将有所帮助,但总的来说,我认为您在这方面做得对

    但正如我所知,repository类不应该公开或引用 WebClient()或类似的web类,这是存储库应该处理的 仅数据库和模型类

    这不仅仅是数据库的问题。我的感觉是存储库处理“数据源”,外部服务属于这一类。这方面没有绝对的规则。在你的情况下什么是有意义的

    因此,我不确定管理共享WebClient的最佳位置是什么 电话

    我认为存储库很好。基于您的体系结构,它还适合于哪些方面?您可以随时添加WebApi,但它可能不会增加任何价值,只会使事情变得复杂

    因此,从action方法中,我只调用共享类并传递 描述字段


    在我看来这是个计划。您也可以跳过控制器/动作方法调用,通过ajax调用直接从视图转到服务,代码示例将有所帮助,但总体而言,我认为您在这方面做得不错

    但正如我所知,repository类不应该公开或引用 WebClient()或类似的web类,这是存储库应该处理的 仅数据库和模型类

    这不仅仅是数据库的问题。我的感觉是存储库处理“数据源”,外部服务属于这一类。这方面没有绝对的规则。在你的情况下什么是有意义的

    因此,我不确定管理共享WebClient的最佳位置是什么 电话

    我认为存储库很好。基于您的体系结构,它还适合于哪些方面?您可以随时添加WebApi,但它可能不会增加任何价值,只会使事情变得复杂

    因此,从action方法中,我只调用共享类并传递 描述字段


    在我看来这是个计划。您还可以跳过控制器/操作方法调用,通过ajax调用直接从视图转到服务

    您可以创建操作过滤器来管理此API调用。。。因此,您不需要使用此代码来处理对其他类的调用

    如果描述在每个动作中都是静态的,那么您甚至可以将描述放在装饰器本身中

    [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)
    }
    
    基本控制器中

    public void SetAdditionalInfo(string description)
    {
        this.APICallDescription = description;
    }
    
    基本
    ActionFilterAttribute
    类具有以下可重写的方法:

    OnActionExecuting
    –在控制器操作之前调用此方法 被执行

    OnActionExecuted
    –此方法在控制器操作后调用 被执行

    OnResultExecuting
    –在控制器操作之前调用此方法 结果被执行

    OnResultExecuted
    –此方法在控制器操作后调用 结果被执行


    您可以创建操作筛选器来管理此API调用。。。因此,您不需要使用此代码来处理对其他类的调用

    如果描述在每个动作中都是静态的,那么您甚至可以将描述放在装饰器本身中

    [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)
    }
    
    基本控制器中

    public void SetAdditionalInfo(string description)
    {
        this.APICallDescription = description;
    }
    
    基本
    ActionFilterAttribute
    类具有以下可重写的方法:

    OnActionExecuting
    –在控制器操作之前调用此方法 被执行

    OnActionExecuted
    –此方法在控制器操作后调用 被执行

    OnResultExecuting
    –在控制器操作之前调用此方法 结果被执行

    OnResultExecuted
    –此方法在控制器操作后调用 结果被执行


    你能给我们看一段你的代码吗?所以我们可以看到它是如何结合在一起的?@JamieR你能检查我的编辑吗?我提供了一个直接包含WebClient的操作方法的示例。我正在尝试将这个共享WebClient移动到一个共享位置。你能给我们看一下你的代码片段吗?所以我们可以看看它是如何结合在一起的?@JamieR你能检查我的编辑吗,,我提供了一个动作冰毒的样本