Эта функция рекурсивно сжимает дерево каталогов, сжимает файлы и записывает правильные относительные имена файлов в архиве. Архивные записи такие же, как и в zip -r output.zip source_dir
.
import os
import zipfile
def make_zipfile(output_filename, source_dir):
relroot = os.path.abspath(os.path.join(source_dir, os.pardir))
with zipfile.ZipFile(output_filename, "w", zipfile.ZIP_DEFLATED) as zip:
for root, dirs, files in os.walk(source_dir):
# add directory (needed for empty dirs)
zip.write(root, os.path.relpath(root, relroot))
for file in files:
filename = os.path.join(root, file)
if os.path.isfile(filename): # regular files only
arcname = os.path.join(os.path.relpath(root, relroot), file)
zip.write(filename, arcname)
Подобно реализации KingNestor, вы также можете сделать следующее, что облегчит вашу работу:
1) Напишите свою модель
public class MyUser{public String UserName{get; set;}}
2) добавьте маршрут в глобальный asax
routes.MapRoute(
"NameRouting",
"{name}",
new { controller = "PersonalPage", action = "Index", username="name" });
3) Сверните свой собственный связыватель модели, полученный из IModelBinder
public class CustomBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var request = controllerContext.HttpContext.Request;
var username = getUserNameFromDashedString(request["username"]);
MyUser user = new MyUser(username);
return user;
}
}
4) в своем действии:
public ActionResult Index([ModelBinder(typeof(CustomBinder))] MyUser usr)
{
ViewData["Welcome"] = "Viewing " + usr.Username;
return View();
}
Я не думаю, что это можно сделать. AFAIK ASP.NET MVC распознает параметры маршрутизации через символ «/».
Ваш формат, с другой стороны, идет как "{controller} -is- {id} - {action}", поэтому нет способа отличить контроллер от идентификатора и действия.
Я думаю, что использование символов «/» не влияет и не ухудшает SEO; он влияет только на удобочитаемость и сохранение URL-адреса человеком.
В любом случае, следующий URL-адрес возможен: http://www.abc.com/this-is-the-page-of/Peter
by добавление другого маршрута в метод Global.asax
RegisterRoutes:
routes.MapRoute(
"AnotherRoute",
"this-is-the-page-of/{id}",
new { controller = "PersonalPage", action = "Details", id = "" }
);
... при условии, что PersonalPageController
реализует метод Details ActionResult, указывающий на нужную страницу.
Я лично не стал бы предлагать такой маршрут, но если он соответствует вашим потребностям, вам нужно сделать что-то вроде:
Имейте следующий маршрут в вашем файле Global.asax:
routes.MapRoute(
"NameRouting",
"{name}",
new { controller = "PersonalPage", action = "routeByName" });
Затем в вашем «PersonalPageController» укажите следующий метод:
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult routeByName(string name)
{
switch (name)
{
case "this-is-peter-page": return View("PeterView");
case "this-is-john-page": return View("JohnView");
case Default: return View("NotFound");
}
}
Убедитесь, что у вас есть соответствующие представления: «PeterView», «JohnView» и «NotFound» в ваших Views / PersonalPage / .