【问题标题】:Use Web Api in a MVC Controller在 MVC 控制器中使用 Web Api
【发布时间】:2016-06-10 00:30:05
【问题描述】:

我必须创建一个将使用我的 Web 服务的 Web 服务和应用程序。

我创建了 Web Api 项目,我有这个方法:

namespace StudentListApi.Controllers
{
    //[Authorize]
    public class ValuesController : ApiController
    {
        StudentContext db = new StudentContext();
        // GET api/values
        public IEnumerable<Student> GetStudents()
        {
            return db.Students;
        }
        //...
    }
}

我需要在控制器中使用这个方法。我的 MVC 网站获取学生的数据。并考虑这些数据:

public class HomeController : Controller
{
    private const string APP_PATH = "http://localhost:2640";

    private Models.StudentListEntities db = new Models.StudentListEntities();

    public ActionResult Index()
    {

        //var students = db.Students.OrderByDescending(x => x.Id);
        using (var client = new HttpClient())
        {
            var students = client.GetAsync(APP_PATH + "/api/value").Result;
            //return students.StatusCode.ToString();
            return View(students);
        }

    }
}

但是它不起作用,我有一个错误:

错误是俄语,但我认为您可以从异常名称中理解,并且该类型的项目模型必须是 StudentList.Model.Student 但我有 HttpResponseMessage。

如何从 Web 服务中获取数据,将其转换为 "StudentList.Model.Student" 类型并将其提供给 View()

【问题讨论】:

  • Result 中有什么?它是 JSON 字符串、XML 吗?您的 API 返回什么?
  • 我是菜鸟,我不知道 API 返回什么,也不知道如何检查。

标签: c# asp.net-mvc asp.net-mvc-4


【解决方案1】:

您提到的网址是字符串。我认为您需要使用基于 URI 的地址。

此外,除了 GetAsync,您还需要使用 async 和 await 关键字。

试试下面的示例-

public class DataSourceController : Controller
{
    HttpClient _client;
    string webapiurl = "http://localhost:56472/api/DataSource";

    public DataSourceController()
    {
        _client = new HttpClient();
        _client.BaseAddress = new Uri(webapiurl);
        _client.DefaultRequestHeaders.Accept.Clear();
        _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 
    }


    //
    // GET: /DataSource/
    public async Task<ActionResult> Index()
    {
        var ResponseMessage = await _client.GetAsync(webapiurl);

        if(ResponseMessage.IsSuccessStatusCode)
        {

            var data = ResponseMessage.Content.ReadAsStringAsync().Result;

            var datasource = JsonConvert.DeserializeObject<List<DataSourceInfo>>(data);
            return View(datasource);

        }

        return View("Error");

    }
}

看看这是否有帮助。

【讨论】:

  • 查看更新的代码...希望您使用这 3 个命名空间 - 使用 Newtonsoft.Json;使用 System.Net.Http.Headers;使用 System.Threading.Tasks;
  • 它工作!非常感谢,但我编辑了一些代码,因为是错误workcode
【解决方案2】:

由于您正在进行网络服务调用,因此您需要反序列化来自调用的响应。
反序列化的种类将基于您在 Api 中配置的响应。

并且需要在Result.Content.ReadAsStringAsync()值上完成。

【讨论】:

  • 好的,我把它带到 View() ?以及如何在视图中使用它?例如,我现在有模型 IEnumerable foreach (var item in Model) { item.Name item.Surname
  • public ActionResult Index() { using (var client = new HttpClient()) { var content = client.GetAsync(APP_PATH + "/api/value").Result.Content; var students = JsonConvert.DeserializeObject>(content);返回视图(学生); } } 这里我假设内容是来自 Api 的 Json 格式。如果是 Xml 格式,则需要做 XML 反序列化。注意:您从 NewtonSoft Nuget 包中获得“JsonConvert”类型。
【解决方案3】:
using (var client = new HttpClient())
{
     var students = client.GetAsync(APP_PATH + "/api/value").Result;
     //return students.StatusCode.ToString();
     return View(students);
}

你的路径是这样的 (APP_PATH + "/api/value") 但你的控制器名称是 "ValuesController" 编辑你的 ValuesControllerValueController 或者像这样改变你的路径 (APP_PATH + "/api/values")

然后检查您的 api ("http://localhost:2640/api/values") 是否正常工作,而不是检查 HomeController 中的请求代码。

我在控制台应用程序中使用它并使用 Newtonsoft nuget 包

安装包 Newtonsoft.Json

using (var client = new HttpClient())
{
    client.BaseAddress = new Uri("yourRootUrl");
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    // New code:
    HttpResponseMessage response = await client.GetAsync("api/values");
    if (response.IsSuccessStatusCode)
    {

        var res = Task.Factory.StartNew(() => {
            var data = response.Content.ReadAsStringAsync();
            data.Wait();
            return  JsonConvert.DeserializeObject<List<Student>>(data.Result);
        });
        res.Wait();
        foreach (var s in res.Result)
        {
            Console.WriteLine(s.Name);
        }

    }
 }

【讨论】:

  • 是的,在浏览器中它工作正常,但在 HomeController 中它不起作用。在 Google Chrome 中我采用 xml 格式,在 Internet Explorer 中我采用 json 格式。现在我知道我必须使用反序列化,但它也不起作用。我有错误
  • 我使用和反序列化添加了示例 HttpClient。不要忘记添加 application/json client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
猜你喜欢
相关资源
最近更新 更多
热门标签