我不知道这种 ASP.NET MVC 插件的存在。为了模仿它的功能,你可以编写一个自定义Authorize
属性:
public class LoadAndAuthorizeResourceAttribute : AuthorizeAttribute
{
private class ModelDescriptor
{
public string Name { get; set; }
public Type ModelType { get; set; }
}
private const string ModelTypeKey = "__ModelTypeKey__";
public override void OnAuthorization(AuthorizationContext filterContext)
{
var parameters = filterContext.ActionDescriptor.GetParameters();
if (parameters.Length > 0)
{
// store the type of the action parameter so that we could access it later
// in the AuthorizeCore method
filterContext.HttpContext.Items[ModelTypeKey] = new ModelDescriptor
{
Name = parameters[0].ParameterName,
ModelType = parameters[0].ParameterType,
};
}
base.OnAuthorization(filterContext);
}
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
var authorized = base.AuthorizeCore(httpContext);
if (!authorized)
{
// the user is not authenticated or authorized => no need to continue
return false;
}
// get the currently authenticated username
string username = httpContext.User.Identity.Name;
// get the id of the resource that he is trying to manipulate
// the id should be sent either as part of the query string or the routes
string id = httpContext.Request.RequestContext.RouteData.Values["id"] as string;
// get the action param type
var modelDescriptor = httpContext.Items[ModelTypeKey] as ModelDescriptor;
if (modelDescriptor == null)
{
throw new InvalidOperationException("The controller action that was decorated with this attribute must take a model as argument");
}
// now load the corresponding entity from your database given the
// username, id and type
object model = LoadModel(id, username, modelDescriptor.ModelType);
if (model == null)
{
// the model that satisfies the given criteria was not found in the database
return false;
}
httpContext.Request.RequestContext.RouteData.Values[modelDescriptor.Name] = model;
return true;
}
private object LoadModel(string id, string username, Type modelType)
{
// TODO: depending on how you are querying your database
// you should load the corresponding model here or return null
// if not found
throw new NotImplementedException();
}
}
现在你可以有一个用这个属性装饰的控制器动作:
[LoadAndAuthorizeResource]
public ActionResult Edit(Picture model)
{
... if we get that far the user is authorized to modify this model
}