using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text.Json.Serialization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using WalkingTec.Mvvm.Core;
using WalkingTec.Mvvm.Core.Auth;
using WalkingTec.Mvvm.Core.Extensions;
using WalkingTec.Mvvm.Core.Support.Json;
namespace WalkingTec.Mvvm.Mvc
{
public abstract class BaseController : Controller, IBaseController
{
[JsonIgnore]
[BindNever]
public WTMContext Wtm { get; set; }
[JsonIgnore]
[BindNever]
public Configs ConfigInfo { get => Wtm?.ConfigInfo; }
[JsonIgnore]
[BindNever]
public GlobalData GlobaInfo { get => Wtm?.GlobaInfo; }
[JsonIgnore]
[BindNever]
public IUIService UIService { get => Wtm?.UIService; }
[JsonIgnore]
[BindNever]
public IDistributedCache Cache { get => Wtm?.Cache; }
[JsonIgnore]
[BindNever]
public string CurrentCS { get => Wtm?.CurrentCS; }
[JsonIgnore]
[BindNever]
public DBTypeEnum? CurrentDbType { get => Wtm?.CurrentDbType; }
[JsonIgnore]
[BindNever]
public string ParentWindowId { get => Wtm?.ParentWindowId; }
[JsonIgnore]
[BindNever]
public string CurrentWindowId { get => Wtm?.CurrentWindowId; }
[JsonIgnore]
[BindNever]
public string WindowIds { get => Wtm?.WindowIds; }
#region DataContext
[JsonIgnore]
[BindNever]
public IDataContext DC { get => Wtm?.DC; }
#endregion
#region URL
[JsonIgnore]
[BindNever]
public string BaseUrl { get => Wtm?.BaseUrl; }
#endregion
[JsonIgnore]
[BindNever]
public IStringLocalizer Localizer { get => Wtm?.Localizer; }
//-------------------------------------------方法------------------------------------//
//#region CreateVM
/////
///// Create a ViewModel, and pass Session,cache,dc...etc to the viewmodel
/////
///// The type of the viewmodel
///// If the viewmodel is a BaseCRUDVM, the data having this id will be fetched
///// If the viewmodel is a BatchVM, the BatchVM's Ids property will be assigned
///// properties of the viewmodel that you want to assign values
///// if true, the viewmodel will not call InitVM internally
///// ViewModel
//private BaseVM CreateVM(Type VMType, object Id = null, object[] Ids = null, Dictionary values = null, bool passInit = false)
//{
// //Use reflection to create viewmodel
// var ctor = VMType.GetConstructor(Type.EmptyTypes);
// BaseVM rv = ctor.Invoke(null) as BaseVM;
// rv.Wtm = this.Wtm;
// rv.FC = new Dictionary();
// rv.CreatorAssembly = this.GetType().AssemblyQualifiedName;
// rv.Controller = this;
// rv.ControllerName = this.GetType().FullName;
// if (HttpContext != null && HttpContext.Request != null)
// {
// try
// {
// if (Request.QueryString != QueryString.Empty)
// {
// foreach (var key in Request.Query.Keys)
// {
// if (rv.FC.Keys.Contains(key) == false)
// {
// rv.FC.Add(key, Request.Query[key]);
// }
// }
// }
// if (HttpContext.Request.HasFormContentType)
// {
// var f = HttpContext.Request.Form;
// foreach (var key in f.Keys)
// {
// if (rv.FC.Keys.Contains(key) == false)
// {
// rv.FC.Add(key, f[key]);
// }
// }
// }
// }
// catch { }
// }
// //try to set values to the viewmodel's matching properties
// if (values != null)
// {
// foreach (var v in values)
// {
// PropertyHelper.SetPropertyValue(rv, v.Key, v.Value, null, false);
// }
// }
// //if viewmodel is derrived from BaseCRUDVM<> and Id has value, call ViewModel's GetById method
// if (Id != null && rv is IBaseCRUDVM cvm)
// {
// cvm.SetEntityById(Id);
// }
// //if viewmodel is derrived from IBaseBatchVM<>,set ViewMode's Ids property,and init it's ListVM and EditModel properties
// if (rv is IBaseBatchVM temp)
// {
// temp.Ids = new string[] { };
// if (Ids != null)
// {
// var tempids = new List();
// foreach (var iid in Ids)
// {
// tempids.Add(iid.ToString());
// }
// temp.Ids = tempids.ToArray();
// }
// if (temp.ListVM != null)
// {
// temp.ListVM.CopyContext(rv);
// temp.ListVM.Ids = Ids == null ? new List() : temp.Ids.ToList();
// temp.ListVM.SearcherMode = ListVMSearchModeEnum.Batch;
// temp.ListVM.NeedPage = false;
// }
// if (temp.LinkedVM != null)
// {
// temp.LinkedVM.CopyContext(rv);
// }
// if (temp.ListVM != null)
// {
// //Remove the action columns from list
// temp.ListVM.OnAfterInitList += (self) =>
// {
// self.RemoveActionColumn();
// self.RemoveAction();
// if (temp.ErrorMessage.Count > 0)
// {
// self.AddErrorColumn();
// }
// };
// temp.ListVM.DoInitListVM();
// if (temp.ListVM.Searcher != null)
// {
// var searcher = temp.ListVM.Searcher;
// searcher.CopyContext(rv);
// if (passInit == false)
// {
// searcher.DoInit();
// }
// }
// }
// temp.LinkedVM?.DoInit();
// //temp.ListVM.DoSearch();
// }
// //if the viewmodel is a ListVM, Init it's searcher
// if (rv is IBasePagedListVM lvm)
// {
// var searcher = lvm.Searcher;
// searcher.CopyContext(rv);
// if (passInit == false)
// {
// searcher.DoInit();
// }
// lvm.DoInitListVM();
// }
// if (rv is IBaseImport tvm)
// {
// var template = tvm.Template;
// template.CopyContext(rv);
// template.DoInit();
// }
// //if passinit is not set, call the viewmodel's DoInit method
// if (passInit == false)
// {
// rv.DoInit();
// }
// return rv;
//}
/////
///// Create a ViewModel, and pass Session,cache,dc...etc to the viewmodel
/////
///// The type of the viewmodelThe type of the viewmodel
///// use Lambda to set viewmodel's properties,use && for multiply properties, for example Wtm.CreateVM(values: x=>x.Field1=='a' && x.Field2 == 'b'); will set viewmodel's Field1 to 'a' and Field2 to 'b'
///// if true, the viewmodel will not call InitVM internally
///// ViewModel
//public T Wtm.CreateVM(Expression> values = null, bool passInit = false) where T : BaseVM
//{
// SetValuesParser p = new SetValuesParser();
// var dir = p.Parse(values);
// return CreateVM(typeof(T), null, new object[] { }, dir, passInit) as T;
//}
/////
///// Create a ViewModel, and pass Session,cache,dc...etc to the viewmodel
/////
///// The type of the viewmodelThe type of the viewmodel
///// If the viewmodel is a BaseCRUDVM, the data having this id will be fetched
///// properties of the viewmodel that you want to assign values
///// if true, the viewmodel will not call InitVM internally
///// ViewModel
//public T Wtm.CreateVM(object Id, Expression> values = null, bool passInit = false) where T : BaseVM
//{
// SetValuesParser p = new SetValuesParser();
// var dir = p.Parse(values);
// return CreateVM(typeof(T), Id, new object[] { }, dir, passInit) as T;
//}
/////
///// Create a ViewModel, and pass Session,cache,dc...etc to the viewmodel
/////
///// The type of the viewmodelThe type of the viewmodel
///// If the viewmodel is a BatchVM, the BatchVM's Ids property will be assigned
///// use Lambda to set viewmodel's properties,use && for multiply properties, for example Wtm.CreateVM(values: x=>x.Field1=='a' && x.Field2 == 'b'); will set viewmodel's Field1 to 'a' and Field2 to 'b'
///// if true, the viewmodel will not call InitVM internally
///// ViewModel
//public T Wtm.CreateVM(object[] Ids, Expression> values = null, bool passInit = false) where T : BaseVM
//{
// SetValuesParser p = new SetValuesParser();
// var dir = p.Parse(values);
// return CreateVM(typeof(T), null, Ids, dir, passInit) as T;
//}
/////
///// Create a ViewModel, and pass Session,cache,dc...etc to the viewmodel
/////
///// The type of the viewmodelThe type of the viewmodel
///// If the viewmodel is a BatchVM, the BatchVM's Ids property will be assigned
///// use Lambda to set viewmodel's properties,use && for multiply properties, for example Wtm.CreateVM(values: x=>x.Field1=='a' && x.Field2 == 'b'); will set viewmodel's Field1 to 'a' and Field2 to 'b'
///// if true, the viewmodel will not call InitVM internally
///// ViewModel
//public T Wtm.CreateVM(Guid[] Ids, Expression> values = null, bool passInit = false) where T : BaseVM
//{
// SetValuesParser p = new SetValuesParser();
// var dir = p.Parse(values);
// return CreateVM(typeof(T), null, Ids.Cast