asp.net mvc 实现记忆返回的功能

时间:2023-12-30 13:11:56

大体思路是在当前跳转链接追加一个参数memoryguid,以guid为key把查询query保存在cookie里,跳转的时候带走这个guid,回来的时候还带着,这样我们就能根据这个guid从cookie里获取我们的query了.思路确定了,根据实际的情况实现适合自己的代码就行了,我们index是主页,list是一个分部页,因此我定义了两个Attribute来搞定这件事,代码如下:

public class MemoryGoAttribute : ActionFilterAttribute
{ private readonly string _queryName; /// <summary>
/// 保存的查询实体的参数名称
/// </summary>
/// <param name="queryName"></param>
public MemoryGoAttribute(string queryName)
{
_queryName = queryName;
} public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var parameters = filterContext.ActionParameters;
if (!string.IsNullOrEmpty(_queryName))
{
object queryModel;
var flag = parameters.TryGetValue(_queryName, out queryModel);
if (flag)
{
//生成唯一标识 area controller action
//var uniqueId = Guid.NewGuid().ToString("N");
var uniqueId = filterContext.RouteData.DataTokens["area"].ToString()
+ filterContext.RouteData.Values["controller"].ToString()
+ filterContext.RouteData.Values["action"].ToString();
uniqueId = uniqueId.ToLower();
//将唯一标识添加到RouteData
filterContext.RouteData.Values.Add("memoryguid", uniqueId);
//存入cookie
var json = JsonConvert.SerializeObject(queryModel);
CookieHelper.ClearCookie(uniqueId);
var cookieHelper = CookieHelper.AddCookie(uniqueId, json, iDays: 0, iHours: 1);
}
}
base.OnActionExecuting(filterContext);
}
}

上边是在list上应用的特性,下边是应用在index上的特性

public class MemoryBackAttribute : ActionFilterAttribute
{
private readonly Type _queryType;
/// <summary>
/// 查询实体的类型
/// </summary>
/// <param name="queryType"></param>
public MemoryBackAttribute(Type queryType)
{
_queryType = queryType;
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var queryString = filterContext.HttpContext.Request.QueryString;
var uniqueId = queryString.Get("memoryguid");
if (!string.IsNullOrEmpty(uniqueId))
{
var json = CookieHelper.GetCookie(uniqueId.ToString());
if (!string.IsNullOrEmpty(json))
{ var dic = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
//dic to obj
var obj = Activator.CreateInstance(_queryType);
foreach (var prop in _queryType.GetProperties())
{
object value;
if (dic.TryGetValue(prop.Name, out value))
{
var type = prop.PropertyType;
//把数据转换成指定的类型,
prop.SetValue(obj, ChangeType(value, type), null);
}
} filterContext.Controller.ViewBag.MemoryObj = obj; //dic to url: key=value&key=value
var url = new StringBuilder();
dic.Keys.ToList().ForEach(key => { url.AppendFormat("{0}={1}&", key, dic[key]); }); filterContext.Controller.ViewBag.MemoryStr = url.ToString();
}
}
base.OnActionExecuting(filterContext);
} //转换成指定的类型
private object ChangeType(object obj, Type type)
{
//判断type类型是否为泛型,因为nullable是泛型类,
if (type.IsGenericType && type.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
{
//如果type为nullable类,声明一个NullableConverter类,该类提供从Nullable类到基础基元类型的转换
System.ComponentModel.NullableConverter nullableConverter = new System.ComponentModel.NullableConverter(type);
//将type转换为nullable对的基础基元类型
type = nullableConverter.UnderlyingType;
}
try
{
return Convert.ChangeType(obj, type, CultureInfo.InvariantCulture);
}
catch (Exception)
{
//不能转换
return null;
}
}
}

然后页面上的链接需要将我们的这个guid追加上去,因此我写了个UrlHelper的扩展方法

public static class UrlHelperExtension
{
public static string MemoryAction(this UrlHelper url, string actionName, string controllerName, object routeValues)
{
var originalUrl = url.Action(actionName, controllerName, routeValues); var concat = originalUrl.Contains("?") ? "&" : "?"; object uniqueId;
//从RouteData中获取
var routeData = url.RequestContext.RouteData.Values;
if (routeData.TryGetValue("memoryguid", out uniqueId))
{
return string.Format(originalUrl + "{0}memoryguid={1}", concat, uniqueId);
}
//从QueryString中获取
var queryString = url.RequestContext.HttpContext.Request.QueryString;
uniqueId = queryString.Get("memoryguid");
if (uniqueId != null)
{
return string.Format(originalUrl + "{0}memoryguid={1}", concat, uniqueId);
} return originalUrl;
}
}

这样就大功告成了,我的实际应用是这样的

[MemoryBack(typeof(QueryModel))]
public ActionResult Index()
{ } [MemoryGo("query")]
public PartialViewResult List(QueryModel query)
{ } <a href="Url.MemoryAction("action","controller",new{})" />

以上都是自己现在能想到,如果你们还有其它更好的思路和实现,请不要吝啬告诉我啊