siteMapFile
не является допустимым атрибутом XML в MvcSiteMapProvider (хотя вы можете использовать его как пользовательский атрибут), поэтому я не уверен, какой проводник вы выполняете для этого. Но в нижней строке есть нет функции, которая загружает «файлы детской карты сайта», и даже если бы это было так, это не помогло бы с вашей проблемой, потому что все узлы сразу загружаются в память. Реально на среднем сервере существует верхний предел около 10 000 - 15 000 узлов.
Проблема, которую вы описываете, является известной проблемой. В issue #258 есть несколько советов, которые могут или не помогут.
Мы работаем с new XML sitemap implementation, который позволит вам подключить файл Sitemap XML напрямую к источнику данных, который можно использовать для обхода этой проблемы (по крайней мере, в отношении XML-карты сайта). Эта реализация основана на потоках и имеет подкачку, которая может быть привязана непосредственно к источнику данных и будет плавно переходить на несколько таблиц, поэтому она очень эффективна. Однако, несмотря на то, что есть рабочий прототип, еще некоторое время от него делается в выпуск.
Если вам это нужно раньше, чем позже, вы можете взять прототип от this branch.
Вам понадобится код, чтобы подключить его к вашему приложению (это может быть изменено для официального выпуска). Я создал demo project here.
Application_Start
var registrar = new MvcSiteMapProvider.Web.Routing.XmlSitemapFeedRouteRegistrar();
registrar.RegisterRoutes(RouteTable.Routes, "XmlSitemap2");
XmlSitemap2Controller
using MvcSiteMapProvider.IO;
using MvcSiteMapProvider.Web.Mvc;
using MvcSiteMapProvider.Xml.Sitemap.Configuration;
using System.Web.Mvc;
public class XmlSitemap2Controller : Controller
{
private readonly IXmlSitemapFeedResultFactory xmlSitemapFeedResultFactory;
public XmlSitemap2Controller()
{
var builder = new XmlSitemapFeedStrategyBuilder();
var xmlSitemapFeedStrategy = builder
.SetupXmlSitemapProviderScan(scan => scan.IncludeAssembly(this.GetType().Assembly))
.AddNamedFeed("default", feed => feed.WithMaximumPageSize(5000).WithContent(content => content.Image().Video()))
.Create();
var outputCompressor = new HttpResponseStreamCompressor();
this.xmlSitemapFeedResultFactory = new XmlSitemapFeedResultFactory(xmlSitemapFeedStrategy, outputCompressor);
}
public ActionResult Index(int page = 0, string feedName = "")
{
var name = string.IsNullOrEmpty(feedName) ? "default" : feedName;
return this.xmlSitemapFeedResultFactory.Create(page, name);
}
}
IXmlSiteMapProvider
И вам потребуется 1 или более IXmlSitemapProvider
реализации. Для удобства существует базовый класс XmlSiteMapProviderBase
. Они похожи на создание контроллеров в MVC.
using MvcSiteMapProvider.Xml.Sitemap;
using MvcSiteMapProvider.Xml.Sitemap.Specialized;
using System;
using System.Linq;
public class CategoriesXmlSitemapProvider : XmlSitemapProviderBase, IDisposable
{
private EntityFramework.MyEntityContext db = new EntityFramework.MyEntityContext();
// This is optional. Don't override it if you don't want to use last modified date.
public override DateTime GetLastModifiedDate(string feedName, int skip, int take)
{
// Get the latest date in the specified page
return db.Category.OrderBy(x => x.Id).Skip(skip).Take(take).Max(c => c.LastUpdated);
}
public override int GetTotalRecordCount(string feedName)
{
// Get the total record count for all pages
return db.Category.Count();
}
public override void GetUrlEntries(IUrlEntryHelper helper)
{
// Do not call ToList() on the query. The idea is that we want to force
// EntityFramework to use a DataReader rather than loading all of the data
// at once into RAM.
var categories = db.Category
.OrderBy(x => x.Id)
.Skip(helper.Skip)
.Take(helper.Take);
foreach (var category in categories)
{
var entry = helper.BuildUrlEntry(string.Format("~/Category/{0}", category.Id))
.WithLastModifiedDate(category.LastUpdated)
.WithChangeFrequency(MvcSiteMapProvider.ChangeFrequency.Daily)
.AddContent(content => content.Image(string.Format("~/images/category-image-{0}.jpg", category.Id)).WithCaption(category.Name));
helper.SendUrlEntry(entry);
}
}
public void Dispose()
{
db.Dispose();
}
}
Обратите внимание, что в настоящее время не IXmlSiteMapProvider
реализация, которая считывает узлы от значения по умолчанию (или любой другой) SiteMap, но создавая один подобен тому, как показано выше, за исключением того, что запрос к SiteMap для узлов вместо база данных для записей.
В качестве альтернативы вы можете использовать сторонний XML-файл Sitemap. Хотя, почти все они настроены немасштабируемым способом для больших сайтов, и большинство из них оставляют это для вас, чтобы обрабатывать пейджинг. Если они не передают узлы, они не будут реально масштабироваться более чем на несколько тысяч URL-адресов.
Другие детали, которые вам могут потребоваться, это использовать технику forcing a match, чтобы уменьшить общее количество узлов в SiteMap. Если вы используете HTML-помощники Menu и/или SiteMap, вам нужно будет оставить все ваши узлы высокого уровня в одиночку. Но любой узел, который не появляется ни в одном, является хорошим кандидатом для этого. Реально, почти любой сайт, управляемый данными, может быть сведен к нескольким десяткам узлов с использованием этого метода, но имейте в виду, что каждый узел, который вынужден сопоставлять несколько маршрутов в SiteMap, означает, что отдельные URL-записи должны быть добавлены в карту XML-данных ,
Я предположил, что вы можете разрешать те атрибуты, которые имеет карта сайта по умолчанию, как в [здесь] (https://msdn.microsoft.com/en-us/library/ms178426 (v = vs.140) .aspx) , Спасибо за ссылки. Я попытаюсь использовать это приложение. FYI, я хочу иметь структуру, такую как [сайт сайта practo.com] (https://www.practo.com/sitemap.xml). Вы увидите, что они уменьшают загрузку страницы, используя расположение URL-адресов для самих файлов Sitemap. И если вы будете следовать одной из ссылок, вы увидите, что их те, кто несет вес сайта, имеют многочисленные узлы. Хотя, я не уверен, что они динамичны по своей природе или нет. – devP
ОК, я думаю, что неправильно понял. MvcSiteMapProvider в первую очередь предназначен для навигации по сайту, и по умолчанию он добавляет простую XML-карту для поисковых систем, которая считывает узлы из навигации SiteMap. Но если вам не нужны функции навигации, вы можете использовать прототип, как показано выше, и он автоматически разбивается и создает «дочерний файл» в значении «WithMaximumPageSize». Но FYI использует потоки выгружаемых данных, а не файлы. Пока вы не помещаете какие-либо HTML-помощники в свои представления, функции навигации не будут использоваться, но в настоящее время нет возможности полностью их отключить. – NightOwl888
Другими словами, если вы не используете навигационные функции, вам нужно сохранить файл Mvc.sitemap, но вам не нужно вставлять в него какие-либо узлы, кроме корневого узла. Вы также можете проигнорировать ссылку выше о «принуждении к совпадению» и совете о том, как вытащить узлы из SiteMap навигации, потому что это не относится к вашему делу. Но примеры кода действительно применимы. – NightOwl888