当前位置: 首页 > news >正文

使用 ASP.NET Core wwwroot 上传和存储文件

在 ASP.NET Core 应用程序中上传和存储文件是用户个人资料、产品目录等功能的常见要求。本指南将解释使用wwwroot存储图像(可用于文件)的过程以及如何在应用程序中处理图像上传。

步骤 1:设置项目环境

确保您的 ASP.NET 项目中具有必要的依赖项和环境设置。这包括配置服务和wwwroot在项目中创建用于静态文件服务的文件夹。 

静态文件服务是将未编译的内容(如图像、CSS 和 JavaScript 文件)直接从服务器传送到客户端浏览器的过程。

第 2 步:定义模型和 DTO

创建模型和数据传输对象 (DTO) 来处理图像元数据和其他相关数据。 

public class Branch
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public string Location { get; set; }
    public string Email { get; set; }
    public string Phone { get; set; }
    public string? ImagePath { get; set; } // Path to the stored image

步骤 3:配置图像上传的控制器操作 

实现控制器操作来处理上传图像的 HTTP 请求。 

上传并存储图像

1、为图像生成一个唯一的文件名。

2、将图像存储在wwwroot/images目录中(或任何其他目录中)。

3、在数据库中保存图像路径。

[HttpPost]
public async Task<IActionResult> AddBranch([FromForm] AddBranchDto addBranchDto, IFormFile image)
{
    string? imagePath = null;
    if (image != null)
    {
        var fileName = $"{Guid.NewGuid()}-{Path.GetFileName(image.FileName)}";
        var filePath = Path.Combine(_webHostEnvironment.WebRootPath, "images", fileName);

        using (var stream = new FileStream(filePath, FileMode.Create))
        {
            await image.CopyToAsync(stream);
        }

        imagePath = Path.Combine("images", fileName);
    }

    var branchEntity = new Branch
    {
        Name = addBranchDto.Name,
        Location = addBranchDto.Location,
        Email = addBranchDto.Email,
        Phone = addBranchDto.Phone,
        ImagePath = imagePath
    };

    _dbContext.Branches.Add(branchEntity);
    await _dbContext.SaveChangesAsync();

    return Ok(branchEntity);
}

更新图像

处理图像的更新,包括在上传新图像时删除旧图像。

[HttpPut("{id:guid}")]
public async Task<IActionResult> UpdateBranch(Guid id, [FromForm] UpdateBranchDto updateBranchDto, IFormFile image)
{
    var branch = _dbContext.Branches.Find(id);
    if (branch == null)
        return NotFound();

    if (image != null)
    {
        var fileName = $"{Guid.NewGuid()}-{Path.GetFileName(image.FileName)}";
        var filePath = Path.Combine(_webHostEnvironment.WebRootPath, "images", fileName);

        if (!string.IsNullOrEmpty(branch.ImagePath))
        {
            var oldFilePath = Path.Combine(_webHostEnvironment.WebRootPath, branch.ImagePath.Replace('/', '\\'));
            if (System.IO.File.Exists(oldFilePath))
            {
                System.IO.File.Delete(oldFilePath);
            }
        }

        using (var stream = new FileStream(filePath, FileMode.Create))
        {
            await image.CopyToAsync(stream);
        }

        branch.ImagePath = Path.Combine("images", fileName);
    }

    branch.Name = updateBranchDto.Name;
    branch.Location = updateBranchDto.Location;
    branch.Email = updateBranchDto.Email;
    branch.Phone = updateBranchDto.Phone;

    await _dbContext.SaveChangesAsync();

    return Ok(branch);
}

步骤 4:提供静态文件 

配置应用程序以从wwwroot目录提供静态文件。

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles(); // Enable static file serving

    app.UseRouting();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

步骤 5:前端集成

在您的前端(例如,Angular)中,实现表单来处理图像上传。

<form [formGroup]="branchForm" (ngSubmit)="onSubmit()">
  <!-- Other form fields -->
  <mat-label>Image</mat-label>
  <input type="file" formControlName="image" (change)="onFileChange($event)" />
  <button type="submit">Save</button>
</form>

处理文件变更及提交

onFileChange(event: any): void {
    const file = event.target.files[0];
    if (file) {
        this.selectedFile = file;
    }
}

onSubmit(): void {
    if (this.branchForm.valid) {
        const formData = new FormData();
        Object.keys(this.branchForm.value).forEach(key => {
            formData.append(key, this.branchForm.value[key]);
        });

        if (this.selectedFile) {
            formData.append('image', this.selectedFile);
        }

        if (this.isEditMode) {
            this.branchService.updateBranch(this.branchId, formData).subscribe();
        } else {
            this.branchService.addBranch(formData).subscribe();
        }
    }
}

结论

        通过遵循这些步骤,您可以成功地将具有唯一名称的图像上传并存储在wwwrootASP.NET 应用程序的目录中,从而确保有效地管理和检索图像。

如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。   

相关文章:

使用 ASP.NET Core wwwroot 上传和存储文件

在 ASP.NET Core 应用程序中上传和存储文件是用户个人资料、产品目录等功能的常见要求。本指南将解释使用wwwroot存储图像&#xff08;可用于文件&#xff09;的过程以及如何在应用程序中处理图像上传。 步骤 1&#xff1a;设置项目环境 确保您的 ASP.NET 项目中具有必要的依…...

什么是 Azure OpenAI ?了解微软 Azure OpenAI 和 OpenAI 的关系

一、什么是Azure OpenAI &#xff1f; 微软已与 OpenAI 合作以实现三个主要目标&#xff1a; ⦿利用 Azure 的基础结构&#xff08;包括安全性、合规性和区域可用性&#xff09;&#xff0c;帮助用户构建企业级应用程序。 ⦿在微软产品&#xff08;包括 Azure AI 产品以及以外…...

Flink CDC 自定义函数处理 SQLServer XML类型数据 映射 doris json字段方案

Flink CDC 自定义函数处理 SQLServer XML类型数据方案 1. 背景 因业务使用SQLServer数据库&#xff0c;CDC同步到doris 数仓。对于SQLServer xml类型&#xff0c;doris没有相应的字段对应&#xff0c; 可以使用json来存储xml数据。需要进行一步转换。从 flink 自定义函数入手…...

导致启动nacos报错Caused by: java.lang.IllegalStateException: No DataSource set 的两种原因

Java资深小白&#xff0c;不足之处&#xff0c;或者有任何错误欢迎指出。 --蓝紫报错代码如下: C:\Windows\System32>cd D:\nacos-server-2.2.3\nacos\binC:\Windows\System32>d:D:\nacos-server-2.2.3\nacos\bin>startup.cmd -m standalone "nacos is starting…...

mysql乱码、mysql数据中文问号

网上排出此错误方法的很多&#xff0c;但是 都不简洁&#xff0c;找不到根本原因 主要排查两点&#xff1a; 1.代码中jdbc链接的编码规则 urljdbc:mysql://localhost:3306/title?useUnicodetrue&amp;characterEncodingutf8 将characterEncoding设置为utf8 2.设置mysq…...

python RAG 管道

RAG&#xff08;RetrievalAugmented Generation&#xff09;管道是一种结合了信息检索&#xff08;Retrieval&#xff09;和文本生成&#xff08;Generation&#xff09;的技术框架&#xff0c;主要用于生成高质量、基于事实的文本。它通过从外部知识源&#xff08;如文档、数据…...

018-spring-基于aop的事务控制

1 先配置平台事务管理器 2 在配置 spring提供的advice 3 事务增强的aop 总结&#xff1a; 事务就是要做2个配置&#xff1a; <!-- 1 开启事务管理器 不同的框架对应不同的事务管理器 --> <bean id"transactionManager" class"org.springframework.j…...

HTML 轮播图(Carousel)详细讲解

HTML 轮播图&#xff08;Carousel&#xff09;详细讲解 轮播图&#xff08;Carousel&#xff09;是一种常见的用户界面组件&#xff0c;用于在同一位置展示多个图像或内容&#xff0c;允许用户通过滑动或自动播放的方式查看不同的内容。它通常用于展示产品、图片、广告等。 1…...

计算机网络-数据链路层(ppp协议)

2.2 ppp协议 点对点协议ppp是目前使用最广泛的点对点数据链路层协议。 2.3 媒体接入控制基本概念 共享信道要着重考虑的一个问题就是如何协调多个发送和接收站点对一个共享传输媒体的占用&#xff0c;即媒体接入控制MAC。 2.3.1 静态划分信道 频分复用 时分复用 波分复用 码分复…...

如何优化Python网络爬虫的数据清洗流程,以提升数据质量并有效应对网站反爬虫机制?

优化爬虫数据清洗流程&#xff0c;应对反爬虫机制 一、数据清洗的重要性 在网络爬虫中&#xff0c;数据清洗是关键环节。打个比方&#xff0c;我们从网页抓取到的原始数据就像一堆杂乱的杂物&#xff0c;里面有各种格式、错误和重复信息。比如抓取到的文本可能包含HTML标签、…...

QSharedMemory 实现数据exe间共享

定义共享数据结构 首先&#xff0c;需要定义一个结构体来包含要共享的数据。这个结构体应该包含所有需要在多个类的实例之间共享的成员变量 struct SharedData {int intValue;QString stringValue;// 可以添加更多需要共享的成员变量}; 使用 QSharedMemory 进行数据共享 在写…...

强化学习(1)

Reinforcement Learning Goal-directed learing from ineraction with the environment. 1. Basic Element 基本元素 1.1 Agent 玩家 1.2 Environment 1.3 Goal 2. Main Element 主要元素 2.1 State 2.2 Action 状态与行为往复 2.3 Reward 目标&#xff1a;最大化总…...

Spring Boot 嵌套事务详解及失效解决方案

在复杂的业务场景中&#xff0c;嵌套事务可以帮助我们更加精细地控制数据的一致性。然而&#xff0c;在 Spring Boot 中&#xff0c;如果嵌套事务的配置不当&#xff0c;可能会导致事务不生效的问题&#xff0c;尤其是在同一个类中进行方法调用时。 本文将详细介绍嵌套事务的原…...

IDEA 社区版 SpringBoot不能启动

报错原因&#xff0c;Failed to load class [javax.servlet.Filter] <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId><scope>provided</scope> </dependency>…...

【SQL server】教材数据库(4)

学生&#xff08;学号&#xff0c;年龄&#xff0c;性别&#xff0c;系名&#xff09; 教材&#xff08;编号&#xff0c;书名&#xff0c;出版社编号&#xff0c;价格&#xff09; 订购&#xff08;学号&#xff0c;书号&#xff0c;数量&#xff09; 出版社&#xff08;编…...

px、em、rem,vw区别介绍

在网页设计中&#xff0c;px、em、rem 和 vw 都是常用的 CSS 单位&#xff0c;它们各自有不同的用途和特性。下面是这些单位的详细介绍及其区别&#xff1a; 1. px&#xff08;像素&#xff09; 定义&#xff1a; px 是最常用的绝对单位&#xff0c;表示屏幕上的一个物理像素…...

pip安装paddle失败

一、pip安装paddle失败&#xff0c;报错如下 Preparing metadata (setup.py) ... error error: subprocess-exited-with-error import common, dual, tight, data, prox ModuleNotFoundError: No module named common [end of output] 二、解决方法&#xff1a; 按照提示安装对…...

QWT 之 QwtPlotDirectPainter直接绘制

QwtPlotDirectPainter 是 Qwt 库中用于直接在 QwtPlot 的画布上绘制图形的一个类。它提供了一种高效的方法来实时更新图表&#xff0c;特别适合需要频繁更新的数据可视化应用&#xff0c;例如实时数据流的显示。 使用 QwtPlotDirectPainter 的主要优势在于它可以绕过 QwtPlot 的…...

编辑音频的基本属性

导入音频 “文件-导入-选择音频”拖到音频轨道创建序列。选择音频&#xff0c;在效果空间可以看到音频的基本属性。 音量的设置 “效果工作区-效果控件-音量”在这里可以控制所有引导的混合音量 静音 静止所有声音 音频仪表 一般位于时间轴的后面&#xff0c;找不到可以…...

【英特尔IA-32架构软件开发者开发手册第3卷:系统编程指南】2001年版翻译,2-44

文件下载与邀请翻译者 学习英特尔开发手册&#xff0c;最好手里这个手册文件。原版是PDF文件。点击下方链接了解下载方法。 讲解下载英特尔开发手册的文章 翻译英特尔开发手册&#xff0c;会是一件耗时费力的工作。如果有愿意和我一起来做这件事的&#xff0c;那么&#xff…...

格式化输出年月日

直接上图 结论&#xff1a;老老实实用yyyy&#xff0c;得到的年月日是我们口头上说的时间&#xff0c;而YYYY有点反人类.... 对于一年的最后一周的一些日子&#xff0c;会统计成下一年&#xff1b; 对于下一年的第一周的一些日子&#xff0c;会统计成上一年&#xff1b; 你猜…...

解决Spring boot集成quartz时service注入失败为null的问题

解决Spring boot集成quartz时service注入失败为null的问题 一、报错信息二、代码任务类源代码配置类原代码 三、注入失败原因四、解决的思路11、任务类修改2、配置类修改 五、 解决的思路2 一、报错信息 java.lang.NullPointerException: null at farbun.server.scheduledTask…...

Python 青铜宝剑十六维,破医疗数智化难关(下)

九、模型可靠性的验证秘籍 在医疗数智化进程中,模型可靠性宛如一座灯塔,为精准医疗决策指引方向。以疾病诊断模型为例,一旦模型可靠性存疑,在癌症早期筛查场景下,可能将良性病变误判为恶性,让患者承受不必要的痛苦与恐慌,又或是遗漏细微癌变迹象,延误最佳治疗时机;在…...

初识具身智能

具身智能是智能科学的一个基础问题&#xff0c;在过去的5.4亿年以来&#xff0c;地球上所有生物都是通过身体和环境交互、进化逐步产生的。通俗地讲&#xff0c;具身智能体以第一人称视角身临其境地从环境交互中理解外部世界的本质概念&#xff0c;被认为是通向通用人工智能的重…...

Node 使用pkg打包部署

一、安装pkg(不太好装&#xff0c;需要借助国内镜像) npm install -g pkg --registryhttps://registry.npm.taobao.org 二、配置package.jsonsan // package.json ,配置专门制定pkg的执行入口 { ... "bin": "main.js", "pkg":{"assets&q…...

计算机网络-L2TP Over IPSec基础实验

一、概述 上次我们进行了标准L2TP的配置&#xff0c;但是在最后我们在进行业务流量访问时看到流量是没有进行加密的&#xff0c;这就导致可能得安全风险&#xff0c;所以这里其实可以退像GRE那样调用IPSec框架来进行加密保护。 拓扑 数据不加密 现在需要配置IPSec&#xff0c;然…...

Java工程师实现视频文件上传minio文件系统存储及网页实现分批加载视频播放

Java工程师实现minio存储大型视频文件网页实现分批加载视频播放 一、需求说明 老板给我出个题目&#xff0c;让我把的电影文件上传到minio文件系统&#xff0c;再通过WEB端分配加载视频播放&#xff0c;类似于我们普通的电影网站。小编把Java代码共享出来。是真正的能拿过来直…...

html5css3

1.html5新增语义化标签 <header><nav><article><section><aside><footer> 2.新增多媒体标签 视频<video>格式&#xff1a;map4,webm,ogg <video controls"controls" autoplay"autoplay" muted"mute…...

运维人员的Go语言学习路线

以下是一份更为详细的适合运维人员的Go语言学习路线图&#xff1a; 一、基础环境搭建与入门&#xff08;第 1 - 2 周&#xff09; 第 1 周 环境搭建 在本地开发机和常用的运维服务器环境&#xff08;如 Linux 系统&#xff09;中安装 Go 语言。从官方网站&#xff08;https://…...

怎么在家访问公司服务器?

在日常工作中&#xff0c;特别是对信息技术从业者而言&#xff0c;工作往往离不开公司的服务器。他们需要定期访问服务器&#xff0c;获取一些关键的机密文件或数据。如果您在家办公&#xff0c;并且需要处理未完成的任务&#xff0c;同时需要从公司服务器获取所需的数据&#…...

【linux学习指南】】Ext系列文件系统(三)ext2 文件系统的认识与构成

文章目录 &#x1f4dd;ext2 ⽂件系统&#x1f320; 宏观认识&#x1f309; Block Group &#x1f320;块组内部构成&#x1f309;超级块&#xff08;SuperBlock&#xff09; &#x1f320;GDT&#xff08;GroupDescriptorTable&#xff09;&#x1f309;块位图&#xff08;Blo…...

区块链安全常见的攻击分析——Unprotected callback - ERC721 SafeMint reentrancy【8】

区块链安全常见的攻击分析——Unprotected callback - ERC721 SafeMint reentrancy【8】 1.1 漏洞分析1.2 漏洞合约1.3 攻击分析1.4 攻击合约 重点&#xff1a;MaxMint721 漏洞合约的 mint 函数调用了 ERC721 合约中的 _checkOnERC721Received 函数&#xff0c;触发 to 地址中实…...

Linux中sed命令的使用技巧

一、sed语法介绍 sed命令主要用于文本内容的编辑&#xff0c;默认只处理模式空间&#xff0c;不处理原数据。 命令格式&#xff1a; sed [option] command filename示例&#xff1a;删除空白行 sed ‘/^\s*$/d’ filename option 参数&#xff1a; -n&#xff1a;只有经过sed…...

小米路由器开启SSH,配置阿里云ddns,开启外网访问SSH和WEB管理界面

文章目录 前言一、开启SSH二、配置阿里云ddns1.准备工作2.创建ddns脚本3.添加定时任务 三、开启外网访问SSH和WEB管理界面1、解除WEB管理页面访问限制2.手动添加防火墙端口转发规则&#xff0c;开启外网访问WEB管理和SSH 前言 例如&#xff1a;随着人工智能的不断发展&#xf…...

Flink源码解析之:如何根据JobGraph生成ExecutionGraph

Flink源码解析之&#xff1a;如何根据JobGraph生成ExecutionGraph 在上一篇Flink源码解析中&#xff0c;我们介绍了Flink如何根据StreamGraph生成JobGraph的流程&#xff0c;并着重分析了其算子链的合并过程和JobGraph的构造流程。 对于StreamGraph和JobGraph的生成来说&…...

活动预告 |【Part2】Microsoft 安全在线技术公开课:安全性、合规性和身份基础知识

课程介绍 通过参加“Microsoft 安全在线技术公开课&#xff1a;安全性、合规性和身份基础知识”活动提升你的技能。在本次免费的介绍性活动中&#xff0c;你将获得所需的安全技能和培训&#xff0c;以创造影响力并利用机会推动职业发展。你将了解安全性、合规性和身份的基础知…...

网络基础入门到深入(2):网络协议-TCP/IP协议栈

目录 一.TCP/IP协议栈的四层结构 二.每一层的作用与协议 1.作用层 作用&#xff1a; 常见协议: 示例: 2.传输层 作用: 核心功能: 3.网络层 作用: 核心功能: 常见协议: 示例: 4.数据链路层(物理层) 作用: 核心功能: 常见技术: 示例: 三.TCP/IP协议栈的分层…...

美畅物联丨视频上云网关获取视频流地址供第三方调用的方法

在视频监控与流媒体传输领域&#xff0c;视频流地址的获取与调用是极为关键的环节。视频上云网关作为一款高效且稳定的视频传输设备&#xff0c;为获取视频流地址提供了便捷途径&#xff0c;从而使外部系统或平台能够方便地进行调用。今天我们就来讨论一下如何在视频上云网关上…...

【Cesium】一、cesium简介

文章目录 前言1.什么是Cesium&#xff1f;2.Cesium能做什么&#xff1f;3.Cesium的依赖性4.Cesium学习参考 前言 本人是前端&#xff0c;主要是开发web&#xff0c;使用技术栈Vue、Js。最近因工作需要开始学习使用Cesium&#xff0c;找到一位博主的文章很好&#xff0c;一边学…...

微服务架构介绍

微服务架构是一种现代化的软件架构风格&#xff0c;它将应用程序构建为一组小型、自治的服务&#xff0c;每个服务都运行在其独立的进程中&#xff0c;服务与服务之间通过轻量级通信机制&#xff08;通常是HTTP/RESTful API&#xff09;进行通信。 1. 服务&#xff08;Service&…...

SOLID-开闭原则

单一职责原则&#xff1a;https://blog.csdn.net/dmk877/article/details/143447010 在前面我们学习了单一职责原则&#xff0c;今天来一起学习一下SOLID原则中的开闭原则(Open-Closed Principle, OCP) 通过本篇博客你将学到到以下内容 ①什么是开闭原则 ②如何实现开闭原则 ③…...

Mac 安装 Flutter 提示 A network error occurred while checking

错误信息 A network error occurred while checking "https://maven.google.com/": Operation timed out原因 在中国大陆(由于访问 Google 服务器的限制导致超时),无法连接到 https://maven.google.com/ 解决方案 需要使用镜像网站 #flutter 使用国内的镜像 export …...

Rocky Linux下安装meld

背景介绍&#xff1a; meld是一款Linux系统下的用于 文件夹和文件的比对软件&#xff0c;非常常用&#xff1b; 故障现象&#xff1a; 输入安装命令后&#xff0c;sudo yum install meld&#xff0c;报错。 12-31 22:12:17 ~]$ sudo yum install meld Last metadata expirat…...

Sentinel 介绍与使用指南:构建高可用、可靠的微服务架构

在微服务架构中&#xff0c;服务间的依赖和调用非常复杂&#xff0c;这也带来了高并发、大流量等挑战。 如何确保系统在高负载情况下仍能稳定运行&#xff0c;如何避免某个服务的故障影响整个系统的稳定性&#xff1f;Sentinel&#xff0c;作为一个轻量级的、专为分布式系统设计…...

异步请求在TypeScript网络爬虫中的应用

异步请求的重要性 异步请求是现代网络应用中不可或缺的一部分&#xff0c;特别是在网络爬虫领域。它允许爬虫在等待网络响应的同时继续执行其他任务&#xff0c;从而提高效率和性能。在JavaScript和TypeScript中&#xff0c;异步请求可以通过多种方式实现&#xff0c;包括回调…...

智能商业分析 Quick BI

Quick BI 是阿里云提供的一款智能商业分析&#xff08;BI&#xff09;工具&#xff0c;旨在帮助企业快速获取业务洞察、优化决策过程、提升数据分析效率。通过强大的数据可视化和分析功能&#xff0c;Quick BI 能够帮助用户轻松连接多种数据源、创建多维度的报表和仪表盘&#…...

[算法] [leetcode-75] 颜色分类

75 颜色分类 给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums &#xff0c;原地 对它们进行排序&#xff0c;使得相同颜色的元素相邻&#xff0c;并按照红色、白色、蓝色顺序排列。 我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。 必须在不使用库内置的 sort 函…...

抖音短视频矩阵系统源码开发技术解析

开发概览&#xff1a; 抖音短视频矩阵系统的构建基于一系列现代技术栈&#xff0c;主要包括VUE, Spring Boot和Django。本文档旨在为开发者提供关于短视频矩阵系统源代码的开发与部署指南。 技术框架分析&#xff1a; 前端技术选型&#xff1a; 对于前端界面的构建&#xf…...

Linux(CentOS)安装 MySQL

CentOS版本&#xff1a;CentOS 7 三种安装方式&#xff1a; 一、通过 yum 安装&#xff0c;最简单&#xff0c;一键安装&#xff0c;全程无忧。 二、通过 rpm 包安装&#xff0c;需具备基础概念及常规操作。 三、通过 gz 包安装&#xff0c;需具备配置相关操作。 --------…...

头歌实训数据结构与算法-二叉树及其应用(第9关:二叉树的顺序存储及基本操作)

任务描述 本关任务&#xff1a;以顺序结构存储二叉树&#xff0c;编写前序、中序、后序及层次顺序遍历二叉树的算法&#xff0c;并计算二叉树深度、所有结点总数。 相关知识 二叉树的定义 二叉树的递归定义&#xff1a; 二叉树或者是一棵空树。 或者是一棵由一个根结点和两…...