从MVC控制器调用Web API

13 浏览
0 Comments

从MVC控制器调用Web API

我在我的MVC5项目解决方案中有一个WebAPI控制器。\nWebAPI有一个方法,它以Json列表的形式返回特定文件夹中的所有文件:\n[{\"name\":\"file1.zip\", \"path\":\"c:\\\\\"}, {...}]\n我想从HomeController中调用这个方法,将Json响应转换为List并将这个列表返回给一个Razor视图。如果文件夹中没有文件,这个列表可能是空的:[]。\n这是APIController:\n

public class DocumentsController : ApiController
{
    #region Methods
    /// 
    /// 以Json形式获取存储库中的所有文件。
    /// 
    /// QDocumentRecord的Json表示。
    public HttpResponseMessage GetAllRecords()
    {
      // 找到文件的所有代码都在这里,并且完全正常运行...
         return new HttpResponseMessage()
         {
             Content = new StringContent(JsonConvert.SerializeObject(listOfFiles), Encoding.UTF8, "application/json")
         };
    }               
}

\n这是我的HomeController:\n

public class HomeController : Controller
{
     public Index()
     {
      // 我想调用API的GetAllFiles方法,并将结果放入变量中:
      var files = JsonConvert.DeserializeObject>(API返回的Json);
      }
 }

\n最后这是模型,如果你需要的话:\n

public class QDocumentRecord
{
      public string id {get; set;}
      public string path {get; set;}
   .....
}

\n那么我该如何进行这个调用?

0
0 Comments

问题出现的原因:

- 希望在不同的控制器中调用相同的逻辑代码

- 希望将文件查找的逻辑放入一个公共类中,以便在未来的代码维护中更加简化

解决方法:

- 将原本在ApiController中的代码移动到一个可以同时被HomeController和DocumentController调用的类中

- 将文件查找的逻辑提取到一个公共类中,这样在未来的代码维护中可以更加方便

- 调用API Controller可以在安全性要求较高的场景下使用,例如在支付行业中,安全标准要求网站不能直接访问数据库,而是通过内部的Web服务来访问,以减少数据库被攻击的风险

代码示例:

// 公共类 CommonClass.cs
public class CommonClass
{
    public List GetFiles()
    {
        // 文件查找逻辑
        // ...
        return files;
    }
}
// HomeController.cs
public class HomeController : Controller
{
    public ActionResult Index()
    {
        CommonClass common = new CommonClass();
        List files = common.GetFiles();
        // 其他处理逻辑
        // ...
        return View(files);
    }
}
// DocumentController.cs
public class DocumentController : ApiController
{
    public IHttpActionResult GetFiles()
    {
        CommonClass common = new CommonClass();
        List files = common.GetFiles();
        // 返回文件列表
        return Ok(files);
    }
}

以上是解决这个问题的方法和示例代码。如果安全性不是首要考虑因素,那么将逻辑代码提取到公共类中的方法仍然是一个有效的思考点。

0
0 Comments

问题原因:这段代码中出现了一个问题,即在MVC控制器中调用Web API。问题的根源是在MVC控制器中使用HttpClient来调用Web API时没有正确设置相关参数。

解决方法:为了解决这个问题,我们需要在MVC控制器中对HttpClient进行正确的配置。具体来说,我们需要设置Web API的基本地址、请求头和接受的数据格式。下面是正确的代码示例:

public class ProductsController : Controller
{
    // GET: Products
    public async Task<ActionResult> Index()
    {
        string apiUrl = "http://localhost:58764/api/values";
        using (HttpClient client=new HttpClient())
        {
            client.BaseAddress = new Uri(apiUrl);
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
            HttpResponseMessage response = await client.GetAsync(apiUrl);
            if (response.IsSuccessStatusCode)
            {
                var data = await response.Content.ReadAsStringAsync();
                var table = Newtonsoft.Json.JsonConvert.DeserializeObject<System.Data.DataTable>(data);
            }
        }
        return View();
    }
}

通过以上代码,我们可以正确地在MVC控制器中调用Web API,并且获取到返回的数据。通过设置正确的参数,我们可以确保请求能够成功,并且能够正确解析返回的数据。

0
0 Comments

问题的出现原因:

该问题出现的原因是因为在HomeController中想要调用某个方法并将Json响应转换为List,但是不希望增加HTTP调用和(反)序列化的开销,因为这些代码在同一个程序集中。

解决方法:

1. 从ApiController返回一个具体类型的对象:

public IEnumerable GetAllRecords()
{
    listOfFiles = ...
    return listOfFiles;
}

2. 如果一定要返回HttpResponseMessage类型,仍然不需要手动调用JsonConvert.SerializeObject()方法:

return Request.CreateResponse>(HttpStatusCode.OK, listOfFiles);

3. 将业务逻辑提取到一个专门处理工作的类中:

public class FileListGetter
{
    public IEnumerable GetAllRecords()
    {
        listOfFiles = ...
        return listOfFiles;
    }
}

然后从MVC controller中直接调用这个类或者ApiController:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var listOfFiles = new DocumentsController().GetAllRecords();
        // 或者
        var listOfFiles = new FileListGetter().GetAllRecords();
        return View(listOfFiles);
    }
}

4. 如果确实需要进行HTTP请求,可以使用HttpWebRequest、WebClient、HttpClient或RestSharp等工具库。

在这个例子中,将FileListGetter类放在哪里?在模型中放置这个逻辑是否可行?

FileListGetter类可以放在控制器内部,也可以作为一个单独的类放在控制器外部。将这个逻辑放在模型中是可行的。

0