从MVC控制器调用Web API

A-S*_*ani 23 c# asp.net-mvc asp.net-web-api

我的MVC5项目解决方案中有一个WebAPI控制器.WebAPI有一个方法,它将特定文件夹中的所有文件作为Json列表返回:

[{"name":"file1.zip", "path":"c:\\"}, {...}]

从我的HomeController我想调用此方法,将Json响应转换为List<QDocument>并将此列表返回到Razor视图.此列表可能为空:[]如果文件夹中没有文件.

这是APIController:

public class DocumentsController : ApiController
{
    #region Methods
    /// <summary>
    /// Get all files in the repository as Json.
    /// </summary>
    /// <returns>Json representation of QDocumentRecord.</returns>
    public HttpResponseMessage GetAllRecords()
    {
      // All code to find the files are here and is working perfectly...

         return new HttpResponseMessage()
         {
             Content = new StringContent(JsonConvert.SerializeObject(listOfFiles), Encoding.UTF8, "application/json")
         };
    }               
}
Run Code Online (Sandbox Code Playgroud)

这是我的HomeController:

public class HomeController : Controller
{
     public Index()
     {
      // I want to call APi GetAllFiles and put the result to variable:
      var files = JsonConvert.DeserializeObject<List<QDocumentRecord>>(API return Json);
      }
 }
Run Code Online (Sandbox Code Playgroud)

最后,这是您需要的模型:

public class QDocumentRecord
{
      public string id {get; set;}
      public string path {get; set;}
   .....
}
Run Code Online (Sandbox Code Playgroud)

那我怎么能打这个电话呢?

Lif*_*fPi 19

它在这里很晚,但想分享下面的代码.如果我们将WebApi作为一个完全不同的项目放在同一个解决方案中,那么我们可以从MVC控制器调用相同的内容,如下所示

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();

        }
    }
Run Code Online (Sandbox Code Playgroud)


Cod*_*ter 18

从我的HomeController我想调用此方法并将Json响应转换为List

不,你没有.当代码触手可及时,您真的不想添加HTTP调用和(反)序列化的开销.它甚至在同一个组件中!

无论如何,你的ApiController反对(我的首选)惯例.让它返回一个具体类型:

public IEnumerable<QDocumentRecord> GetAllRecords()
{
    listOfFiles = ...
    return listOfFiles;
}
Run Code Online (Sandbox Code Playgroud)

如果你不想那样而且你绝对确定你需要返回HttpResponseMessage,那么仍然没有必要打扰JsonConvert.SerializeObject()自己:

return Request.CreateResponse<List<QDocumentRecord>>(HttpStatusCode.OK, listOfFiles);
Run Code Online (Sandbox Code Playgroud)

然后,您不需要控制器中的业务逻辑,因此您将其提取到一个为您工作的类中:

public class FileListGetter
{
    public IEnumerable<QDocumentRecord> GetAllRecords()
    {
        listOfFiles = ...
        return listOfFiles;
    }
}
Run Code Online (Sandbox Code Playgroud)

无论哪种方式,您都可以直接从MVC控制器调用此类或ApiController:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var listOfFiles = new DocumentsController().GetAllRecords();
        // OR
        var listOfFiles = new FileListGetter().GetAllRecords();

        return View(listOfFiles);
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,如果你真的,真的必须做一个HTTP请求,您可以使用HttpWebRequest,WebClient,HttpClientRestSharp,对于所有这些教程的大量存在.


kmc*_*mee 5

为什么不简单地将ApiController调用中的代码 - DocumentsController移动到可以从HomeController和DocumentController调用的类.将其拉出到您从两个控制器调用的类中.这个问题在你的问题中:

//找到文件的所有代码都在这里并且工作正常...

从同一网站上的另一个控制器调用API控制器是没有意义的.

这将简化代码,当你再回到它时,你将有一个共同的类来查找文件并在那里做那个逻辑......

  • “从同一网站上的另一个控制器调用 API 控制器没有意义”+1 (2认同)