WEB API返回的字符串列表

2023-05-16

参考网址:https://www.cnblogs.com/yuanmo/p/10045467.html

开发工具:vs2015
语言:C# ASP.NET 5

第一次弄asp.net mvc,太难了,一堆问题

我的程序结构:web api->mvc5后台,即mvc5后台访问web api,获取到数据之后,显示到前端的页面上

web api接口代码如下:

public List<string> GetLocalDirs()
{
    List<string> retList = GetGoodDirs();
    if (retList.Count() == 0)
        retList.Add("-1:搜索目录失败");
    return retList;
}

这个接口返回的是一个字符串列表,如果没有搜索到目录,就一条数据:-1:搜索目录失败。在请求它的mvc5后台代码参考网上的内容,也很简单:

public ActionResult SearchDir()
{
    WebClient webClient = new WebClient();
    string remoteDirList = webClient.DownloadString(strRemoteUrl);
    DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(List<string>));
    MemoryStream ms = new MemoryStream(Encoding.Default.GetBytes(remoteDirList));
    List<string> listTmp = (List<string>)ser.ReadObject(ms);
    
    DirFindViewModel model = new DirFindViewModel();
    model.dirList = listTmp;
    return PartialView(model);
}

这个action是由js在页面后面请求。收到web api的返回内容后,反序列化为List<string>结构。通过调试发现,如果返回的字符串不带中文,即只有普通的英文符号(比如字母、数字等),就没有问题,如果有中文,就失败。后加了个try:

public ActionResult SearchDir()
{
    string remoteDirList = "";
    try
    {
        WebClient webClient = new WebClient();
        remoteDirList = webClient.DownloadString(strRemoteUrl);
        DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(List<string>));
        MemoryStream ms = new MemoryStream(Encoding.Default.GetBytes(remoteDirList));
        List<string> listTmp = (List<string>)ser.ReadObject(ms);
    
        DirFindViewModel model = new DirFindViewModel();
        model.dirList = listTmp;
        return PartialView(model);
    }
    catch(Exception e)
    {
        model.strDesc = e.Message;
        return PartialView(model);
    }
}

通过catch,发现是反序列化时失败,说什么格式不正确,同时发现 remoteDirList 的中文内容是乱码,这应该是编码的问题了,于是去网上找相关的说明,修改后的代码如下:

public ActionResult SearchDir()
{
    string remoteDirList = "";
    try
    {
        WebClient webClient = new WebClient();
        remoteDirList = webClient.DownloadString(strRemoteUrl);

        // 转换编码为unicode
        byte[] utf8Bytes = Encoding.Default.GetBytes(remoteDirList);
        byte[] defBytes = Encoding.Convert(Encoding.UTF8, Encoding.Default, utf8Bytes);
        remoteDirList = Encoding.Default.GetString(defBytes);


        DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(List<string>));
        MemoryStream ms = new MemoryStream(Encoding.Default.GetBytes(remoteDirList));
        List<string> listTmp = (List<string>)ser.ReadObject(ms);
    
        DirFindViewModel model = new DirFindViewModel();
        model.dirList = listTmp;
        return PartialView(model);
    }
    catch(Exception e)
    {
        model.strDesc = e.Message;
        return PartialView(model);
    }
}

再跟踪仍然失败,仔细看转换之后的字符串,发现前面的大部分是正常的,只有最后一个字会被转成??,即两个问号。反复捉摸,问了同事,参考网上的,既然web api返回List<string>在接收端是个字符串,那我直接改为返回字符串,修改后如下:

public string GetLocalDirs()
{
    List<string> retList = GetGoodDirs();
    if (retList.Count() == 0)
        retList.Add("-1:搜索目录失败");

    string retStr = Newtonsoft.Json.JsonConvert.SerializeObject(retList);
    return retStr;
}

改过之后,发现还是不行,原本正常的字符串,这次多出了转义符,比如修改之前返回的是:
["-1:搜索目录失??"],修改之后,返回的变成了:
"[\"-1:搜索目录失败\"]"
注意,这是实际的内容,如果是在调试模式下,在变量列表中显示的内容就是 “\"[\\\"-1:搜索目录失败\\\"]\"”,(两边的双引号是工具显示字符串的),这个就有点不可思议了,我在web api的接口中,把返回的retStr写入到文件中,查看它确实没错,并不存在黑底符。没办法,我就摒弃了库函数,直接自己实现,代码也很简单:

public string GetLocalDirs()
{
    List<string> retList = GetGoodDirs();
    if (retList.Count() == 0)
        retList.Add("-1:搜索目录失败");

    string retStr = "[";
    int txtIndex = 0;
    foreach(string itemText in retList)
    {
        if (txtIndex > 0)
            retStr += ",";
        retStr += "\"" + itemText + "\"";
        txtIndex++;
   }
   retStr += "]";

    return retStr;
}

这改过之后,仍然把返回的内容写入文件,查看和之前没啥区别,依然有转义符,没办法了,既然传输会带上转义符,那就在接收端把它去掉,修改代码如下:

public ActionResult SearchDir()
{
    string remoteDirList = "";
    try
    {
        WebClient webClient = new WebClient();
        remoteDirList = webClient.DownloadString(strRemoteUrl);

        // 转换编码为unicode
        byte[] utf8Bytes = Encoding.Default.GetBytes(remoteDirList);
        byte[] defBytes = Encoding.Convert(Encoding.UTF8, Encoding.Default, utf8Bytes);
        remoteDirList = Encoding.Default.GetString(defBytes);
        remoteDirList = remoteDirList.Replace("\\", "");        // 加了这三行
        remoteDirList = remoteDirList.Replace("\"[", "[");
        remoteDirList = remoteDirList.Replace("]\"", "]");

        DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(List<string>));
        MemoryStream ms = new MemoryStream(Encoding.Default.GetBytes(remoteDirList));
        List<string> listTmp = (List<string>)ser.ReadObject(ms);
    
        DirFindViewModel model = new DirFindViewModel();
        model.dirList = listTmp;
        return PartialView(model);
    }
    catch(Exception e)
    {
        model.strDesc = e.Message;
        return PartialView(model);
    }
}

再测试,转义符已经被成功清除掉了,现在还是有编码的问题,再仔细考虑,这个编码我点有混乱,在catch的提示信息中,有出现“utf8”的字样,那看来还是编码的问题导致的,对于http传输,不大可能丢失字节,就算丢,也不可能是每次都丢,并且丢的是中间的内容。再仔细查看编码的转换部分,把鼠标放在 Encoding.Default 的Default 上,提示是ANSI 代码页的编码,但是string提示又是unicode,加上catch提示中的utf8字样,难道是反序列化的编码不对?对它的编码进行修改,不再使用Default编码,修改后代码如下:

public ActionResult SearchDir()
{
    string remoteDirList = "";
    try
    {
        WebClient webClient = new WebClient();
        remoteDirList = webClient.DownloadString(strRemoteUrl);

        // 转换编码为unicode
        byte[] utf8Bytes = Encoding.Default.GetBytes(remoteDirList);
        byte[] defBytes = Encoding.Convert(Encoding.UTF8, Encoding.Default, utf8Bytes);
        remoteDirList = Encoding.Default.GetString(defBytes);
        remoteDirList = remoteDirList.Replace("\\", "");
        remoteDirList = remoteDirList.Replace("\"[", "[");
        remoteDirList = remoteDirList.Replace("]\"", "]");

        DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(List<string>));
        MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(remoteDirList));    // 改了编码
        List<string> listTmp = (List<string>)ser.ReadObject(ms);
    
        DirFindViewModel model = new DirFindViewModel();
        model.dirList = listTmp;
        return PartialView(model);
    }
    catch(Exception e)
    {
        model.strDesc = e.Message;
        return PartialView(model);
    }
}

注,这里只是修改了 MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(remoteDirList)); 一行中的编码,由Default改成了Unicode。然后再测试,一切ok,所有的中文也都能正常显示了,反序列化也不再被catch了。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WEB API返回的字符串列表 的相关文章

  • 如何以编程方式在 Google 文档中创建文档?

    The Google 文档列表 API 的文档 http code google com apis documents overview html 好像说可以创建本地文档并上传 有没有办法实际创建和编辑文档on通过 API 的 Google
  • Electron 应用程序可以与 java 代码集成吗?

    由于node js仍然缺乏Java中存在的重要功能 因此我想使用Java而不是node js 并使用Web语言 html js css 创建客户端 Electron 是跨平台的 java 也是跨平台的 因此似乎有一个能够两全其美的解决方案
  • 保护客户端 API 的安全

    我正在为基于 JavaScript 的游戏构建服务器端 API 和客户端库 其中必须确保两个非常重要的功能的安全 用户每次游玩都必须扣款 我们必须确保提交的分数是玩家实际获得的分数 解决第一个问题看起来很简单 在每次游戏开始时 我们都会调用
  • 通过 MailChimp 发送电子邮件

    我认为问题出在附近 api gt listSubscribers include libs mailchimp MCAPI class php options array list id gt list id subject gt Prov
  • 创建默认应用程序时 FirebaseOptions 不能为 null

    我正在尝试在 Flutter 集成电子邮件和基于 google 的登录中尝试一个示例项目 并计划使用 firebase 初始化来执行此操作 同时我已按照教程中提到的所有步骤进行操作 一旦尝试使用 firebase 我就会收到此错误已初始化
  • 在 html 中创建子页面 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 假设我有一个网站http www example com http www example com 如何为此页面创建更多子页面 即 w
  • 如何将 YouTube API 集成到我的 iPhone 应用程序中?

    我想将 YouTube API 集成到我的应用程序中 我该怎么做 附注 我正在为 YouTube 频道制作一个应用程序 我尝试以webview 但这让一切变得更糟 因为用户可以看到 YouTube 控件 搜索等 以及有关 YouTube i
  • 我们可以使用 axios 的 onDownloadProgress 来加载 API 吗?

    我需要使用 axios 创建一个用于在 React 项目中加载 API 的进度条 我为此发现了 onDownloadProgress 函数 但我不知道我们是否可以使用它来获取诸如加载百分比之类的信息 或者它是否仅用于文件下载 所以我不确定我
  • Android 添加新日历

    我已经检查了所有从 Android 应用程序中创建新日历的方法 我见过的唯一方法是在最新的 api 版本中使用新的 Calendar API 但这似乎只有在您使用时才有效CalendarContract ACCOUNT TYPE LOCAL
  • 用于分享帖子的 Yammers REST API

    我想使用 REST API 从我的业务应用程序共享帖子 不是发布新消息 而是共享现有帖子 有谁知道要使用哪个端点以及如何实现它 当您使用 Yammer API 创建新帖子时 请将参数 shared message id 与要共享的消息的 m
  • useState 由于某种原因没有更新?

    当我尝试使用 axios 从后端 API 获取一些数据 并在由于某种原因获得结果后设置状态时 状态不会更新 当我尝试使用状态时 它只会向我显示一个空数组 但有趣的是当我console log res data 它会毫无问题地向我显示我的列表
  • 从我自己的博客获取帖子[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 是否有任何 API 通过它我可以从 wordpress com 上我自己的博客获取帖子并将它们放在我的
  • 对同一域发出 get 请求,出现 CORS 错误

    在浏览器扩展中 这是我的 ajax 调用 var xhr new XMLHttpRequest xhr open GET window location href true xhr responseType arraybuffer xhr
  • PayPal Rest API for Payments 在沙箱中返回 NULL

    我有一个 PayPal 沙盒帐户 我可以在 PHP 上使用curl 通过 api 检索令牌 但是处理测试卡只会返回 null 有人看到代码有问题吗 这是 PayPal 沙盒的已知问题吗 下面代码片段中的客户端是伪造的 但是 如前所述 使用我
  • asp.NET 2.0网站无法访问App_Code中的类

    将我的网站部署到服务器后 我在访问课程时遇到问题 请注意 这是一个网络Site不是网络应用 错误是 编译器错误消息 CS0246 找不到类型或命名空间名称 Order 是否缺少 using 指令或程序集引用 版本信息 Microsoft N
  • 如何使用php api检查电子邮件或手机paypal帐户状态?

    如何使用 php api 检查电子邮件或手机 Paypal 帐户状态 好的 如果我想汇款到此电子邮件贝宝 email protected cdn cgi l email protection 或手机 1234567890 汇款前 我可以检查
  • 如何在 Google Maps API 中指示语言?

    就像你访问一样maps google com tw or maps google co kr or maps google co jp 您可以看到每个国家 地区都显示自己的语言 我可以在 Google 地图 API 中使用任何属性来动态设置
  • API Gateway POST 方法在测试期间工作,但不适用于邮递员

    我会尽力清楚地解释我的问题 我有一个 API 它使用 Node js 编写的 lambda 函数在 DynamoDB 中编写一些内容 当我在 AWS 控制台中调用它时 API 按预期工作 我发送这样的正文 user id 4dz545zd
  • 在 Tomcat 上部署 Java Web 项目,无需 WAR 或 EAR

    我有一个 Java Web 项目 Struts Spring 在我的本地主机上完美运行 我必须将其部署在我的网站上 但虚拟主机提供的 Tomcat Manager 界面显示 由于安全原因 它无法上传 WAR 文件 当联系技术支持时 我被告知
  • 使用“邮递员”chrome 应用程序的肥皂请求正文

    假日网络服务 的肥皂请求正文会是什么样子 http www holidaywebservice com HolidayService v2 HolidayService2 asmx wsdl http www holidaywebservi

随机推荐