cao死我好湿好紧好爽动态视屏|精选久久久久久久久久|中文无码精品一区二区三区四季|AAA国语精品刺激对白视频|

當(dāng)前位置:首頁(yè) > APP資源 > 正文內(nèi)容

webapp導(dǎo)航橫向滑動(dòng)(div橫向?qū)Ш綑?

APP資源11個(gè)月前 (03-11)394

[S2010]解析路由模式 (源代碼)

[S2011]利用多個(gè)中間件來(lái)構(gòu)建終結(jié)點(diǎn)處理器(源代碼)

[S2012]在參數(shù)上標(biāo)注特性來(lái)決定綁定的數(shù)據(jù)源(源代碼)

[S2013]默認(rèn)的參數(shù)綁定規(guī)則(源代碼)

[S2014]針對(duì)TryPar[Se方法的參數(shù)綁定(源代碼)

[S2015]針對(duì)BindA[Sync方法的參數(shù)綁定(源代碼)

[S2016]自定義路由約束(源代碼)

[S2010]解析路由模式 (源代碼)

[S2011]利用多個(gè)中間件來(lái)構(gòu)建終結(jié)點(diǎn)處理器(源代碼)

[S2012]在參數(shù)上標(biāo)注特性來(lái)決定綁定的數(shù)據(jù)源(源代碼)

[S2013]默認(rèn)的參數(shù)綁定規(guī)則(源代碼)

[S2014]針對(duì)TryPar[Se方法的參數(shù)綁定(源代碼)

[S2015]針對(duì)BindA[Sync方法的參數(shù)綁定(源代碼)

[S2016]自定義路由約束(源代碼)

下面我們通過(guò)一個(gè)簡(jiǎn)單的實(shí)例演示如何利用RoutePatternFactory對(duì)象解析指定的路由模板,并生成對(duì)應(yīng)的RoutePattern對(duì)象。我們定義了如下所示的Format方法將指定的RoutePattern對(duì)象格式化成一個(gè)字符串。

staticstringFormat( RoutePattern pattern)

{

varbuilder = newStringBuilder;

builder.AppendLine(

$"RawText: {pattern.RawText}" );

builder.AppendLine(

$"InboundPrecedence: {pattern.InboundPrecedence}" );

builder.AppendLine(

$"OutboundPrecedence: {pattern.OutboundPrecedence}" );

展開(kāi)全文

varsegments = pattern.PathSegments;

builder.AppendLine( "Segments");

foreach( varsegment insegments)

{

foreach( varpart insegment.Parts)

{

builder.AppendLine( $"\t {ToString(part)}" );

}

}

builder.AppendLine( "Defaults");

foreach( var@ defaultinpattern.Defaults)

{

builder.AppendLine(

$"\t {@ default.Key} = {@ default.Value} " );

}

builder.AppendLine( "ParameterPolicies ");

foreach( varpolicy inpattern.ParameterPolicies)

{

builder.AppendLine(

$"\t {policy.Key}= { string.Join( ',',policy.Value.Select(it = it.Content))} " );

}

builder.AppendLine( "RequiredValues");

foreach( varrequired inpattern.RequiredValues)

{

builder.AppendLine(

$"\t {required.Key}= {required.Value}" );

}

returnbuilder.ToString;

staticstringToString( RoutePatternPart part)

= part switch

{

RoutePatternLiteralPart literal

= $"Literal: {literal.Content}" ,

RoutePatternSeparatorPart separator

= $"Separator: {separator.Content}" ,

RoutePatternParameterPart parameter

= @ $"Parameter: Name = {parameter.Name}; Default = {parameter.Default}; IsOptional = { parameter.IsOptional}; IsCatchAll = { parameter.IsCatchAll};ParameterKind = { parameter.ParameterKind}" ,

_ = thrownewArgumentException( "Invalid RoutePatternPart.")

};

}

usingMicrosoft.AspNetCore.Routing.Patterns;

usingSystem.Text;

vartemplate = @"weather/{city:regex(^0\d{{2,3}}$)=010}/{days:int:range(1,4)=4}/{detailed?}";

varpattern = RoutePatternFactory.Parse(

pattern: template,

defaults: null,

parameterPolicies: null,

requiredValues: new{ city = "010", days = 4});

varapp = WebApplication.Create;

app.MapGet( "/", = Format(pattern));

app.Run;

如果利用瀏覽器訪問(wèn)啟動(dòng)后的應(yīng)用程序,回到得到如圖1所示結(jié)果,它結(jié)構(gòu)化地展示了路由模式的原始文本、出入棧路由匹配權(quán)重、每個(gè)段的組成、路由參數(shù)的默認(rèn)值和參數(shù)策略,以及生成URL必須提供的默認(rèn)參數(shù)值。

圖1 針對(duì)路由模式的解析

[S2011]利用多個(gè)中間件來(lái)構(gòu)建終結(jié)點(diǎn)處理器

如果某個(gè)終結(jié)點(diǎn)針對(duì)請(qǐng)求處理的邏輯相對(duì)復(fù)雜,需要多個(gè)中間件協(xié)同完成,我們可以調(diào)用IEndpointRouteBuilder 對(duì)象的CreateApplicationBuilder方法創(chuàng)建一個(gè)新的IApplicationBuilder對(duì)象,并將這些中間件注冊(cè)到這個(gè)該對(duì)象上,最后利用它這些中間件轉(zhuǎn)換成RequestDelegate委托。

varapp = WebApplication.Create;

IEndpointRouteBuilder routeBuilder = app;

app.MapGet( "/foobar", routeBuilder

.CreateApplicationBuilder

.Use(FooMiddleware)

.Use(BarMiddleware)

.Use(BazMiddleware)

.Build);

app.Run;

staticasyncTask FooMiddleware(

HttpContext context,RequestDelegate next )

{

awaitcontext.Response.WriteAsync( "Foo=");

awaitnext(context);

};

staticasyncTask BarMiddleware(

HttpContext context, RequestDelegate next )

{

awaitcontext.Response.WriteAsync( "Bar=");

awaitnext(context);

};

staticTask BazMiddleware(

HttpContext context, RequestDelegate next )

= context.Response.WriteAsync( "Baz");

上面的演示程序注冊(cè)了一個(gè)路徑模板為“foobar”的路由,并注冊(cè)了三個(gè)中間件來(lái)處理路由的請(qǐng)求。該演示程序啟動(dòng)之后,如果我們利用瀏覽器對(duì)路由地址“/foobar”發(fā)起請(qǐng)求,將會(huì)得到如圖2所示的輸出結(jié)果。呈現(xiàn)出來(lái)的字符串是通過(guò)注冊(cè)的三個(gè)中間件(FooMiddleware、BarMiddleware和BazMiddleware)輸出內(nèi)容組合而成。

圖2 輸出結(jié)果

[S2012]在參數(shù)上標(biāo)注特性來(lái)決定綁定的數(shù)據(jù)源

如下這個(gè)演示程序調(diào)用WebApplication對(duì)象的MapPost方法注冊(cè)了一個(gè)采用“/{foo}”作為模板的終結(jié)點(diǎn)。作為終結(jié)點(diǎn)處理器的委托指向靜態(tài)方法Handle,我們?yōu)檫@個(gè)方法定義了五個(gè)參數(shù),分別標(biāo)注了上述五個(gè)特性。我們將五個(gè)參數(shù)組合成一個(gè)匿名對(duì)象作為返回值。

usingMicrosoft.AspNetCore.Mvc;

varapp = WebApplication.Create;

app.MapPost( "/{foo}", Handle);

app.Run;

staticobjectHandle(

[FromRoute] stringfoo,

[FromQuery] intbar,

[FromHeader] stringhost,

[FromBody] Point point,

[FromServices] IHostEnvironment environment )

= new{ Foo = foo, Bar = bar, Host = host, Point = point,

Environment = environment.EnvironmentName };

publicclassPoint

{

publicintX { get; set; }

publicintY { get; set; }

}

程序啟動(dòng)之后,我們針對(duì)“http://localhost:5000/abc?bar=123”這個(gè)URL發(fā)送了一個(gè)POST請(qǐng)求,請(qǐng)求的主體內(nèi)容為一個(gè)Point對(duì)象序列化成生成的JSON。如下所示的是請(qǐng)求報(bào)文和響應(yīng)報(bào)文的內(nèi)容,可以看出Handle方法的foo和bar參數(shù)分別綁定的是路由參數(shù)“foo”和查詢字符串“bar”的值,參數(shù)host綁定的是請(qǐng)求的Host報(bào)頭,參數(shù)point是請(qǐng)求主體內(nèi)容反序列化的結(jié)果,參數(shù)environment則是由針對(duì)當(dāng)前請(qǐng)求的IServiceProvider對(duì)象提供的服務(wù)(S2012)。

POST http: //localhost:5000/abc?bar=123 HTTP/1.1

Content-Type: application/json

Host: localhost: 5000

Content-Length: 18

{ "x": 123, "y": 456}

HTTP/ 1.1200OK

Content-Type: application/json; charset=utf -8

Date: Sat, 06Nov 202111: 55: 54GMT

Server: Kestrel

Content-Length: 100

{ "foo": "abc", "bar": 123, "host": "localhost:5000", "point":{ "x": 123, "y": 456}, "environment": "Production"}

[S2013]默認(rèn)的參數(shù)綁定規(guī)則

如果請(qǐng)求處理器方法的參數(shù)沒(méi)有顯式指定綁定數(shù)據(jù)的來(lái)源,路由系統(tǒng)也能根據(jù)參數(shù)的類型盡可能地從當(dāng)前HttpContext上下文中提取相應(yīng)的內(nèi)容予以綁定。針對(duì)如下這幾個(gè)類型,對(duì)應(yīng)參數(shù)的綁定源是明確的。

HttpContext:綁定為當(dāng)前HttpContext上下文。

HttpRequest:綁定為當(dāng)前HttpContext上下文的Request屬性。

HttpResponse: 綁定為當(dāng)前HttpContext上下文的Response屬性。

ClaimsPrincipal: 綁定為當(dāng)前HttpContext上下文的User屬性。

CancellationToken: 綁定為當(dāng)前HttpContext上下文的RequestAborted屬性。

上述的綁定規(guī)則體現(xiàn)在如下演示程序的調(diào)試斷言中。這個(gè)演示實(shí)例還體現(xiàn)了另一個(gè)綁定規(guī)則,那就是只要當(dāng)前請(qǐng)求的IServiceProvider能夠提供對(duì)應(yīng)的服務(wù),對(duì)應(yīng)參數(shù)(“httpContextAccessor”)上標(biāo)注的FromSerrvicesAttribute特性不是必要的。但是倘若缺少對(duì)應(yīng)的服務(wù)注冊(cè),請(qǐng)求的主體內(nèi)容會(huì)一般會(huì)作為默認(rèn)的數(shù)據(jù)來(lái)源,所以FromSerrvicesAttribute特性最好還是顯式指定為好。對(duì)于我們演示的這個(gè)例子,如果我們將前面針對(duì)AddHttpContextAccessor方法的調(diào)用移除,對(duì)應(yīng)參數(shù)的綁定自然會(huì)失敗,但是錯(cuò)誤消息并不是我們希望看到的。

usingSystem.Diagnostics;

usingSystem.Security.Claims;

varbuilder = WebApplication.CreateBuilder;

builder.Services.AddHttpContextAccessor;

varapp = builder.Build;

app.MapGet( "/", Handle);

app.Run;

staticvoidHandle(

HttpContext httpContext,

HttpRequest request,

HttpResponse response,

ClaimsPrincipal user,

CancellationToken cancellationToken,

IHttpContextAccessor httpContextAccessor )

{

varcurrentContext = httpContextAccessor.HttpContext;

Debug.Assert(ReferenceEquals(httpContext, currentContext));

Debug.Assert(ReferenceEquals(request, currentContext.Request));

Debug.Assert(ReferenceEquals(response, currentContext.Response));

Debug.Assert(ReferenceEquals(user, currentContext.User));

Debug.Assert(cancellationToken == currentContext.RequestAborted);

}

[S2014]針對(duì)TryParse方法的參數(shù)綁定

如果我們?cè)谀硞€(gè)類型中定義了一個(gè)名為T(mén)ryParse的靜態(tài)方法將指定的字符串表達(dá)式轉(zhuǎn)換成當(dāng)前類型的實(shí)例,路由系統(tǒng)在對(duì)該類型的參數(shù)進(jìn)行綁定的時(shí)候會(huì)優(yōu)先從路由參數(shù)和查詢字符串中提取相應(yīng)的內(nèi)容,并通過(guò)調(diào)用這個(gè)方法生成綁定的參數(shù)。

varapp = WebApplication.Create;

app.MapGet( "/", (Point foobar) = foobar);

app.Run;

publicclassPoint

{

publicintX { get; set; }

publicintY { get; set; }

publicPoint( intx, inty )

{

X = x;

Y = y;

}

publicstaticboolTryParse(

stringexpression, outPoint? point )

{

varsplit = expression.Trim( '(', ')').Split( ',');

if(split.Length == 2

int.TryParse(split[ 0], outvarx)

int.TryParse(split[ 1], outvary))

{

point = newPoint(x, y);

returntrue;

}

point = null;

returnfalse;

}

}

上面的演示程序?yàn)樽远x的Point類型定義了一個(gè)靜態(tài)的TryParse方法使我們可以將一個(gè)以“(x,y)”形式定義的表達(dá)式轉(zhuǎn)換成Point對(duì)象。注冊(cè)的終結(jié)點(diǎn)處理器委托以該類型為參數(shù),指定的參數(shù)名稱為“foobar”。我們?cè)诎l(fā)送的請(qǐng)求中以查詢字符串的形式提供對(duì)應(yīng)的表達(dá)式“(123,456)”,從返回的內(nèi)容可以看出參數(shù)得到了成功綁定。

圖3 TryParse方法針對(duì)參數(shù)綁定的影響

[S2015]針對(duì)BindAsync方法的參數(shù)綁定

如果某種類型的參數(shù)具有特殊的綁定方式,我們還可以將具體的綁定實(shí)現(xiàn)在一個(gè)按照約定定義的BindAsync方法中。按照約定,這個(gè)BindAsync應(yīng)該定義成返回類型為ValueTaskT的靜態(tài)方法,它可以擁有一個(gè)類型為HttpContext的參數(shù),也可以額外提供一個(gè)ParameterInfo類型的參數(shù),這兩個(gè)參數(shù)分別與當(dāng)前HttpContext上下文和描述參數(shù)的ParameterInfo對(duì)象綁定。前面演示實(shí)例中為Point類型定義了一個(gè)TryParse方法可以替換成如下這個(gè) BingAsync方法。

publicclassPoint

{

publicintX { get; set; }

publicintY { get; set; }

publicPoint( intx, inty )

{

X = x;

Y = y;

}

publicstaticValueTaskPoint? BindAsync(

HttpContext httpContext,

ParameterInfo parameter)

{

Point? point = null;

varname = parameter.Name;

varvalue= httpContext.GetRouteData

.Values.TryGetValue(name!, outvarv)

? v

: httpContext.Request.Query[name!].SingleOrDefault;

if( valueisstringexpression)

{

varsplit = expression.Trim( '(', ')')?.Split( ',');

if(split?.Length == 2

int.TryParse(split[ 0], outvarx)

int.TryParse(split[ 1], outvary))

{

point = newPoint(x, y);

}

}

returnnewValueTaskPoint?(point);

}

}

[S2016]自定義路由約束

我們可以使用預(yù)定義的IRouteConstraint實(shí)現(xiàn)類型完成一些常用的約束,但是在一些對(duì)路由參數(shù)具有特定約束的應(yīng)用場(chǎng)景中,我們不得不創(chuàng)建自定義的約束類型。舉個(gè)例子,如果需要對(duì)資源提供針對(duì)多語(yǔ)言的支持,最好的方式是在請(qǐng)求的URL中提供對(duì)應(yīng)的Culture。為了確保包含在URL中的是一個(gè)合法有效的Culture,最好為此定義相應(yīng)的約束。下面將通過(guò)一個(gè)簡(jiǎn)單的實(shí)例來(lái)演示如何創(chuàng)建這樣一個(gè)用于驗(yàn)證Culture的自定義路由約束。我們創(chuàng)建了一個(gè)提供基于不同語(yǔ)言資源的API。我們將資源文件作為文本資源進(jìn)行存儲(chǔ),如圖4所示,我們創(chuàng)建了兩個(gè)資源文件 (Resources.resx和Resources.zh.resx),并定義了一個(gè)名為hello的文本資源條目。

圖4 存儲(chǔ)文本資源的兩個(gè)資源文件

如下演示程序中注冊(cè)了一個(gè)模板為“resources/{lang:culture}/{resourceName:required}”的終結(jié)點(diǎn)。路由參數(shù)“{resourceName}”表示資源條目的名稱(比如“hello”),另一個(gè)路由參數(shù)“{lang}”表示指定的語(yǔ)言,約束表達(dá)式名稱culture對(duì)應(yīng)的就是我們自定義的針對(duì)語(yǔ)言文化的約束類型CultureConstraint。因?yàn)檫@是一個(gè)自定義的路由約束,我們通過(guò)調(diào)用IServiceCollection接口的ConfigureTOptions方法將此約束采用的表達(dá)式名稱(“culture”)和CultureConstraint類型之間的映射關(guān)系添加到RouteOptions配置選項(xiàng)中。

usingApp;

usingApp.Properties;

usingSystem.Globalization;

varbuilder = WebApplication.CreateBuilder;

vartemplate = "resources/{lang:culture}/{resourceName:required}";

builder.Services.ConfigureRouteOptions(

options = options.ConstraintMap

.Add( "culture", typeof(CultureConstraint)));

varapp = builder.Build;

app.MapGet(template, GetResource);

app.Run;

staticIResult GetResource(

stringlang, stringresourceName )

{

CultureInfo.CurrentUICulture = newCultureInfo(lang);

vartext = Resources.ResourceManager.GetString(resourceName);

returnstring.IsNullOrEmpty(text)

? Results.NotFound

: Results.Content(text);

}

該終結(jié)點(diǎn)的處理方法GetResource定義了兩個(gè)參數(shù),我們知道它們會(huì)自動(dòng)綁定為同名的路由參數(shù)。由于系統(tǒng)自動(dòng)根據(jù)當(dāng)前線程的UICulture來(lái)選擇對(duì)應(yīng)的資源文件,我們對(duì)CultureInfo類型的CurrentUICulture靜態(tài)屬性進(jìn)行了設(shè)置。如果從資源文件將對(duì)應(yīng)的文本提取出來(lái),我們將創(chuàng)建一個(gè)ContentResult對(duì)象并返回。應(yīng)用啟動(dòng)之后,我們可以利用瀏覽器指定匹配的URL獲取對(duì)應(yīng)語(yǔ)言的文本。如圖5所示,如果指定一個(gè)不合法的語(yǔ)言(如“xx”),將會(huì)違反我們自定義的約束,此時(shí)就會(huì)得到一個(gè)狀態(tài)碼為“404 Not Found”的響應(yīng)。

圖5 采用相應(yīng)的URL得到某個(gè)資源針對(duì)某種語(yǔ)言的內(nèi)容

我們來(lái)看看針對(duì)語(yǔ)言文化的路由約束CultureConstraint究竟做了什么。如下面的代碼片段所示,我們?cè)贛atch方法中會(huì)試圖獲取作為語(yǔ)言文化內(nèi)容的路由參數(shù)值,如果存在這樣的路由參數(shù),就可以利用它創(chuàng)建一個(gè)CultureInfo對(duì)象。如果這個(gè)CultureInfo對(duì)象的EnglishName屬性名不以“Unknown Language”字符串作為前綴,我們就認(rèn)為指定的是合法的語(yǔ)言文件。

publicclassCultureConstraint: IRouteConstraint

{

publicboolMatch(

HttpContext? httpContext,

IRouter? route,

stringrouteKey,

RouteValueDictionary values,

RouteDirection routeDirection )

{

try

{

if(values.TryGetValue(routeKey, outvarvalue)

valueisnot null)

{

return! newCultureInfo(( string) value)

.EnglishName.StartsWith( "Unknown Language");

}

returnfalse;

webapp導(dǎo)航橫向滑動(dòng)(div橫向?qū)Ш綑?

}

catch

{

returnfalse;

}

}

}

掃描二維碼推送至手機(jī)訪問(wèn)。

版權(quán)聲明:本文由飛速云SEO網(wǎng)絡(luò)優(yōu)化推廣發(fā)布,如需轉(zhuǎn)載請(qǐng)注明出處。

本文鏈接:http://m.smallwaterjetsystem.com/post/95729.html

“webapp導(dǎo)航橫向滑動(dòng)(div橫向?qū)Ш綑?” 的相關(guān)文章

keepappcancel的簡(jiǎn)單介紹

keepappcancel的簡(jiǎn)單介紹

大部分的健身app提供健身訓(xùn)練計(jì)劃教練課程分享打卡社區(qū)等功能,一些健身軟件還提供記錄體重變化和飲食習(xí)慣分析等功能下面為大家提供了幾款方便實(shí)用的健身app,一起來(lái)看看吧!1KeepappKeep是一款目前非常受歡迎的移動(dòng)健身指導(dǎo)健身應(yīng)用,是。 根據(jù)查詢百度經(jīng)驗(yàn)得知,如果您不想繼續(xù)使用keep的會(huì)員服務(wù)...

網(wǎng)站類app(網(wǎng)站類型有哪些)

網(wǎng)站類app(網(wǎng)站類型有哪些)

1、2旅游app排行榜前十名3旅游的app有哪些4旅游攻略app排行榜前十名口碑最好的旅游軟件有哪些?口碑好的旅游軟件去哪兒攜程旅行窮游驢媽媽旅游螞蜂窩自由行一去哪兒去哪兒APP是國(guó)內(nèi)較大的一家旅游出行APP,上面有旅游。 2、2AppmakriOS,WindowsPhone,AndroidAppM...

做企業(yè)規(guī)劃的app(做企業(yè)規(guī)劃的步驟有哪些)

做企業(yè)規(guī)劃的app(做企業(yè)規(guī)劃的步驟有哪些)

十大室內(nèi)設(shè)計(jì)培訓(xùn)機(jī)構(gòu)排行榜 現(xiàn)在室內(nèi)設(shè)計(jì)的門(mén)檻越來(lái)越低,越來(lái)越考驗(yàn)設(shè)計(jì)師的能力,想要讓自己的技術(shù)精益求精,想在預(yù)計(jì)的時(shí)間內(nèi)學(xué)到真本領(lǐng),則選擇去正規(guī)學(xué)校進(jìn)行專業(yè)的學(xué)習(xí)。因?yàn)閷I(yè)的室內(nèi)培訓(xùn)學(xué)??梢越o學(xué)員進(jìn)行更加正規(guī)的培訓(xùn),比如杭州清風(fēng)室內(nèi)設(shè)計(jì)培訓(xùn)學(xué)院,專攻室內(nèi)設(shè)計(jì)一門(mén)專業(yè),老師都是股份責(zé)任制,培訓(xùn)班進(jìn)行...

優(yōu)秀的app首頁(yè)設(shè)計(jì)樣式(優(yōu)秀的app首頁(yè)設(shè)計(jì)樣式有哪些)

優(yōu)秀的app首頁(yè)設(shè)計(jì)樣式(優(yōu)秀的app首頁(yè)設(shè)計(jì)樣式有哪些)

UI設(shè)計(jì)必要知道的APP頁(yè)面 一起始頁(yè)launchscreen說(shuō)明程序啟動(dòng)時(shí)需要一定的反應(yīng)時(shí)間,在這段時(shí)間內(nèi)屏幕處于空置狀態(tài),為了讓用戶知道程序已經(jīng)啟動(dòng),現(xiàn)在只有一個(gè)加載過(guò)程,而且也是為了緩解用戶的焦慮,所以用圖片視頻代替;回答目前互聯(lián)發(fā)展勢(shì)頭越來(lái)越好,app應(yīng)用也是日益增多,因此app的引導(dǎo)頁(yè)設(shè)計(jì)...

app應(yīng)用開(kāi)發(fā)哪里做得好(各種app開(kāi)發(fā)的是學(xué)什么專業(yè)的)

app應(yīng)用開(kāi)發(fā)哪里做得好(各種app開(kāi)發(fā)的是學(xué)什么專業(yè)的)

北京華盛恒輝科技有限公司東軟集團(tuán)海輝軟件等都不錯(cuò)北京華盛恒輝科技有限公司hivekion是一家專注IT產(chǎn)品研發(fā)與服務(wù)的企業(yè),是全球領(lǐng)先的IT解決方案提供商?hào)|軟以軟件技術(shù)為核心,通過(guò)軟件與服務(wù)的結(jié)合,軟件與制造的。 其實(shí)市場(chǎng)上做APP的也有好多公司,但是每一個(gè)公司他主營(yíng)都不一樣,因?yàn)槊總€(gè)公司技術(shù)的專業(yè)...

app軟件開(kāi)發(fā)制作方案(app軟件開(kāi)發(fā)制作方案怎么做)

app軟件開(kāi)發(fā)制作方案(app軟件開(kāi)發(fā)制作方案怎么做)

從最初與客戶了解需求功能到最終的測(cè)試上線,一個(gè)完整的APP就被開(kāi)發(fā)出來(lái)了如同其他軟件開(kāi)發(fā)一樣,APP的整個(gè)生命周期都是需要緊扣用戶需求的,一旦脫離用戶需求,就極可能開(kāi)發(fā)出質(zhì)量差用戶不認(rèn)可的APP軟件,這是許多APP開(kāi)發(fā);就可以聯(lián)網(wǎng)進(jìn)行系統(tǒng)內(nèi)測(cè),參與人員包括項(xiàng)目需求方和開(kāi)發(fā)公司測(cè)試人員,可以下載并安裝...