到了2022年,闲鱼框架已经差不多要退出历史舞台了,但它给Flutter还是作出了巨大的贡献的,特别是中国的Flutter开发者。
这篇文章只是记录一下方便自己查阅,对于新学或者是新建项目者,还是应该考虑当前最主流的 GetX 和 Provider。

闲鱼文件结构
page:总页面,注册effect,reducer,component,adapter的功能,相关的配置都在此页面操作
state:这地方就是我们存放子模块变量的地方;初始化变量和接受上个页面参数,也在此处,是个很重要的模块
view:主要是我们写页面的模块
action:这是一个非常重要的模块,所有的事件都在此处定义和中转
effect:相关的业务逻辑,网络请求等等的“副作用”操作,都可以写在该模块
reducer:该模块主要是用来更新数据的,也可以写一些简单的逻辑或者和数据有关的逻辑操作

几句话搞懂他们的关系:
page 入口,所有功能在这初始化
state 可以理解为一个结构类,存放所有变量的,在各个页面之间共享
action 是一个枚举类,定义 action 的集合,当发起 action 的时候,根据 action 名字调用 reducer
reducer 处理发起的 action,并更新 state
view 负责视图层的构建,由 state 驱动
effect 处理所有副作用的函数,不做任何数据处理。分为两种,一种是对生命周期的回调,一种是对非处理数据事件的回调

错误内容:

提示:找不到导入的项目“C:\Program Files\Microsoft Visual
Studio\2022\Community\MSBuild\Microsoft\VisualStudio\v16.0\WebApplications\Microsoft.WebApplication.targets”。此外,已尝试在
$(MSBuildExtensionsPath32) - "C:\Program Files (x86)\MSBuild"
的回退搜索路径中找到“Microsoft\VisualStudio\v16.0\WebApplications\Microsoft.WebApplication.targets”。这些搜索路径在“C:\Users\Administrator\AppData\Local\Microsoft\VisualStudio\17.0_fa40166f\devenv.exe.config”中定义。确认
声明中的路径正确,并且该文件位于某个搜索路径中的磁盘上。

解决办法

修改 .csproj:

<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v16.0\WebApplications\Microsoft.WebApplication.targets" />

将路径中的 v16.0 改成:v$(VisualStudioVersion)

<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\WebApplications\Microsoft.WebApplication.targets" />

建类:ViewBagActionFilter

namespace MetaWeb.Core
{
    public class ViewBagActionFilter : ActionFilterAttribute
    {

        public ViewBagActionFilter()
        {
            //DI will inject what you need here
        }

        public override void OnResultExecuting(ResultExecutingContext context)
        {
            // for razor pages
            if (context.Controller is PageModel)
            {
                var controller = context.Controller as PageModel;
                controller?.ViewData.Add("Langs", Langs.instance());
                //also you have access to the httpcontext & route in controller.HttpContext & controller.RouteData
            }

            // for Razor Views
            if (context.Controller is Controller)
            {
                var controller = context.Controller as Controller;
                if(controller != null)
                    controller.ViewBag.Langs = Langs.instance();
            }

            base.OnResultExecuting(context);
        }
    }
}

Program.cs 中添加:

builder.Services.AddControllersWithViews(options => {
    options.Filters.Add<ViewBagActionFilter>();
});

新建处理类:

public class SlugifyParameterTransformer : IOutboundParameterTransformer
{
    public string? TransformOutbound(object? value)
    {
        if(value == null) return null;
        string? result = value.ToString();
        if(result == null) return null;

        return Regex.Replace(result, "([a-z])([A-Z])", "$1-$2").ToLower();
    }
}

路由注入 Program.cs :

builder.Services.AddRouting(options => {
    options.ConstraintMap["slugify"] = typeof(SlugifyParameterTransformer);
    options.LowercaseUrls = true;
});

路由:

app.MapControllerRoute(name: "default", pattern: "{controller:slugify=Home}/{action:slugify=Index}/{id?}");

builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(o =>
    {
        o.LoginPath = "/user/login";
    });

app.UseRouting();
app.UseAuthentication();    //增加登录验证,注意顺序
app.UseAuthorization();

登录验证成功后:

var claims = new List<Claim>()
{
    new Claim(ClaimTypes.Name, userInfo.Nickname),
    new Claim(ClaimTypes.NameIdentifier, userInfo.ID.ToString()),
    new Claim("Phone", userInfo.Phone)
};
var claimnsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);

//它会自动发送token给客户端。并生成cookies
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimnsIdentity), 
    new AuthenticationProperties
    {
        IsPersistent = true
    });

验证:

context.HttpContext.User.Identity.IsAuthenticated

取值:

string? Nickname = context.HttpContext.User.Identity.Name
string? uid = context.HttpContext.User.FindFirst(ClaimTypes.NameIdentifier)?.Value
string phone = context.HttpContext.User.FindFirst("Phone")?.Value ?? "18011112222";