一起谈.NET技术,Silverlight + RIA Service的SUID的实例

简介:   1、准备工作  新建一个Silverlight Business Application,首先修改web.config,他自动生成的配置比较省略,我手动加入membership,role,profile的配置,我是ASP.NET MVC的项目中拷贝过来,直接用他的配置也可以,不过手动配置一下连接字符串LocalSqlServer,不然不能运行。

  1、准备工作

  新建一个Silverlight Business Application,首先修改web.config,他自动生成的配置比较省略,我手动加入membership,role,profile的配置,我是ASP.NET MVC的项目中拷贝过来,直接用他的配置也可以,不过手动配置一下连接字符串LocalSqlServer,不然不能运行。
 
  
< membership >
< providers >
< clear />
< add name ="AspNetSqlMembershipProvider" type ="System.Web.Security.SqlMembershipProvider" connectionStringName ="ApplicationServices" enablePasswordRetrieval ="false" enablePasswordReset ="true" requiresQuestionAndAnswer ="false" requiresUniqueEmail ="false" maxInvalidPasswordAttempts ="5" minRequiredPasswordLength ="6" minRequiredNonalphanumericCharacters ="0" passwordAttemptWindow ="10" applicationName ="/Vega" />
</ providers >
</ membership >
< profile >
< providers >
< clear />
< add name ="AspNetSqlProfileProvider" type ="System.Web.Profile.SqlProfileProvider" connectionStringName ="ApplicationServices" applicationName ="/" />
</ providers >
< properties >
< add name ="FriendlyName" />
</ properties >
</ profile >
< roleManager enabled ="true" >
< providers >
< clear />
< add name ="AspNetSqlRoleProvider" type ="System.Web.Security.SqlRoleProvider" connectionStringName ="ApplicationServices" applicationName ="/Vega" />
< add name ="AspNetWindowsTokenRoleProvider" type ="System.Web.Security.WindowsTokenRoleProvider" applicationName ="/" />
</ providers >
</ roleManager >

  我用的连接字符串名字是ApplicationServices,如果没安装ASP.NET的SQL数据,可以用Visual Studio 命令提示(2010) (在开始菜单的Visual Studio Tools里)调出命令提示符输入aspnet_regsql,调出“ASP.NET SQL SERVER安装向导”,而在运行-cmd里因为没有相关环境变量,是调不出安装向导的。

  新建一个ADO.NET实体数据模型。

  编译一下,然后新建Domain Service Class,勾上Course,如果不编译,那么数据实体模型是找不到的。我们需要Microsoft Silverlight 4 Toolkit,http://silverlight.codeplex.com/,没安装的话要先安装。

  2、用户登录和角色

  用户登录后往往要根据不用角色实现不同的功能导航,所以要修改/Views/Login/LoginStatus.xaml 这个登录状态的用户控件。首先加上管理员的功能面板。
 
   
< StackPanel x:Name ="adminControls" Style =" {StaticResource LoginPanelStyle} " >
<!-- welcomeText.Text property's binding is setup in code-behind -->
< TextBlock x:Name ="welcomeAdminText" Style =" {StaticResource WelcomeTextStyle} " VerticalAlignment ="Center" />
<!-- welcomeText.Text property's binding is setup in code-behind -->
< TextBlock Text =" | " Style =" {StaticResource SpacerStyle} " />
< HyperlinkButton TargetName ="ContentFrame" Content ="课程" VerticalAlignment ="Center" Foreground ="White" NavigateUri ="/Courses" />
< TextBlock Text =" | " Style =" {StaticResource SpacerStyle} " />
< HyperlinkButton TargetName ="ContentFrame" Content ="学员" VerticalAlignment ="Center" Foreground ="White" NavigateUri ="/Students" />
< TextBlock Text =" | " Style =" {StaticResource SpacerStyle} " />
< HyperlinkButton TargetName ="ContentFrame" Content ="排课" VerticalAlignment ="Center" Foreground ="White" NavigateUri ="/Schedules" />
< TextBlock Text =" | " Style =" {StaticResource SpacerStyle} " />
< Button x:Name ="adminLogoutButton" Content =" {Binding ApplicationStrings.LogOffButton, Source={StaticResource ResourceWrapper}} "
Click
="LogoutButton_Click"
Style
=" {StaticResource LoginRegisterLinkStyle} "
IsEnabled
=" {Binding Authentication.IsLoggingOut, Converter={StaticResource NotOperatorValueConverter}} " />
</ StackPanel >

  然后增加一个状态,叫做adminLoggedIn,在<vsm:VisualStateGroup x:Name="loginStates">代码短里加上adminLoggedIn的代码:

 
   
< vsm:VisualState x:Name ="adminLoggedIn" >
< Storyboard >
< ObjectAnimationUsingKeyFrames BeginTime ="00:00:00" Storyboard.TargetName ="logoutControls" Storyboard.TargetProperty ="(UIElement.Visibility)" >
< DiscreteObjectKeyFrame KeyTime ="00:00:00.0000000" >
< DiscreteObjectKeyFrame.Value >
< Visibility > Collapsed </ Visibility >
</ DiscreteObjectKeyFrame.Value >
</ DiscreteObjectKeyFrame >
</ ObjectAnimationUsingKeyFrames >
< ObjectAnimationUsingKeyFrames BeginTime ="00:00:00" Storyboard.TargetName ="loginControls" Storyboard.TargetProperty ="(UIElement.Visibility)" >
< DiscreteObjectKeyFrame KeyTime ="00:00:00.0000000" >
< DiscreteObjectKeyFrame.Value >
< Visibility > Collapsed </ Visibility >
</ DiscreteObjectKeyFrame.Value >
</ DiscreteObjectKeyFrame >
</ ObjectAnimationUsingKeyFrames >
</ Storyboard >
</ vsm:VisualState >

  不要忘了在其他的状态里加上把adminControls设置为不显示,只有在adminLoggedIn才显示管理员的功能导航。在构造器函数里加上welcomeAdminText的绑定:

 
   
public LoginStatus()
{
this .InitializeComponent();

this .welcomeText.SetBinding(TextBlock.TextProperty, WebContext.Current.CreateOneWayBinding( " User.DisplayName " , new StringFormatValueConverter(ApplicationStrings.WelcomeMessage)));
this .welcomeAdminText.SetBinding(TextBlock.TextProperty, WebContext.Current.CreateOneWayBinding( " User.DisplayName " , new StringFormatValueConverter(ApplicationStrings.WelcomeMessage)));
this .authService.LoggedIn += this .Authentication_LoggedIn;
this .authService.LoggedOut += this .Authentication_LoggedOut;
this .UpdateLoginState();
}

  修改UpdateLoginState函数,判断如果当前用户角色有admin,就显示admin的功能导航按钮:

 
   

private void UpdateLoginState()
{
if (WebContext.Current.User.IsAuthenticated)
{
VisualStateManager.GoToState(
this , (WebContext.Current.Authentication is WindowsAuthentication) ?
" windowsAuth " :
this .authService.User.IsInRole( " admin " ) ? " adminLoggedIn " : " loggedIn " , true );
}
else
{
VisualStateManager.GoToState(
this , " loggedOut " , true );
}
}

  通过ASP.NET 网站配置加上个admin角色和用户。

  好了,用户程序登录之后判断有admin角色,登录后就显示管理员的功能导航了。

  3、绑定数据源

  新建一个课程页面,在Page页面上加上DomainDataSource,一种办法是通过数据源窗口直接拽页面上去。
  他会自动帮你建立一个riaDataSource,还有DataGrid。
  在DataGrid外面加一个BusyIndicator(他是Silverlight Toolkit的控件之一),如果BusyIndicator得IsBusy为Ture,那么会出现一个等待的提示,并且BusyIndicator包含的内容不可操作,所以要把BusyIndicator的IsBusy和DomainDataSource的IsBusy绑定起来: IsBusy="{Binding IsBusy, ElementName=courseDomainDataSource}" 。
  DataGrid已经和DomainDataSource绑定了,IDE帮我们自动加上代码: ItemsSource="{Binding Data, ElementName=courseDomainDataSource}"。
  我还要加个简单搜索,通过课程名称模糊搜索,加一个TextBox。
 
   
< TextBlock Margin ="0,18,137,0" Text ="课程名称" FontSize ="12" HorizontalAlignment ="Right" Width ="48" Height ="23" VerticalAlignment ="Top" />
< TextBox Margin ="0,15,0,0" x:Name ="tbFilterCourseName" Height ="23" VerticalAlignment ="Top" HorizontalAlignment ="Right" Width ="120" />

  好了,然后拖一个DataPaper上去实现分页,也和DomainDataSource绑定上 Source="{Binding Data, ElementName=courseDomainDataSource}"。

  我们还要加上一排CheckBox用于多选,跟ASP.NET的GridView差不多,有一种DataGridTemplateColumn。CheckBox直接绑定实体对象,加上Tag="{Binding}",然后给CheckBox加上事件,在选中的把绑定的对象加入到一个List里,取消选中的时候在取出来,维护一个要删除对象的列表。

 
   
    private IList < Course > deletedCourses = new List < Course > ();

private void CheckBox_Checked( object sender, RoutedEventArgs e)
{
var checkBox
= sender as CheckBox;
this .deletedCourses.Add(checkBox.Tag as Course);
}

private void CheckBox_Unchecked( object sender, RoutedEventArgs e)
{
var checkBox
= sender as CheckBox;
this .deletedCourses.Remove(checkBox.Tag as Course);
}

  另外加一个删除全部的按钮。下面是BusyIndicator的全部代码:

 
   
< toolkit:BusyIndicator x:Name ="dataBusyIndicator" BusyContent ="载入课程数据" IsBusy =" {Binding IsBusy, ElementName=courseDomainDataSource} " >
< Grid >
< sdk:DataGrid AutoGenerateColumns ="False" ItemsSource =" {Binding Data, ElementName=courseDomainDataSource} " x:Name ="courseDataGrid" RowDetailsVisibilityMode ="VisibleWhenSelected" Margin ="30,47,0,33" IsReadOnly ="True" >
< sdk:DataGrid.Resources >
< DataTemplate x:Name ="CheckBoxCellTemplate" >
< CheckBox VerticalAlignment ="Center" HorizontalAlignment ="Center" Tag =" {Binding} " Checked ="CheckBox_Checked" Unchecked ="CheckBox_Unchecked" />
</ DataTemplate >
</ sdk:DataGrid.Resources >
< sdk:DataGrid.Columns >
< sdk:DataGridTemplateColumn CanUserReorder ="True" CanUserResize ="True" CanUserSort ="True" Width ="30" >
< sdk:DataGridTemplateColumn.CellEditingTemplate >
< StaticResource ResourceKey ="CheckBoxCellTemplate" />
</ sdk:DataGridTemplateColumn.CellEditingTemplate >
</ sdk:DataGridTemplateColumn >
< sdk:DataGridTextColumn x:Name ="courseNameColumn" Binding =" {Binding CourseName} " Header ="课程名称" Width ="SizeToCells" MinWidth ="70" />
< sdk:DataGridTextColumn x:Name ="titleColumn" Binding =" {Binding Title} " Header ="标题" Width ="SizeToCells" MinWidth ="100" />
< sdk:DataGridTextColumn x:Name ="providerColumn" Binding =" {Binding Provider} " Header ="内容提供商" Width ="SizeToCells" MinWidth ="70" />
< sdk:DataGridTextColumn x:Name ="teachersColumn" Binding =" {Binding Teachers} " Header ="主讲老师" Width ="SizeToCells" MinWidth ="70" />
< sdk:DataGridTextColumn x:Name ="publishDateColumn" Binding =" {Binding PublishDate} " Header ="发布时间" Width ="SizeToCells" MinWidth ="70" />
< sdk:DataGridTextColumn x:Name ="createTimeColumn" Binding =" {Binding CreateTime} " Header ="创建时间" Width ="SizeToCells" MinWidth ="70" />
</ sdk:DataGrid.Columns >
</ sdk:DataGrid >
< sdk:DataPager Margin ="30,444,0,10" x:Name ="dataPager1" PageSize ="10" Source =" {Binding Data, ElementName=courseDomainDataSource} " />
< TextBlock Margin ="0,18,137,0" Text ="课程名称" FontSize ="12" HorizontalAlignment ="Right" Width ="48" Height ="23" VerticalAlignment ="Top" />
< TextBox Margin ="0,15,0,0" x:Name ="tbFilterCourseName" Height ="23" VerticalAlignment ="Top" HorizontalAlignment ="Right" Width ="120" />
< Button Content ="删除所选" Height ="23" HorizontalAlignment ="Left" Margin ="30,15,0,0" Name ="button1" VerticalAlignment ="Top" Width ="75" Click ="button1_Click" />
</ Grid >
</ toolkit:BusyIndicator >

  然后,要把DomainDataSource.FilterDescriptors的筛选和我刚才加的TextBox绑定起来,这样就自动搜索了。

 
   
< riaControls:DomainDataSource AutoLoad ="True" Height ="0" LoadedData ="courseDomainDataSource_LoadedData" x:Name ="courseDomainDataSource" QueryName ="GetCoursesQuery" Width ="0" >
< riaControls:DomainDataSource.SortDescriptors >
< riaControls:SortDescriptor Direction ="Descending" PropertyPath ="CourseID" />
</ riaControls:DomainDataSource.SortDescriptors >
< riaControls:DomainDataSource.FilterDescriptors >
< riaControls:FilterDescriptor Operator ="Contains" PropertyPath ="CourseName" IgnoredValue ="" Value =" {Binding Text, ElementName=tbFilterCourseName} " />
</ riaControls:DomainDataSource.FilterDescriptors >
< riaControls:DomainDataSource.DomainContext >
< my1:VegaContext />
</ riaControls:DomainDataSource.DomainContext >
</ riaControls:DomainDataSource >

  如果不加FilterDescriptors,那么分页的时候报错,因为分页前必须Order,也可以在后台加一个默认排序:

 
   
public IQueryable < Course > GetCourses()
{
return this .ObjectContext.Courses.OrderByDescending < Course, int > (c => c.CourseID);
}

  效果如下:

  4、删除全部选择的项目。

  只需要逐个删除列表中的对象,然后DomainDataSource.SubmitChanges()就行了,很方便吧。

 
  
private void button1_Click( object sender, RoutedEventArgs e)
{
var result
= MessageBox.Show( " 确定删除该课程?删除后不可恢复! " , " 提示 " , MessageBoxButton.OKCancel);
if (result == MessageBoxResult.OK)
{
foreach (var course in this .deletedCourses)
{
this .courseDomainDataSource.DataView.Remove(course);
}
this .deletedCourses.Clear();
this .courseDomainDataSource.SubmitChanges();
}
}

  5、上传图片

  我需要一个上传图片的功能,首先需要后台支持,建一个DomainService专门负责上传。
 
    
[EnableClientAccess()]
public class UploadService : DomainService
{
public string Upload( byte [] stream, string extension)
{
var rootPath
= HttpContext.Current.Server.MapPath( " /Uploads " );
var datePath
= DateTime.Now.ToString( " yyyyMMdd " );
var dirPath
= Path.Combine(rootPath, datePath);
if ( ! Directory.Exists(dirPath))
{
Directory.CreateDirectory(dirPath);
}

var fileName
= Guid.NewGuid().ToString() + extension;
using (var fileStream = new FileStream(
Path.Combine(dirPath, fileName), FileMode.Create, FileAccess.Write))
{
fileStream.Write(stream,
0 , stream.Length);
fileStream.Flush();
fileStream.Close();
}
return " /Uploads/ " + datePath + " / " + fileName;
}
}

  代码很简单,就一个方法,将传过来的字节流保存到服务器上,然后返回为这个文件自动生成的路径。

  在服务器端建一个DomainService后,客户端会自动生成调用的代码,真的很方便。在客户端直接实例化一个Context就能用了 private UploadContext uploadContext = new UploadContext();在Silverlight建一个用户控件,专门负责上传和现实图片。

 
    
< UserControl xmlns:toolkit ="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit" x:Class ="Vega.Controls.SelecteImage"
xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d
="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc
="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable
="d"
d:DesignHeight
="300" d:DesignWidth ="400" >
< toolkit:BusyIndicator Name ="busyIndicator" >
< StackPanel Margin ="0" Orientation ="Horizontal" >
< Image HorizontalAlignment ="Left" VerticalAlignment ="Top" Source ="/Vega;component/Assets/Icons/picture2.png" MaxWidth ="150" MaxHeight ="150" Name ="image" />
< Button x:Name ="btnSelected" Content ="选择" Margin ="8,0,0,0" HorizontalAlignment ="Left" VerticalAlignment ="Bottom" Click ="btnSelected_Click" />
</ StackPanel >
</ toolkit:BusyIndicator >
</ UserControl >

  点击选择按钮,出现一个文件选择框,然后将选中文件上传到服务器,将返回的图片路径复制给Image控件:

 
   
private void btnSelected_Click( object sender, RoutedEventArgs e)
{
var fileDialog
= new OpenFileDialog()
{
Filter
= " 图片(.jpg)|*.jpg|图片(.jpeg)|*.jpeg|图片(.png)|*.png " ,
Multiselect
= false
};

var result
= fileDialog.ShowDialog();
if (result.HasValue && result.Value)
{
var stream
= fileDialog.File.OpenRead();
var bytes
= new byte [stream.Length];
stream.Read(bytes,
0 , bytes.Length);
this .busyIndicator.IsBusy = true ;
var op
= this .uploadContext.Upload(bytes, fileDialog.File.Extension);
op.Completed
+= (opSender, opE) => {
this .ImageUri = new Uri(op.Value, UriKind.Relative);
this .busyIndicator.IsBusy = false ;
};
}
}

  然后,我为控件加了一个属性,ImageUrl暴露给外面,提供绑定什么的功能。

 
   
public static readonly DependencyProperty ImageUriProperty = DependencyProperty.Register(
" ImageUri " ,
typeof (Uri),
typeof (SelecteImage),
new PropertyMetadata( null , new PropertyChangedCallback(OnImageUriChanged)));

private static void OnImageUriChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((SelecteImage)d).OnImageUriChanged(e);
}

protected virtual void OnImageUriChanged(DependencyPropertyChangedEventArgs e)
{
if (e.NewValue == null )
{
return ;
}
var uri
= (Uri)e.NewValue;
if ( ! uri.IsAbsoluteUri)
{
// Application.Current.Host.Source
var source = Application.Current.Host.Source;
uri
= new Uri(String.Format( " {0}://{1}:{2}{3} " ,source.Scheme,source.Host,source.Port,uri.OriginalString), UriKind.Absolute);
}
this .image.Source = new BitmapImage(uri);
}

public Uri ImageUri
{
get { return (Uri)GetValue(ImageUriProperty); }
set { SetValue(ImageUriProperty, value); }
}

  由于Silverlight中的相对Uri并不是只服务器上的资源,而是指XAP文件中的资源,所以我吧相对地址改为绝对地址。

  这个图片上传控件就OK乐。

  6、DataForm,实现新增和编辑

  首先拖上去一个DataForm控件,然后将DataForm和DomainService绑定起来。ItemsSource="{Binding ElementName=courseDomainDataSource, Path=Data}" CurrentItem="{Binding ElementName=courseDomainDataSource, Path=DataCurrentItem}",ItemSource绑定的是数据源,CurrentItem绑定时当前项目,如果不绑定ItemSource,只绑定CurrentItem的话就可以用CurrentItem="{Binding ElementName=courseDomainDataSource, Path=Data.CurrentItem}",不过如果这样的话,就只能编辑不能新增了。DataForm有很多按钮,比如导航的,编辑的,删除的,我只需需要增加和编辑,CommandButtonsVisibility="Add, Edit, Commit, Cancel",如果需要全部按钮的话CommandButtonsVisibility="All"就行了。
  另外,外面要重新设置DataForm的字段,把刚才做的上传图片的控件加进入,我需要编辑EditDataTemplate。
 
   
< toolkit:BusyIndicator Grid.Column ="1" x:Name ="formBusyIndicator" IsBusy =" {Binding IsBusy, ElementName=courseDomainDataSource} " />
< toolkit:DataForm Grid.Column ="1" Margin ="30,18,30,12" x:Name ="dfCourse" AutoEdit ="False" ItemsSource =" {Binding ElementName=courseDomainDataSource, Path=Data} " CurrentItem =" {Binding CurrentItem} " AutoGenerateFields ="False" AutoCommit ="False" EditEnded ="dfCourse_EditEnded" CommandButtonsVisibility ="Add, Edit, Commit, Cancel" >
< toolkit:DataForm.Resources >
< DataTemplate x:Key ="EditDataTemplate" >
< StackPanel >
< toolkit:DataField Label ="课程名称:" Margin ="0,0,0,8" >
< TextBox Text =" {Binding CourseName, Mode=TwoWay} " />
</ toolkit:DataField >
< toolkit:DataField Label ="标题:" Margin ="0,0,0,8" >
< TextBox Text =" {Binding Title, Mode=TwoWay} " />
</ toolkit:DataField >
< toolkit:DataField Label ="子标题:" Margin ="0,0,0,8" >
< TextBox Text =" {Binding SubTitle, Mode=TwoWay} " />
</ toolkit:DataField >
< toolkit:DataField Label ="短标题:" Margin ="0,0,0,8" >
< TextBox Text =" {Binding ShortTitle, Mode=TwoWay} " />
</ toolkit:DataField >
< toolkit:DataField Label ="主讲老师:" Margin ="0,0,0,8" >
< TextBox Text =" {Binding Teachers, Mode=TwoWay} " />
</ toolkit:DataField >
< toolkit:DataField Label ="提供商:" Margin ="0,0,0,8" >
< TextBox Text =" {Binding Provider, Mode=TwoWay} " />
</ toolkit:DataField >
< toolkit:DataField Label ="发布时间:" Margin ="0,0,0,8" >
< sdk:DatePicker SelectedDate =" {Binding PublishDate, Mode=TwoWay} " />
</ toolkit:DataField >
< toolkit:DataField Label ="概要:" Margin ="0,0,0,8" >
< TextBox Text =" {Binding Summary, Mode=TwoWay} " Height ="120" HorizontalScrollBarVisibility ="Auto" VerticalScrollBarVisibility ="Auto" AcceptsReturn ="True" />
</ toolkit:DataField >
< toolkit:DataField Label ="图片:" Margin ="0,0,0,8" >
< Vega_Controls:SelecteImage ImageUri =" {Binding ThumbUrl, Mode=TwoWay} " Margin ="0" d:LayoutOverrides ="Width, Height" />
</ toolkit:DataField >
</ StackPanel >
</ DataTemplate >
</ toolkit:DataForm.Resources >
< toolkit:DataForm.EditTemplate >
< StaticResource ResourceKey ="EditDataTemplate" />
</ toolkit:DataForm.EditTemplate >
</ toolkit:DataForm >
把SelectImage的ImageUrl属性和实体的属性绑定起来。
  效果图。
  最后加上事件,在完成编辑的时候提交更改就好了。
 
   
private void dfCourse_EditEnded( object sender, DataFormEditEndedEventArgs e)
{
if (e.EditAction == DataFormEditAction.Commit)
{
var course
= (Course) this .courseDataGrid.SelectedItem;
if (course.CourseID == 0 )
{
course.CreateTime
= DateTime.Now;
}
this .courseDomainDataSource.SubmitChanges();
}
}
  最后最后,加上验证。直接修改DomainService.matadata.cs和ASP.NET MVC2集成的验证方式一样,使用Attribute的方式:
 
    
[Display(Name = " 课程名称 " )]
[Required(ErrorMessage
= " 课程名称不能为空 " )]
public string CourseName { get ; set ; }
  不过效果好多了
目录
相关文章
|
28天前
|
自然语言处理 物联网 图形学
.NET 技术凭借其独特的优势和特性,为开发者们提供了一种高效、可靠且富有创造力的开发体验
本文深入探讨了.NET技术的独特优势及其在多个领域的应用,包括企业级应用、Web应用、桌面应用、移动应用和游戏开发。通过强大的工具集、高效的代码管理、跨平台支持及稳定的性能,.NET为开发者提供了高效、可靠的开发体验,并面对技术更新和竞争压力,不断创新发展。
45 7
|
27天前
|
开发框架 安全 .NET
在数字化时代,.NET 技术凭借跨平台兼容性、丰富的开发工具和框架、高效的性能及强大的安全稳定性,成为软件开发的重要支柱
在数字化时代,.NET 技术凭借跨平台兼容性、丰富的开发工具和框架、高效的性能及强大的安全稳定性,成为软件开发的重要支柱。它不仅加速了应用开发进程,提升了开发质量和可靠性,还促进了创新和业务发展,培养了专业人才和技术社区,为软件开发和数字化转型做出了重要贡献。
24 5
|
27天前
|
传感器 人工智能 供应链
.NET开发技术在数字化时代的创新作用,从高效的开发环境、强大的性能表现、丰富的库和框架资源等方面揭示了其关键优势。
本文深入探讨了.NET开发技术在数字化时代的创新作用,从高效的开发环境、强大的性能表现、丰富的库和框架资源等方面揭示了其关键优势。通过企业级应用、Web应用及移动应用的创新案例,展示了.NET在各领域的广泛应用和巨大潜力。展望未来,.NET将与新兴技术深度融合,拓展跨平台开发,推动云原生应用发展,持续创新。
28 4
|
27天前
|
开发框架 .NET C#
.NET 技术凭借高效开发环境、强大框架支持及跨平台特性,在软件开发中占据重要地位
.NET 技术凭借高效开发环境、强大框架支持及跨平台特性,在软件开发中占据重要地位。从企业应用到电子商务,再到移动开发,.NET 均展现出卓越性能,助力开发者提升效率与项目质量,推动行业持续发展。
27 4
|
27天前
|
机器学习/深度学习 人工智能 Cloud Native
在数字化时代,.NET 技术凭借其跨平台兼容性、丰富的类库和工具集以及卓越的性能与效率,成为软件开发的重要平台
在数字化时代,.NET 技术凭借其跨平台兼容性、丰富的类库和工具集以及卓越的性能与效率,成为软件开发的重要平台。本文深入解析 .NET 的核心优势,探讨其在企业级应用、Web 开发及移动应用等领域的应用案例,并展望未来在人工智能、云原生等方面的发展趋势。
33 3
|
27天前
|
敏捷开发 缓存 中间件
.NET技术的高效开发模式,涵盖面向对象编程、良好架构设计及高效代码编写与管理三大关键要素
本文深入探讨了.NET技术的高效开发模式,涵盖面向对象编程、良好架构设计及高效代码编写与管理三大关键要素,并通过企业级应用和Web应用开发的实践案例,展示了如何在实际项目中应用这些模式,旨在为开发者提供有益的参考和指导。
24 3
|
27天前
|
开发框架 安全 Java
.NET技术的独特魅力与优势,涵盖高效的开发体验、强大的性能表现、高度的可扩展性及丰富的生态系统等方面,展示了其在软件开发领域的核心竞争力
本文深入探讨了.NET技术的独特魅力与优势,涵盖高效的开发体验、强大的性能表现、高度的可扩展性及丰富的生态系统等方面,展示了其在软件开发领域的核心竞争力。.NET不仅支持跨平台开发,具备出色的安全性和稳定性,还能与多种技术无缝集成,为企业级应用提供全面支持。
29 3

热门文章

最新文章