天道酬勤,学无止境

部署asp.net核心应用程序时如何处理环境差异?(How to deal with environment differences when deploying asp.net core application?)

问题

部署ASP.NET Core应用程序时是否可以更改环境设置(例如使用调试/发布版本的配置文件转换)?

在.NET Core应用程序中维护多个环境设置的最佳方法是什么(类似于<appSettings file="local.config">用于本地,暂存和生产)?

回答1

中央配置文件是appsettings.json ,您可以有多个文件,例如appsettings.Production.json等,这些文件将被加载并覆盖来自appsettings.json设置。

例如

        // Set up configuration sources.
        var builder = new ConfigurationBuilder()
            .SetBasePath(hostEnv.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
            .AddJsonFile($"appsettings.{hostEnv.EnvironmentName}.json", optional: true, reloadOnChange: true)
            .AddEnvironmentVariables();

您需要做的就是设置环境类型的环境变量(请参阅此处的文档)。

如果将AddEnvironmentVariables()添加到配置构建器,则还可以具有覆盖的环境变量。 因此,如果您有一个appsettings.json

{
    "Data"  {
         "Default" {
              "ConnectionString" : "..."
         }
    }
}

并想通过环境变量覆盖它,您将设置一个名为“ Data:Default:ConnectionString”的环境变量,其值将覆盖appsettings.config和appsettings.Production.config中的设置(假设您的.AddEnvironmentalVariables().AddJsonFile()之后被调用-使用匹配键的最后一次注册获胜)并带有环境变量中的值。

您可以在此处的官方文档中找到更多信息。

更新

由于在评论中有人将其理解为设置环境的唯一方法,因此设置环境变量的方法有很多(大多数方法在“使用ASP.NET Core中的多个环境”中有记录),最终所有方法最终都变成了环境变量。 ,但范围不同:

  1. 环境变量(在全局上,Windows cmd.exe set ASPNETCORE_ENVIRONMENT=Development$Env:ASPNETCORE_ENVIRONMENT = "Development"$Env:ASPNETCORE_ENVIRONMENT = "Development"export ASPNETCORE_ENVIRONMENT = Developmentexport ASPNETCORE_ENVIRONMENT = Development
  2. 每个命令环境变量(即linux: ASPNETCORE_ENVIRONMENT=Production dotnet MyApp.dll
  3. Docker容器,即通过docker-compose.yaml

     web: environment: - ASPNETCORE_ENVIRONMENT=Debugging
  4. 通过命令行docker run -e ASPNETCORE_ENVIRONMENT=Debugging Docker容器
  5. 在IIS中通过web.config。

     <aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" forwardWindowsAuthToken="false" stdoutLogEnabled="true" > <environmentVariables> <environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Development" /> </environmentVariables> </aspNetCore>
  6. 在IIS上,按AppPool设置(请参见此处)
  7. 在Linux上,通过服务定义文件(请参阅文档)
  8. 可以通过环境变量设置Azure应用服务,可以为每个插槽设置,并具有不同的插槽用于暂存,开发,生产,即部署到暂存,预热和与生产交换
  9. 通过dotnet run --launch-profile Development每次执行dotnet run --launch-profile Development

它们都在特定范围内(全局,容器本地,应用程序池内部,每次执行等)更改/设置环境变量。 选择一种适合您的需求。

回答2

使用其他appsettings.*.json文件是一个不错的方法。 *片段可用于混合任何可区分机器,用户或部署方案的独特环境属性。

但是,我建议您使用另一种方法,而不是使用new ConfigurationBuilder()从头开始构建配置对象(如Web上的许多资源所示)。 以下代码不会替换您现有的配置,而是添加到它:

    public IHostingEnvironment _environment { get; }
    public IConfiguration _configuration { get; }

    public Startup(IConfiguration configuration, IHostingEnvironment environment)
    {
        _environment = environment;

        // use the default config and add config from appsettings.COMPUTERNAME.json (if it exists)
        var builder = new ConfigurationBuilder()
            .SetBasePath(environment.ContentRootPath)
            .AddConfiguration(configuration)
            .AddJsonFile($"appsettings.{System.Environment.GetEnvironmentVariable("COMPUTERNAME")}.json", optional: true);
        _configuration = builder.Build();

    }

背景:

当您基于新的dotnet模板创建项目时,您的项目已经带有一个有用的配置,该配置可通过CreateDefaultBuilder()方法自动构建。 此默认配置结合了来自多个来源的信息:appsettings.json,appsettings。{Environment} .json,Secret Manager,环境变量和命令行参数。

如果您自己完全重建配置,则将失去所有魔力。

暗示:

在上面的示例中, appsettings.COMPUTERNAME.json只是一个示例。 您可以从_environmentSystem.Environment中的任何数据中组成自己的json文件名,从而清楚地区分不同的开发和部署方案。

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 调试时如何处理ClassNotLoadedException?(How do I deal with a ClassNotLoadedException while debugging?)
    问题 因此,我(远程)在Eclipse中调试Java / jboss应用程序,一步一步地进行操作。 一方面,通过方法调用创建了一个GridSquare对象数组( GridSquare是一个相当简单的独立类,包含一些属性和方法),即: GridSquare[] squares = this.theGrid.getSquares(14, 18, 220, 222); ...当我实际执行代码时, squares数组的确填充了GridSquare对象,而在单步执行代码并进行调试时,我感到有些奇怪。 在紧接上面显示的赋值的那一行的断点处,如果我尝试查看squares数组,而不是一个值,我会得到以下信息: org.eclipse.debug.core.DebugException: com.sun.jdi.ClassNotLoadedException: Type has not been loaded occurred while retrieving component type of array. ...谁知道这是怎么回事? 回答1 基本上,这意味着类加载器尚未加载GridSquare []类。 话虽如此,这听起来像是调试器中的一个错误。 断点与代码的关联似乎已被破坏。 您需要重新编译以使行号同步,或者发生其他问题。 此时(在分配之后)在代码中需要加载它。
  • 使用WebClient.DownloadFileAsync时如何处理异常(How to deal with exceptions when using WebClient.DownloadFileAsync)
    问题 我正在以下列方式使用WebClient从Internet下载一些文件: try { ManualResetEvent mr = new ManualResetEvent(false); mr.Reset(); using (WebClient wc = new WebClient()) { wc.DownloadFileCompleted += ((sender, args) => { if (args.Error == null) { File.Move(filePath, Path.ChangeExtension(filePath, ".jpg")); mr.Set(); } else { //how to pass args.Error? } }); wc.DownloadFileAsync(new Uri(string.Format("{0}/{1}", Settings1.Default.WebPhotosLocation, Path.GetFileName(f.FullName))), filePath); mr.WaitOne(); } } catch (Exception ex) { //Catch my error here and handle it (display message box) }
  • 当使用Android 4.x运行异步任务时如何处理屏幕方向变化(How to handle screen orientation changes when there is an asyntask running with android 4.x)
    问题 我尝试实现以下代码来处理屏幕方向更改。 ****DataBaseUpdateService.java**** public class DataBaseUpdateService extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Updatetask Task = new Updatetask(this.getApplicationContext()); if(Task.getStatus() == AsyncTask.Status.PENDING){ Task.execute();}; } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); } @Override public void onPause() { super.onPause(); } @Override public void onResume() { super.onResume(); } } =================================
  • 当我想继承和添加属性时如何处理密封的类(How to deal with a sealed class when I wanted to inherit and add properties)
    问题 在有关堆栈溢出的最新问题中,我询问如何将文件名解析为有关文件的其他元信息。 解决完该问题后,我决定可能要创建一种新类型的对象来保存元数据和原始文件。 我以为我可以做这样的事情: class BackupFileInfo : FileInfo, IEquatable<BackupFileInfo> { //Properties and Methods here } 这样的想法是,我将保留原始FileInfo对象,同时在实现FileInfo的对象的属性(例如IsMainBackup添加元信息。 但是, FileInfo是密封的,这意味着其他类不能从其继承。 相反,我最终得到以下结果: class BackupFileInfo : IEquatable<BackupFileInfo> { public bool IsMainBackup { get; set; } public int ImageNumber { get; set; } public int IncrementNumber { get; set; } public FileInfo FileInfo { get; set; } //public BackupFileInfo() //constructor here public bool Equals(BackupFileInfo other) { return
  • 在GPU上训练时如何处理不确定性?(How to handle non-determinism when training on a GPU?)
    问题 在调整超参数以使模型更好地运行时,我注意到尽管为随机操作固定了所有种子,但每次运行代码时得到的分数(以及因此创建的模型)都不相同。 如果我在CPU上运行,则不会发生此问题。 我在Google上搜索后发现,这是使用GPU进行训练时的常见问题。 这是一个很好/详细的示例,其中包含简短的代码片段,以验证该问题的存在。 他们指出了“ tf.reduce_sum”函数的不确定性。 但是,对我而言并非如此。 可能是因为我使用了不同的硬件(1080 TI)或不同版本的CUDA库或Tensorflow。 似乎CUDA库中有许多不同的部分是不确定的,要弄清楚到底是哪一部分以及如何摆脱它似乎并不容易。 另外,这必须是设计使然,因此很有可能会充分提高效率,以换取非确定性。 所以,我的问题是: 由于GPU在训练NN方面很受欢迎,因此该领域的人们必须有一种处理不确定性的方法,因为我看不到您还能如何可靠地调整超参数。 使用GPU时处理不确定性的标准方法是什么? 回答1 TL; DR 先验确定性操作的非确定性来自并发(多线程)实现。 尽管在这方面不断取得进展,但TensorFlow当前不能保证其所有操作都具有确定性。 在互联网上快速搜索后,情况似乎与其他主要工具包相似。 在训练期间,除非您要调试问题,否则两次跑步之间可以有波动。 不确定性在于培训的本质,明智的做法是测量它,并在比较结果时将其考虑在内
  • 使用docker-compose将docker容器彼此链接时如何处理IP地址?(How to handle IP addresses when linking docker containers with each other using docker-compose?)
    问题 我正在使用docker-compose构建完整的开发堆栈。 该应用程序需要一个mysql服务器才能工作。 mysql服务器是由docker-compose设置的外部容器: mysql: image: mysql:5.6 volumes: - /data/mysql:/var/lib/mysql - ./docker/mysql.d:/etc/mysql/conf.d ports: - "3306:3306" environment: MYSQL_ROOT_PASSWORD: password 该应用程序具有自己的docker-compose.yml并引用了mysql容器: my-application: build: . # the Dockerfile resides in the current folder ports: - "9180:80" - "9543:443" external_links: - mysql_mysql_1:mysql environment: DOCKER_ENVIRONMENT: dev DB_NAME: local_db DB_PASS: password DB_USER: root DB_HOST: # how to set the mysql's IP address? 我无法在docker-compose中传递它们,因为它是动态的。
  • 使用ObserveOn时如何处理OnNext中的异常?(How to handle exceptions in OnNext when using ObserveOn?)
    问题 当我使用ObserveOn(Scheduler.ThreadPool)时,当观察者在OnNext引发错误时,我的应用程序终止。 我发现处理此问题的唯一方法是使用下面的自定义扩展方法(除了确保OnNext永远不会引发异常)。 然后确保每个ObserveOn都跟随一个ExceptionToError 。 public static IObservable<T> ExceptionToError<T>(this IObservable<T> source) { var sub = new Subject<T>(); source.Subscribe(i => { try { sub.OnNext(i); } catch (Exception err) { sub.OnError(err); } } , e => sub.OnError(e), () => sub.OnCompleted()); return sub; } 但是,这感觉不对。 有没有更好的方法来解决这个问题? 例子 由于未捕获的异常,该程序崩溃。 class Program { static void Main(string[] args) { try { var xs = new Subject<int>(); xs.ObserveOn(Scheduler.ThreadPool).Subscribe(x => {
  • 如何处理Java中的LinkageErrors?(How to deal with LinkageErrors in Java?)
    问题 在开发一个高度基于XML的Java应用程序时,我最近在Ubuntu Linux上遇到了一个有趣的问题。 我的应用程序使用Java Plugin Framework,似乎无法将dom4j创建的XML文档转换为Batik的SVG规范实现。 在控制台上,我了解到发生了错误: Exception in thread "AWT-EventQueue-0" java.lang.LinkageError: loader constraint violation in interface itable initialization: when resolving method "org.apache.batik.dom.svg.SVGOMDocument.createAttribute(Ljava/lang/String;)Lorg/w3c/dom/Attr;" the class loader (instance of org/java/plugin/standard/StandardPluginClassLoader) of the current class, org/apache/batik/dom/svg/SVGOMDocument, and the class loader (instance of <bootloader>) for interface org/w3c/dom
  • 重写“漂亮的网址”时如何处理变音符号(重音符号)(How to handle diacritics (accents) when rewriting 'pretty URLs')
    问题 我重写了URL,以包括用户生成的travelblogs的标题。 我这样做是出于URL的可读性和SEO的目的。 http://www.example.com/gallery/280-Gorges_du_Todra/ 第一个整数是id,其余的对我们来说是人类(但与请求资源无关)。 现在,人们可以编写包含任何UTF-8字符的标题,但是URL中不允许使用大多数字符。 我的听众通常是说英语的,但是自从他们旅行以来,他们喜欢添加诸如 Aït Ben Haddou 在Linux上使用PHP进行翻译以显示在URL中的正确方法是什么? 到目前为止,我已经看到了几种解决方案: 只需去除所有不允许的字符,替换空格会产生奇怪的结果: 'Aït Ben Haddou' → /gallery/280-At_Ben_Haddou/ 没有真正的帮助。 只需删除所有不允许的字符,替换空格,最有可能由于使用“ regex-hammer”而保留字符代码(stackoverflow.com) 这给出了奇怪的结果: 'tést tést' → /questions/0000/t233st-t233st 转换为“最近等效” 'Aït Ben Haddou' → /gallery/280-Ait_Ben_Haddou/ 但这对于德国人来说是错误的。 例如,“ü”应音译为“ ue”。 对我来说,作为荷兰人,第三名看起来
  • 打印大型HTML表格时如何处理分页符(How to deal with page breaks when printing a large HTML table)
    问题 我有一个项目,要求打印带有许多行的HTML表格。 我的问题是表格在多页上的打印方式。 有时它将切成两行,使其变得不可读,因为一半在页面的前沿,而其余部分则打印在下一页的顶部。 我能想到的唯一可行的解​​决方案是使用堆叠的DIV而不是表格,并在需要时强制分页。 回答1 <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Test</title> <style type="text/css"> table { page-break-inside:auto } tr { page-break-inside:avoid; page-break-after:auto } thead { display:table-header-group } tfoot { display:table-footer-group } </style> </head> <body> <table> <thead> <tr><th>heading</th></tr> </thead> <tfoot> <tr><td>notes</td></tr> </tfoot> <tbody> <tr> <td>x</td> </tr> <tr> <td>x</td
  • 如何处理上溢和下溢?(How to deal with overflow and underflow?)
    问题 我是Matlab的新手,试图弄清楚当答案实际上在范围内时如何处理上溢和下溢算法。 例如: x = 2e+160 x = x*x (which returns inf, an overflow) x = sqrt(x) (which is in the range) 任何帮助表示赞赏。 回答1 我不是Matlab用户,因此请记住这一点。 其背后的主要问题是首先检测到上溢/下溢 有时候这很困难,因为在其他情况下,当计算不返回zero或inf时,它们也会出现。 例如,在数值积分期间,上溢/下溢会导致结果错误,但仍然是非零数。 根据我的经验,我认为查看以十六进制表示的数字很有用(除非您的HW / SW计算内部使用十进制基数作为变量,这是罕见的,因为大多数HW / SW是二进制的)。 因此,请以十六进制形式查看数字并检测如下模式: ??????????.????FFFFFFFFFFF?? hex 当您查看小数部分FFFFF现在最低位数附近存在许多FFFFF您的数字很可能下溢或非常接近该点。 零的数量或结束时的数量通常随着每次迭代的饱和而减少: ??????????.????FFFFFFFFFFF hex 溢出也类似地饱和,但另一方面是这样的: FFFFFFFFFFF.FFFFFF?????? hex 对于某些算法,在下一次迭代之前更精确地四舍五入这些数字是很精确的,但是在应用未知数之前
  • 使用cmd.exe时如何处理引号字符(How do I deal with quote characters when using cmd.exe)
    问题 我正在尝试这样做: cmd.exe /C "C:\Program Files\Somewhere\SomeProgram.exe" > "C:\temp\Folder Containing Spaces\SomeProgram.out" 但是,我遇到的问题取决于cmd.exe的工作方式。 如果您阅读了它的帮助,它会以特殊方式处理“字符。请参阅问题末尾的帮助。因此,此操作无法正确执行...我猜cmd.exe会去除一些引号,从而使声明格式错误。 我可以成功做到这一点: // quotes not required around folder with no spaces cmd.exe /C "C:\Program Files\Somewhere\SomeProgram.exe" > C:\temp\FolderWithNoSpaces\SomeProgram.out 但是,我真的需要第一个上班。 cmd.exe使用的奇怪报价处理周围是否存在? 我希望它保留所有引号,但似乎没有使其执行该操作的选项。 从以下命令的输出中获取帮助:cmd /? 如果指定了/ C或/ K,则将开关之后的命令行其余部分作为命令行处理,其中以下逻辑用于处理引号(“)字符: 1. If all of the following conditions are met, then quote
  • 使用Ninject时如何处理DBContext(How to handle DBContext when using Ninject)
    问题 我正在尝试第一次使用Ninject和OpenAccess。 请在以下方面帮助我。 这是我的项目的样子... public class ContentController : Controller { private ContentService contentSvc; public ContentController(ContentService contentSvc) { this.contentSvc = contentSvc; } } 下列课程在我的Web应用程序中的文件夹下。 public class ContentService { private IContentRepository contentRepository; public ContentService(IContentRepository contentRepository) { this.contentRepository = contentRepository; } public void InsertContent(Content content) { contentRepository.InsertContent(content); } } 以下存储库属于一个单独的程序集。 public class ContentRepository : IContentRepository {
  • 应用程序在后台时如何处理套接字连接的事件?(How to handle socket connection's events when app is in background?)
    问题 我想在应用程序处于后台时使用以下功能吗? - (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent { case NSStreamEventHasBytesAvailable: { NSLog(@"Event:NSStreamEventHasBytesAvailable"); if (theStream == _inputStream) { NSLog(@"NSStreamEventHasBytesAvailable: on Input Stream"); uint8_t buffer[1024]; int len; while ([_inputStream hasBytesAvailable]) { len = [_inputStream read:buffer maxLength:sizeof(buffer)]; if (len > 0) { NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding]; if (nil != output) { NSLog(@"server said: %@", output); // to get
  • 应用程序在前台时如何处理Firebase通知(How to handle the Firebase notification when app is in foreground)
    问题 我已将Firebase Cloud Messaging与我的应用程序集成在一起。 当我从Firebase控制台发送通知时,如果该应用程序在后台或未打开,则我会成功接收到该通知,否则,如果该应用程序在前台或已打开,则不会收到该通知。 所有建议表示赞赏。 回答1 当应用程序处于前台时,不会自行生成通知。 您需要编写一些其他代码。 收到消息后,将调用onMessageReceived()方法,您可以在其中生成通知。 这是代码: public class MyFirebaseMessagingService extends FirebaseMessagingService { @Override public void onMessageReceived(RemoteMessage remoteMessage) { super.onMessageReceived(remoteMessage); Log.d("msg", "onMessageReceived: " + remoteMessage.getData().get("message")); Intent intent = new Intent(this, MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); PendingIntent
  • 获取对象时如何处理“不存在匹配查询”(How to handle “matching query does not exist” when getting an object)
    问题 当我想使用get()函数选择对象时 personalProfile = World.objects.get(ID=personID) 如果get函数没有返回查找值,则“不存在匹配查询”。 发生错误。 如果我不需要此错误,我将使用try和except函数 try: personalProfile = World.objects.get(ID=personID) except: pass 但是我认为这不是自使用以来最好的方法 except: pass 请推荐一些想法或代码示例来解决此问题 回答1 这取决于您不存在时要执行的操作。 有get_object_or_404: 在给定的模型管理器上调用get(),但它引发Http404而不是模型的DidNotExist异常。 get_object_or_404(World, ID=personID) 除了您当前执行的代码外,这与try非常接近。 否则有get_or_create: personalProfile, created = World.objects.get_or_create(ID=personID) 虽然,如果您选择继续使用当前的方法,则至少要确保将except定位到正确的错误,然后根据需要进行一些处理 try: personalProfile = World.objects.get(ID=personID) except
  • 使用任务并行库时如何处理所有未处理的异常?(How to handle all unhandled exceptions when using Task Parallel Library?)
    问题 我在.NET 4.0中使用TPL(任务并行库)。 我想通过使用Thread.GetDomain().UnhandledException事件集中所有未处理的异常的处理逻辑。 但是,在我的应用程序中,对于以TPL代码Task.Factory.StartNew(...)线程,例如Task.Factory.StartNew(...) ,永远不会触发该事件。 如果使用诸如new Thread(threadStart).Start()类的东西,则确实会触发该事件。 该MSDN文章建议在使用TPL时使用Task.Wait()来捕获AggregateException ,但这不是我想要的,因为此机制不够“集中”。 有人遇到过同样的问题吗?还是只有我一个人? 您对此有什么解决方案吗? 回答1 我认为TaskScheduler.UnobservedTaskException事件是您想要的: 当有故障的任务的未观察到的异常即将触发异常升级策略时发生,默认情况下,该策略将终止该进程。 因此,此事件类似于您在问题中提到的DomainUnhandledException ,但仅在任务中发生。 顺便说一句,未观察到的例外策略(是的,这不是不可观察到的例外,MS专家又发明了一个新词……)从.NET 4.0更改为.NET 4.5。 在.NET 4.0中,未观察到的异常导致进程终止,但在.NET 4.5中
  • 为什么在使用MSI时将文件部署限制在用户配置文件或HKCU中是一个好主意?(Why is it a good idea to limit deployment of files to the user-profile or HKCU when using MSI?)
    问题 为什么最好将MSI或安装文件中的文件部署限制在用户配置文件或HKCU中? 部署是大多数开发的关键部分。 请给这个内容一个机会。 我坚信,可以通过在应用程序设计中进行很小的更改来显着提高软件质量,从而使部署更合理,更可靠-这就是软件开发的全部“答案”。 这是一个Q / A风格的问题,与一个太长的答案分开:如何避免WiX / MSI部署解决方案中的常见设计缺陷? 回答1 如上所述,本节与范围更广的现有答案分开:如何避免WiX / MSI部署解决方案中的常见设计缺陷? (旨在帮助开发人员做出更好的部署决策的答案)。 9.过度使用每个用户的文件和注册表部署。 某些应用程序无法在一台计算机上为所有用户正确运行,因为在安装过程中添加的特定于用户的数据未正确添加到其他用户的配置文件和注册表中。 换句话说,该应用程序仅适用于安装该软件的用户。 这显然是一个严重的设计错误。 有几种方法可以“解决”此问题,但是由于一些基本原因,整个按用户文件和设置的部署问题有些混乱: 您如何引用计数多次安装的组件? (针对机器上的每个用户) 在卸载时如何处理已安装的数据和设置? 您如何处理要安装的新文件和设置,这些新文件和设置与磁盘和注册表中的新文件和设置不同,并且需要用户进行更改? 您确定不会自动覆盖吗? 没有真正明确的答案,但是有几种替代方法可以解决“问题”。 我的首选选项是2和3
  • ASP.NET(C#) 读取EXCEL问题汇总
    使用OLEDB可以对excel文件进行读取,我们只要把该excel文件作为数据源即可。一 在D盘创建excel文件test.xls:  二 将工作表Sheet1的内容读取到DataSet  string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:/test.xls;"+    "Extended Properties='Excel 8.0'";  DataSet ds = new DataSet();  OleDbDataAdapter oada = new OleDbDataAdapter("select * from [Sheet1$]", strConn);  oada.Fill(ds); 读取的DataSet为:  从图中可以看出excel文件中的第一行变成了DataSet中的列名,这正是系统的默认设置。三 如果想把第一行也作为数据行,那我们可以给连接字符串添加一个HDR=No属性如:  string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:/test.xls;"+   "Extended Properties='Excel 8.0;HDR=No'";  DataSet ds = new DataSet();
  • 流Http请求的正文时如何处理错误(What to do with errors when streaming the body of an Http request)
    问题 如何处理Http消息中间的服务器错误? 假设我已经发送了邮件的标头,并且正在流式处理邮件的正文,当遇到意外错误时该怎么办。 我还假设此错误是在生成内容时引起的,而不是连接错误。 (极大)简化代码: // I can define any transfer encoding or header fields i need to. send(header); // Sends the header to the Http client. // Using an iterable instead of stream for code simplicity's sake. Iterable<String> stream = getBodyStream(); Iterator<String> iterator = stream.iterator(); while (iterator.hasNext()) { String string; try { string = iterator.next(); catch (Throwable error) { // Oops! an error generating the content. // What do i do here? (In regards to the Http protocol) } send(string); }