VS调试异常问题解决(二)
一、启动调试出现 无法启动程序 当前状态中是非法
VS工具--选项--调试--常规--启用asp.net的JavaScript调试(chrome和ie)去掉勾选
二、web.config中<customErrors>报错
<customErrors>节点用于定义一些自定义错误信息的信息。
此节点有Mode和defaultRedirect两个属性,其中
defaultRedirect属性是一个可选属性,表示应用程序发生错误时重定向到的默认URL,如果没有指定该属性则显示一般性错误;
Mode属性是一个必选属性,它有三个可能值,它们所代表的意义分别如下:
Mode 说明
On 表示在本地和远程用户都会看到自定义错误信息。
Off 禁用自定义错误信息,本地和远程用户都会看到详细的错误信息。
RemoteOnly 表示本地用户将看到详细错误信息,而远程用户将会看到自定义错误信息。
这里有必要说明一下本地用户和远程用户的概念。当我们访问asp.net应用程时所使用的机器和发布asp.net应用程序所使用的机器为同一台机器时成为本地用户,反之则称之为远程用户。
在开发调试阶段为了便于查找错误Mode属性建议设置为Off,而在部署阶段应将Mode属性设置为On或者RemoteOnly,以避免这些详细的错误信息暴露了程序代码细节从而引来黑客的入侵。
所以想看具体的错误,有两种方式:将mode设置为Off,或者直接在服务器上复现刚才发生错误的操作,看详细的错误信息。
参考:关于web.config中<customErrors>节点说明
三、WCF报错
1、WCF运行不起来
System.ServiceModel.EndpointNotFoundException:“没有终结点在侦听可以接受消息的
"ExceptionMessage": "没有终结点在侦听可以接受消息的 http://localhost.dev.xxx.com/Services/yyyService.svc。这通常是由于不正确的地址或者 SOAP 操作导致的。如果存在此情况,请参见 InnerException 以了解详细信息。","ExceptionType": "System.ServiceModel.EndpointNotFoundException",
可能是 wcf服务没启动?
从IIS_Express中打开wcf站点,看是否有报错,
可能错误:未能加载配置文件;web.Config中wcf路径配置有误
路径错误,看是否需要修改.vs\config\applicationhost.config 中的虚拟路径 <virtualDirectory path="/Service" physicalPath="D:\sources.git\xxx\yyy" />
配置文件拷贝后,WCF运行起来。
2、调试不进断点
调试选项里面的 “仅我的代码”,取消选中
3、无法自动进入并单步执行服务器。调试器未能在服务器进程中停止
以上设置都配置好后,清理解决方案,重新生成。
4、域名绑定问题
可以看到,restapi请求WCF时 没有成功。
在本地看到wcf是ok的。但是在restapi所在的服务器上请求wcf是不行的。于是看服务器上的host,发现没有绑定 wcf域名对应的ip。
四、DBContext报类型初始值设定项引发异常
查看配置文件,configSource节点
<appSettings configSource="VConfigs\Dev\appSettings.config">
<add key="ClientSettingsProvider.ServiceUri" value=""/>
</appSettings>
手动改为
<appSettings configSource="VConfigs\Dev\appSettings.config"/>
参考:http://www.it1352.com/21840.html
五、 Missing type map configuration or unsupported mapping
Missing type map configuration or unsupported mapping. Mapping types: Discount -> DiscountEntity Ferry.Data.Models.Discount ->Entity.DiscountEntity Destination path: List`1[0] Source value: Data.Models.Discount,錯誤源:
参考:http://www.cnblogs.com/dudu/p/5875579.html
从 GitHub 上签出 AutoMapper 的源代码一看 Mapper.Initialize() 的实现,恍然大悟。
public static void Initialize(Action<IMapperConfigurationExpression> config)
{
Configuration = new MapperConfiguration(config);
Instance = new Mapper(Configuration);
}
原来每次调用 Mapper.Initialize() 都会创建新的 Mapper 实例,也就是多次调用 Mapper.Initialize() 只有最后一次生效。
更多参考:【.NET】AutoMapper学习记录
六、the current .NET SDK does not support targeting .NET Standard 2.0. Either target .NET Standard 1.6 or lower, or use a version of the .NET SDK that supports .NET Standard 2.0
通过这句英文一直以为是 .net framework 2.0未安装。
安装以后引用不报错(没有黄色感叹号),编译的时候却还是报错。
找到原因,原文地址
安装 .net core 2.0可以解决。
vs重启后,出错的项目 属性。重新选择目标平台。
七、模板生成pdf时内容不够却分页了
可能的原因是:底部某些 标签(eg table)的元素太多导致,可以将太多元素标签的标签改造下。
八、初始化异常或内存不足
System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
日志记录的详细信息:
System.TypeInitializationException: The type initializer for 'Ferry.Data.Models.FerryDBContext' threw an exception.
---> System.TypeInitializationException: The type initializer for 'System.Data.Entity.Utilities.TypeExtensions' threw an exception.
---> System.TypeInitializationException: The type initializer for 'System.Data.Entity.Core.Metadata.Edm.MetadataItem' threw an exception.
---> System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
咋一看是数据库(或者EF连接)初始化的问题。
若期间没有动过服务器或者DB,,则大致可以认为是服务器问题,可以重启服务,只重启出问题的应用程序池。
九、https网站中样式资源没起作用
F12 看到js报错:Mixed Content: The page at 'https://xxx.com//app/#booking/search'
was loaded over HTTPS, but requested an insecure stylesheet 'http://xxx.com/Site/Styles/offline/main.css'.
This request has been blocked; the content must be served over HTTPS.
http://xxx.com/Site/Styles/offline/main.css这个资源(位于index.html中的<head>标签中)被阻塞了,
原因:在https网站中,载入http网站的资源(网页、图片等),会被浏览器阻拦。HTTPS 是 HTTP over Secure Socket Layer,以安全为目标的 HTTP 通道,在 HTTPS 承载的页面上不允许出现 http 请求。
正确应该是https://xxxx.com/Site/Styles/offline/main.css
十、未能加载文件或程序集
打开WCF时:未能加载文件或程序集“MongoDB.Bson, Version=2.2.3.3, Culture=neutral, PublicKeyToken=null”或它的某一个依赖项。系统找不到指定的文件。
找到相应的目录:D:\sources.git\xxx\DEV\yyy.Offline.Service.Site\bin
看它里面是否有MongoDB.Bson程序集,没有的话copy一份进去。
十一、分析器错误信息: 未能加载类型“xxxx.Global”
解决方法: 删除此项目下bin里面的所有dll,清理 重新生成。
十二、VS中修改代码,再断点调试,发现命中的还是修改前的代码
解决方法: 清理解决方案,再重新生成。
十三、LINQ to Entities 不识别方法“System.DateTime ToDateTime(System.String)”,因此该方法无法转换为存储表达式
因为LINQ语句最后都是要转为sql语句来执行的,当它转换后,发现sql语句中要执行的方法“XX”,并不是一个在数据库中的存储过程函数,也无法进行转换为存储表达式。
即EF不支持复杂类型(如实体)的直接检索,只能用简单类型(string、int、guid等)
类似异常:LINQ to Entity 不识别方法“System.String ToString()”,因此该方法无法转换为存储表达式
最近在项目中遇到需求说,要模糊查询。于是有
var query = store.Repository.Set<EFHotelOrder>().Where(p => p.OrderType == (byte)OrderType.Expert); if (request != null) { if (request.OrderID != null) { query = query.Where(i => i.OrderID.ToString().Contains(request.OrderID.ToString())); } if (request.CityName != null) { query = query.Where(i => i.CityName.Contains(request.CityName)); }
由于orderId被设计为了int型,故用了toString()。所以报了上面的错误。
参考:LINQ to Entities 不识别方法“System.String ToXX()”,因此该方法无法转换为存储表达式
LINQ to Entity 不识别方法“System.String ToString()”,因此该方法无法转换为存储表达式
而此处遇到的是int型的模糊匹配问题,不适用,后来在网上发现:EF中 int没有模糊查询的概念;一般模糊查询都是针对字符串。
十四、你的xxx.mdf 的版本为 782,无法打开,此服务器支持 655 版及更低版本,不支持降级路径
现象:在vs2015中直接添加数据库和表,
查找资料:782是sql server 2014的内部版本号(是vs2015自带的)、655是sql server2008(本机安装的数据库版本)
原因:你的mdf数据库文件是12.00.2000版本,而你的SQLEXPRESS却是2008
(SQL Server Express 是由Microsoft所开发的SQL Server的其中一个版本,SQL Server Express 有 2005 、 2008 与 2008 R2 、2012 R0和最新的 2014五个版本)
查看数据库的版本,SSMS版本
你调用的数据库文件版本太高,当前的数据库不支持,你只能将调用的数据库版本降低
解决:在本机只安装了sql server2008的情况下,数据库也要用管理工具创建的数据库,不能用vs2015上直接创建的。
十五、基础连接已经关闭: 未能为 SSL/TLS 安全通道建立信任关系
当我们有时用代码编写post/Get请求url远程地址会报“基础连接已经关闭: 未能为 SSL/TLS 安全通道建立信任关系。 ---> System.Security.Authentication.AuthenticationException: 根据验证过程,远程证书无效。
”这个异常,是因为远程url使用的域名 没有购买证书,所以用以下方式来解决:
在create url之前 设定“获取或设置用于验证服务器证书的回调”永远为true 即可,具体如下
请求一定需要:
ServicePointManager.ServerCertificateValidationCallback += RemoteCertificateValidate; System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(url); private static bool RemoteCertificateValidate(object sender, X509Certificate cert,X509Chain chain, SslPolicyErrors error) { //为了通过证书验证,总是返回true return true; }
或者
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Ssl3; ServicePointManager.ServerCertificateValidationCallback += (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) => true;
十六、Unable to cast object of type 'Newtonsoft.Json.Linq.JArray' to type 'System.Collections.Generic.List
无法将Newtonsoft.Json.Linq.JArray隐式转换为List<T>
现在webapi一般使用json,
eg: data (Array[CollectionListItemExtend], optional): 返回data。。类型为JArry,那直接用List<>去接收,就会报上面的错误。
在后台接口获取参数时,我们可以使用dynamic,如:
dynamic jArray = HttpHelper<string, RestAPIGetAccount<object>>.GetDataBy=API(url).Result; //JArray jArray = new JArray(); //jArray.ToObject() if (jArray != null && jArray.head != null && jArray.head.code == 0) { List<AccAPI.CollectionListItemExtend> temp = jArray.data.ToObject(typeof(List<AccAPI.CollectionListItem>)); if (temp != null && temp.Count > 0) { string str = temp.ToJSON(); System.Console.ReadLine(); } } public static async Task<RestAPIGetAccount<object>> GetDataBy(string url) { ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Ssl3; ServicePointManager.ServerCertificateValidationCallback += (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) => true; var rs = new RestAPIGetAccount<object>() { head = new Entity.API.OfflineResponseHeader() }; using (HttpClient client = GetHttpClient(url, 100)) { try { var httpResponseMessage = client.GetAsync(url).Result; if (!httpResponseMessage.IsSuccessStatusCode) { var xmlResult = httpResponseMessage.Content.ReadAsStringAsync().Result; rs.head.code = 500; rs.head.message = "http请求失败"; } else { var result = httpResponseMessage.Content.ReadAsStringAsync().Result; if (!string.IsNullOrWhiteSpace(result)) { rs = result.FromJSON<RestAPIGetAccount<object>>(); } } } catch (AggregateException ae) { var exceptions = ae.InnerExceptions.ToList(); rs.head.message = string.Join(",", exceptions.Select(p => p.ToString()).ToArray()); rs.head.code = 500; HotelHelper.WriteErrorLog(LogSourceType.Common, $"Get数据", $"url:{url}{Environment.NewLine}rs:{rs.ToJSON()}{Environment.NewLine}message:{ae.ToString()}"); } catch (Exception ex) { rs.head.message = ex.ToString(); rs.head.code = 500; HotelHelper.WriteErrorLog(LogSourceType.Common, $"Get数据", $"url:{url}{Environment.NewLine}rs:{rs.ToJSON()}{Environment.NewLine}message:{ex.ToString()}"); } } return rs; } public class RestAPIGetAccount<T> { /// <summary> /// 返回data /// </summary> public T data { get; set; } /// <summary> /// /// </summary> public OfflineResponseHeader head { get; set; } } public class OfflineResponseHeader { /// <summary> /// 0-success, (客户端错误400-499) 401未登录, 403没访问权限, (异常500-599) 500-error, /// </summary> public int code { get; set; } /// <summary> /// 錯誤信息 /// </summary> public string message { get; set; } }
其实是 Newtonsoft.Json.Linq.JArry.ToObject()
更多参考:Newtonsoft.Json.Linq.JArray转换为List Convert JSON to a Type
十七、CS0656 C# 缺少编译器要求的成员“Microsoft.CSharp.RuntimeBinder.Binder.Convert”
在使用 dynamic 时生成失败,遇到这样一个错。
解决方法:在项目中添加对 "Micorsoft.CSharp.dll" 的引用
十八、 SqlDateTime 溢出,必须介于 1/1/1753 12:00:00 AM 和 12/31/9999 11:59:59 PM之间
原因:.NET中 DateTime最小值为: 0001-1-1 0:00:00
数据库中DateTime最小值为: 1753-1-1 0:00:00,
很明显:.NET中的最小值超出了数据库时间类型的最小值,导致数据溢出的错误。(两者的最大值都是一样滴)
出现这种问题多半是因为插入或者更新数据库时,datetime字段值为空默认插入0001年01月01日造成datetime类型溢出。
传给数据库表的时间类型值是null值。这里的null指的是程序代码中的null,多数出现这种情况的场景是:在程序里面定义了一个时间类型的变量,没有给赋值,就传给数据库,这时这个变量的值默认是赋成了01年01月01日;由于数据库中DateTime类型字段,最小值是1/1/1753 12:00:00,而.NET Framework中,DateTime类型,最小值是1/1/0001 0:00:00,显然,超出了sql的值的最小值范围,导致数据溢出错误。
解决方法:
方法1、使用System.Data.SqlTypes.SqlDateTime.MinValue替代System.DateTime类型,这样SqlDateTime的MinValue和Sql中DateTime的范围吻合,就不会再出现以上的错误了。
方法2、DateTime为空或最小时,给其赋一个SqlDateTime最小值或者特定值
if (modelberthStatus.TIMEIN == null || modelberthStatus.TIMEIN == DateTime.MinValue) { modelberthStatus.TIMEIN = SqlDateTime.MinValue.Value; } //或者: modelberthStatus.TIMEIN = new DateTime(1900,1,1);
十九、证书验证失败
{System.Net.WebException: Error: TrustFailure (Authentication failed, see inner exception.) ---> System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception.
---> Mono.Btls.MonoBtlsException: Ssl error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED
代码:
ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(CheckValidationResult); private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) { if (CheckIsKMURL(httpWebrequest.Address.AbsoluteUri, ref kmCert) && !IsLogin) { if (kmCert == null) return false; return kmCert.GetCertHashString() == certificate.GetCertHashString(); } }
调式发现:kmCert.GetCertHashString() == certificate.GetCertHashString(); 为false
出现的原因:是客户端在请求https的时候,返回的服务器证书certificate 与 我们本地预先硬编码的服务器证书不匹配。【即我想请求服务器1的接口,本地写了服务器1的证书,但是接口返回中的证书 不是服务器1的证书】
有可能是服务器替换证书了,而代码没改,重点排查下证书是否一致。
二十:某个类同时存在于类库1和类库2中
应用程序中引用的两个不同的程序集包含相同的命名空间和类型,这会产生歧义。
若要解决此错误,请使用(References)编译器选项的别名功能,或者不要引用某个程序集。
eg:引用B.dll后,右键引用中的B.dll属性->别名->Test。
但是我遇到的时候 只是手动引用了类库1,类库2是在默认的C盘Nuget位置(C:\\Users\\xx\\.nuget\\packages),此时通过改别名可能不能解决问题,那么需要考虑怎么去除Nuget的那个引用。
找到:obj/project.assets.json
查看里面的包引用,可能是其他的包间接引用了你这个类库,那需要调整包的引用。