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

【进阶编程】MVC和MVVM实现前后端分离的实现

在 WPF 开发中,通常使用 MVVM(Model-View-ViewModel)架构来分离视图和业务逻辑,但在某些情况下,你可能希望将 MVC(Model-View-Controller)模式与 MVVM 结合使用。这种结合有时是为了兼顾不同的架构优势,尤其是在大型应用程序中,或者当你在 WPF 中同时使用 Web 或 ASP.NET Core 后端时。

MVC 和 MVVM 结合的场景

MVC 是一种广泛用于 Web 开发的架构模式,主要通过 Controller 来协调 ModelView,而 MVVM 是 WPF 中的推荐模式。在某些应用中,你可能需要以下两种模式的结合:

  • Web API/后端使用 MVC:如果你的应用涉及到 Web 服务或后端业务逻辑层,通常你会使用 MVC 模式来管理 API 请求、处理逻辑并返回视图。
  • 前端使用 MVVM:WPF 前端通常使用 MVVM 模式来分离界面和逻辑,控制视图与数据的交互。

如何结合 MVC 和 MVVM

结合 MVC 和 MVVM 主要通过以下方式进行:

  1. 使用 MVC 处理后端业务和数据

    • 在后端部分,你使用 MVC 模式来处理数据库交互、API 请求和数据管理。
    • 前端通过调用后端接口或 Web API 来获取数据,数据从 Model(或 Web API)传递到 ViewModel
  2. 在 WPF 中使用 MVVM 处理界面和交互

    • 在前端的 WPF 应用中,你使用 MVVM 模式管理视图和视图模型,确保业务逻辑和 UI 逻辑解耦。
    • Controller 的角色可以被 ViewModel 取代,ViewModel 负责与后端进行通信,接收数据并将其展示在视图中。

结合 MVC 和 MVVM 的具体示例

后端部分:MVC 模式

假设我们有一个后端 API,使用 ASP.NET Core MVC 处理客户数据。

1. 创建一个 Model 类:

public class Customer
{public int Id { get; set; }public string Name { get; set; }public string Email { get; set; }
}

2. 创建一个 Controller 类:

using Microsoft.AspNetCore.Mvc;[ApiController]
[Route("api/[controller]")]
public class CustomerController : ControllerBase
{// 模拟数据存储private static List<Customer> customers = new List<Customer>{new Customer { Id = 1, Name = "Alice", Email = "alice@example.com" },new Customer { Id = 2, Name = "Bob", Email = "bob@example.com" }};[HttpGet]public IEnumerable<Customer> GetCustomers(){return customers;}[HttpGet("{id}")]public ActionResult<Customer> GetCustomer(int id){var customer = customers.FirstOrDefault(c => c.Id == id);if (customer == null) return NotFound();return customer;}
}

在这个控制器中,GetCustomersGetCustomer 方法分别返回所有客户和单个客户的信息。

前端部分:MVVM 模式

在 WPF 前端中,我们使用 MVVM 模式来展示从后端 API 获取的数据。

1. 创建 Customer Model 类:

public class Customer
{public int Id { get; set; }public string Name { get; set; }public string Email { get; set; }
}

2. 创建 ViewModel 类:

using System.Collections.ObjectModel;
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json;public class MainViewModel : INotifyPropertyChanged
{private ObservableCollection<Customer> _customers;private bool _isLoading;public ObservableCollection<Customer> Customers{get { return _customers; }set{_customers = value;OnPropertyChanged(nameof(Customers));}}public bool IsLoading{get { return _isLoading; }set{_isLoading = value;OnPropertyChanged(nameof(IsLoading));}}public MainViewModel(){Customers = new ObservableCollection<Customer>();LoadCustomers();}private async void LoadCustomers(){IsLoading = true;using (var client = new HttpClient()){client.BaseAddress = new Uri("https://yourapiurl/api/");var response = await client.GetStringAsync("customer");var customers = JsonConvert.DeserializeObject<List<Customer>>(response);foreach (var customer in customers){Customers.Add(customer);}}IsLoading = false;}public event PropertyChangedEventHandler PropertyChanged;protected virtual void OnPropertyChanged(string propertyName){PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));}
}

MainViewModel 中,我们从后端 API 获取客户数据,并将其填充到 ObservableCollection<Customer> 中。我们使用 HttpClient 来发送 GET 请求,并使用 JsonConvert 反序列化返回的 JSON 数据。

3. 创建 XAML 界面:

<Window x:Class="WpfApp.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="MVVM with MVC Example" Height="350" Width="525"><Window.DataContext><local:MainViewModel /></Window.DataContext><Grid><ProgressBar Visibility="{Binding IsLoading, Converter={StaticResource BooleanToVisibilityConverter}}"HorizontalAlignment="Center" VerticalAlignment="Center" Width="200" Height="25" /><ListBox ItemsSource="{Binding Customers}" HorizontalAlignment="Left" Height="200" VerticalAlignment="Top" Width="200"><ListBox.ItemTemplate><DataTemplate><StackPanel><TextBlock Text="{Binding Name}" /><TextBlock Text="{Binding Email}" /></StackPanel></DataTemplate></ListBox.ItemTemplate></ListBox></Grid>
</Window>

在 XAML 中,我们使用数据绑定将 ListBoxItemsSource 绑定到 MainViewModel 中的 Customers 属性,并通过 BooleanToVisibilityConverter 显示/隐藏进度条。

4. 总结:MVC 和 MVVM 结合的优势

MVCMVVM 结合的优势体现在:

  • MVC 适用于后端控制,管理数据库和业务逻辑,处理请求和返回数据。
  • MVVM 适用于前端 UI 逻辑,确保视图和业务逻辑解耦,并提供更加灵活的 UI 更新机制。
  • 使用 Web APIHttpClient,可以轻松地将前端 MVVM 与后端 MVC 进行结合,使得两者之间的通信更加清晰和结构化。

这种结合特别适合于以下场景:

  1. 前后端分离的应用程序,其中后端使用 MVC 处理 API,前端使用 MVVM 来处理 WPF 用户界面。
  2. 需要将前端 WPF 应用与 Web API 连接的场景,保持了前端和后端的分离。
  3. 增强了应用的可维护性和可测试性,MVVM 使得前端更易于单元测试,MVC 使得后端更易于管理。

如果你有更多问题,随时可以提问!

相关文章:

【进阶编程】MVC和MVVM实现前后端分离的实现

在 WPF 开发中&#xff0c;通常使用 MVVM&#xff08;Model-View-ViewModel&#xff09;架构来分离视图和业务逻辑&#xff0c;但在某些情况下&#xff0c;你可能希望将 MVC&#xff08;Model-View-Controller&#xff09;模式与 MVVM 结合使用。这种结合有时是为了兼顾不同的架…...

HT81297 18W内置升压单声道D类音频功放

1、特征 扩频技术 输出功率 18W(VBAT3.7V, RL4Ω, THDN10%, fN 1kHz) 16W(VBAT3.7V,RL-4Ω,THDN1%,fN1kHz) 8W(VBAT3.3V,RL-8Ω,THDN1%, fN1kHz) VBAr供电范围:3.0V至12V 高效H类升压功能 -自适应功放功率的升压轨&#xff0c;延长电池播放时间 (HT81297A) -可调节最大限流值&…...

linux ipmitool配置机器的BMC(服务器管理后台)

前置&#xff1a;mgnt口和网卡1连接入内网&#xff0c;并分配静态ip 1. 安装 ipmitool Debian/Ubuntu: sudo apt-get update sudo apt-get install ipmitool CentOS/RHEL: sudo yum install ipmitool2. 配置 BMC 的 IP 地址 #打印当前ipmi 地址配置信息。 ipmitool lan p…...

【项目实战】location.href 实现文件下载

应用场景 最近在项目中看到一种新的文件下载方式,原理是将[后台地址接口地址请求参数]拼接成一个url,直接将下载任务丢给浏览器去执行.但是在需要校验token的项目中,需要后台单独给这个接口放开token校验 location.href 相关内容 window.location.protocol: 返回当前 URL 的…...

【Threejs】从零开始(十)--加载gltf模型和压缩后的模型

一.加载普通的gltf模型 glTF&#xff08;gl传输格式&#xff09;是一种开放格式的规范 &#xff08;open format specification&#xff09;&#xff0c; 用于更高效地传输、加载3D内容。该类文件以JSON&#xff08;.gltf&#xff09;格式或二进制&#xff08;.glb&#xff09;…...

国标GB28181平台EasyGBS在安防视频监控中的信号传输(电源/视频/音频)特性及差异

在现代安防视频监控系统中&#xff0c;国标GB28181协议作为公共安全视频监控联网系统的国家标准&#xff0c;该协议不仅规范了视频监控系统的信息传输、交换和控制技术要求&#xff0c;还为不同厂商设备之间的互联互通提供了统一的框架。EasyGBS平台基于GB28181协议&#xff0c…...

Day9 神经网络的偏导数基础

多变量函数与神经网络 在神经网络中&#xff0c;我们经常遇到多变量函数。这些函数通常描述了网络的输入、权重、偏置与输出之间的关系。例如&#xff0c;一个简单的神经元输出可以表示为&#xff1a; z f ( w 1 x 1 w 2 x 2 … w n x n b ) z f(w_1x_1 w_2x_2 \ldots…...

day4:tomcat—maven-jdk

一&#xff0c;java项目部署过程 编译&#xff1a;使用javac命令将.java源文件编译成.class宇节码文件打包&#xff1a;使用工具如maven或Gradle将项目的依赖、资源和编译后的字节码打包成一个分发格式&#xff0c;如.jar文件&#xff0c;或者.war文件(用于web应用&#xff09…...

apache-tomcat-6.0.44.exe Win10

apache-tomcat-6.0.44.exe Win10...

Redis(2)常用命令

安装Redis 现在我们安装Redis 5&#xff0c;Redis安装在Linux上面安装&#xff0c;如果想在本机上面安装多个Redis的话&#xff0c;就要使用Docker。 在Ubuntu上面安装&#xff1a; 切换到root用户使用apt命令搜索相关的软件包&#xff08;apt search redis&#xff09;apt …...

【原生js案例】ajax的简易封装实现后端数据交互

ajax是前端与后端数据库进行交互的最基础的工具&#xff0c;第三方的工具库比如jquery,axios都有对ajax进行第二次的封装&#xff0c;fecth是浏览器原生自带的功能&#xff0c;但是它与ajax还是有区别的&#xff0c;总结如下&#xff1a; ajax与fetch对比 实现效果 代码实现 …...

安卓环境配置及打开新项目教程,2024年12月20日最新版

1.去官网下载最新的Android Studio&#xff0c;网址&#xff1a;https://developer.android.com/studio?hlzh-cn 2.下载加速器&#xff0c;注册账号&#xff0c;开启加速器。网址&#xff1a;放在文末。 3.下载安卓代码&#xff0c;项目的路径上不能有中文&#xff0c;特别是…...

Docker 安装 禅道-21.2版本-外部数据库模式

Docker 安装系列 1、拉取最新版本&#xff08;zentao 21.2&#xff09; [rootTseng ~]# docker pull hub.zentao.net/app/zentao Using default tag: latest latest: Pulling from app/zentao 55ab1b300d4b: Pull complete 6b5749e5ef1d: Pull complete bdccb03403c1: Pul…...

写SQL太麻烦?免费搭建 Text2SQL 应用,智能写 SQL | OceanBase AI 实践

自OceanBase 4.3.3版本推出以来&#xff0c;向量检索的能力受到了很多客户的关注&#xff0c;也纷纷表达希望OB能拓展更多 多模数据库大模型 的AI应用实践。 在上篇文章 &#x1f449; OceanBase LLM&#xff0c;免费构建你的专属 AI 助手 &#xff0c;我们介绍了如何去搭建一…...

数据分析实战—鸢尾花数据分类

1.实战内容 (1) 加载鸢尾花数据集(iris.txt)并存到iris_df中,使用seaborn.lmplot寻找class&#xff08;种类&#xff09;项中的异常值&#xff0c;其他异常值也同时处理 。 import pandas as pd from sklearn.datasets import load_iris pd.set_option(display.max_columns, N…...

【专题】2024抖音电商母婴行业分析报告汇总PDF洞察(附原数据表)

原文链接&#xff1a;https://tecdat.cn/?p38651 在数字化浪潮的席卷下&#xff0c;抖音电商母婴行业正经历着深刻变革。当下&#xff0c;年轻一代父母崛起&#xff0c;特别是 24 至 30 岁以及 18 至 23 岁的群体成为抖音母婴行业兴趣人群的主力军。他们带来全新育儿理念&…...

堆栈粉碎的原理与预防攻击措施

1、堆栈粉碎的原理 “堆栈粉碎”&#xff08;stack smashing&#xff09;指的是在计算机程序中利用缓冲区溢出漏洞来修改或破坏函数调用栈的过程。以下是其基本原理&#xff1a; 缓冲区溢出&#xff1a;当程序接收输入数据时&#xff0c;如果没有适当的边界检查和验证&#x…...

Flutter组件————AppBar

AppBar 是 Flutter 中用于创建应用程序顶部栏的组件&#xff0c;它遵循 Material Design 规范。 参数&#xff1a; 参数名称类型描述titleWidget设置 AppBar 中的标题文本或自定义标题小部件。automaticallyImplyLeadingbool决定是否自动添加返回按钮&#xff08;如果页面不是…...

请问深度学习直接缝了别的模型,在论文中这种创新点应该如何描述呢?

作者&#xff1a;星辰 链接&#xff1a;https://www.zhihu.com/question/599461738/answer/3289126344 来源&#xff1a;知乎 著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。 作为散养硕士&#xff0c;我们希望能早早发小论文&#xff0c…...

微流控专题 | 微流体应用说明——藻酸盐微球生产简介

基于水凝胶的递送系统正被越来越多地应用于各个领域&#xff0c;包括封装、保护以及在制药、保健品、食品工业中释放生物活性物质&#xff0c;还用于细胞/细菌/微生物的培养与植入&#xff0c;以及生物研究中基于细胞的基因操作。 尺寸在 50m 范围内的高度单分散的藻酸盐微球 —…...

linux之kylin系统nginx的安装

一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源&#xff08;HTML/CSS/图片等&#xff09;&#xff0c;响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址&#xff0c;提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩

目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI

前一阵子在百度 AI 开发者大会上&#xff0c;看到基于小智 AI DIY 玩具的演示&#xff0c;感觉有点意思&#xff0c;想着自己也来试试。 如果只是想烧录现成的固件&#xff0c;乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外&#xff0c;还提供了基于网页版的 ESP LA…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南

&#x1f680; C extern 关键字深度解析&#xff1a;跨文件编程的终极指南 &#x1f4c5; 更新时间&#xff1a;2025年6月5日 &#x1f3f7;️ 标签&#xff1a;C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言&#x1f525;一、extern 是什么&#xff1f;&…...

springboot整合VUE之在线教育管理系统简介

可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生&#xff0c;小白用户&#xff0c;想学习知识的 有点基础&#xff0c;想要通过项…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)

推荐 github 项目:GeminiImageApp(图片生成方向&#xff0c;可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...

排序算法总结(C++)

目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指&#xff1a;同样大小的样本 **&#xff08;同样大小的数据&#xff09;**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...

解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist

现象&#xff1a; android studio报错&#xff1a; [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决&#xff1a; 不要动CMakeLists.…...

深入理解Optional:处理空指针异常

1. 使用Optional处理可能为空的集合 在Java开发中&#xff0c;集合判空是一个常见但容易出错的场景。传统方式虽然可行&#xff0c;但存在一些潜在问题&#xff1a; // 传统判空方式 if (!CollectionUtils.isEmpty(userInfoList)) {for (UserInfo userInfo : userInfoList) {…...