public ProjectionEditViewModel GetProjectionViewModel(int id) { var viewModel = new ProjectionEditViewModel(); //Get Projection&QueryPart var projectionItem = _contentManager.Get(id, VersionOptions.Latest); var projectionPart = projectionItem.As <ProjectionPart>(); var queryId = projectionPart.Record.QueryPartRecord.Id; var queryPart = _contentManager.Get <QueryPart>(queryId, VersionOptions.Latest); var listViewPart = projectionItem.As <ListViewPart>(); viewModel.Id = id; viewModel.ItemContentType = listViewPart.ItemContentType; viewModel.DisplayName = listViewPart.As <TitlePart>().Title; viewModel.VisableTo = listViewPart.VisableTo; viewModel.PageRowCount = projectionPart.Record.ItemsPerPage; viewModel.IsDefault = listViewPart.IsDefault; //Get AllFields viewModel.Fields = GetFieldDescriptors(listViewPart.ItemContentType); var sortCriterion = queryPart.SortCriteria.FirstOrDefault(); if (sortCriterion != null) { var state = FormParametersHelper.ToDynamic(sortCriterion.State); viewModel.SortedBy = state.Type; var ascending = (bool)state.Sort; viewModel.SortMode = ascending ? "Asc" : "Desc"; } return(viewModel); }
public IEnumerable <JObject> Get(string id) { var pluralService = PluralizationService.CreateService(new CultureInfo("en-US")); if (pluralService.IsPlural(id)) { id = pluralService.Singularize(id); } var entityFilters = new List <JObject>(); var entityFilterRecords = _entityFilterRepository.Table.Where(x => x.EntityName == id); foreach (var entityFilterRecord in entityFilterRecords) { var filterGroup = new JObject(); filterGroup["Id"] = entityFilterRecord.Id; filterGroup["FilterGroupId"] = entityFilterRecord.FilterGroupRecord.Id; filterGroup["Title"] = entityFilterRecord.Title; var filters = new JArray(); foreach (var filterRecord in entityFilterRecord.FilterGroupRecord.Filters) { var filter = new JObject(); filter["Type"] = filterRecord.Type; filter["State"] = FormParametersHelper.ToDynamic(filterRecord.State); filters.Add(filter); } filterGroup["Filters"] = filters; entityFilters.Add(filterGroup); } return(entityFilters); }
public IHqlQuery GetCombinedContentQuery(int[] queryIds, Dictionary <string, object> tokens = null, string[] contentTypesToFilter = null) { var availableFilters = DescribeFilters().ToList(); IEnumerable <ContentItem> contentItems = new List <ContentItem>(); IHqlQuery contentQuery = null; contentQuery = _contentManager.HqlQuery(); // Siccome sono in una Query Definita dallo User, devo anche filtrare per ContentType "CommunicationContact" if (contentTypesToFilter != null) { contentQuery = contentQuery.ForType(contentTypesToFilter); } foreach (var queryId in queryIds) { var queryRecord = _queryRepository.Get(queryId); // Per un bug di Orchard non si devono usare i gruppi, quindi prendo solo il primo gruppo var group = queryRecord.FilterGroups[0]; // fatto da HERMES if (tokens == null) { tokens = new Dictionary <string, object>(); } //FINE // iterate over each filter to apply the alterations to the query object foreach (var filter in group.Filters) { var tokenizedState = _tokenizer.Replace(filter.State, tokens /*new Dictionary<string, object>()*/); var filterContext = new FilterContext { Query = contentQuery, State = FormParametersHelper.ToDynamic(tokenizedState), QueryPartRecord = queryRecord }; string category = filter.Category; string type = filter.Type; // look for the specific filter component var descriptor = availableFilters .SelectMany(x => x.Descriptors) .FirstOrDefault(x => x.Category == category && x.Type == type); // ignore unfound descriptors if (descriptor == null) { continue; } // apply alteration descriptor.Filter(filterContext); contentQuery = filterContext.Query; } } // Filtro sullo stato di pubblicato contentQuery = contentQuery.ForVersion(VersionOptions.Published); return(contentQuery); }
public IEnumerable <ContentItem> GetContentItems(int queryId, IContent container, int skip = 0, int count = 0) { this.availableSortCriteria = this.DescribeSortCriteria().ToList(); var queryRecord = _queryRepository.Get(queryId); if (queryRecord == null) { throw new ArgumentException("queryId"); } var contentItems = new List <ContentItem>(); // aggregate the result for each group query foreach (var contentQuery in GetContentQueries(queryRecord, queryRecord.SortCriteria, container)) { contentItems.AddRange(contentQuery.Slice(skip, count)); } if (queryRecord.FilterGroups.Count <= 1) { return(contentItems); } // re-executing the sorting with the cumulated groups var ids = contentItems.Select(c => c.Id).ToArray(); if (ids.Length == 0) { return(Enumerable.Empty <ContentItem>()); } var groupQuery = _contentManager.HqlQuery().Where(alias => alias.Named("ci"), x => x.InG("Id", ids)); // iterate over each sort criteria to apply the alterations to the query object var sortModel = GetSortModelFromRequest(this.requestContext); if (sortModel != null) { dynamic state = new Composite(); state.Sort = sortModel.Direction; groupQuery = this.AddSortCriterion(sortModel.Category, sortModel.Type, state, groupQuery); } else { foreach (var sortCriterion in queryRecord.SortCriteria) { var state = FormParametersHelper.ToDynamic(sortCriterion.State); groupQuery = this.AddSortCriterion(sortCriterion.Category, sortCriterion.Type, state, groupQuery); } } return(groupQuery.Slice(skip, count)); }
public IEnumerable <IHqlQuery> GetContentQueries(QueryPartRecord queryRecord, IEnumerable <SortCriterionRecord> sortCriteria, IContent container) { var availableSortCriteria = DescribeSortCriteria().ToList(); Dictionary <string, object> filtersDictionary = new Dictionary <string, object>(); if (container != null) { filtersDictionary.Add("Content", container); } // pre-executing all groups foreach (var group in queryRecord.FilterGroups) { var contentQuery = _contentManager.HqlQuery().ForVersion(VersionOptions.Published); // iterate over each filter to apply the alterations to the query object foreach (var filter in group.Filters) { var tokenizedState = _tokenizer.Replace(filter.State, filtersDictionary); dynamic state = FormParametersHelper.ToDynamic(tokenizedState); contentQuery = this.ApplyFilter(contentQuery, filter.Category, filter.Type, state); } var sortModel = GetSortModelFromRequest(this.requestContext); if (sortModel != null) { dynamic state = new Composite(); state.Sort = sortModel.Direction; contentQuery = this.AddSortCriterion(sortModel.Category, sortModel.Type, state, contentQuery); } else if (sortCriteria != null) { // iterate over each sort criteria to apply the alternatives to the query object foreach (var sortCriterion in sortCriteria) { var state = FormParametersHelper.ToDynamic(sortCriterion.State); contentQuery = this.AddSortCriterion(sortCriterion.Category, sortCriterion.Type, state, contentQuery); } } yield return(contentQuery); } }
public ActionResult Edit(int id) { if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to edit media profiles"))) { return(new HttpUnauthorizedResult()); } var profile = _profileService.GetImageProfile(id); var viewModel = new AdminEditViewModel { Id = profile.Id, Name = profile.Name }; var filterEntries = new List <FilterEntry>(); var allFilters = _imageProcessingManager.DescribeFilters().SelectMany(x => x.Descriptors).ToList(); foreach (var filter in profile.Filters.OrderBy(f => f.Position)) { var category = filter.Category; var type = filter.Type; var f = allFilters.FirstOrDefault(x => category == x.Category && type == x.Type); if (f != null) { filterEntries.Add( new FilterEntry { Category = f.Category, Type = f.Type, FilterRecordId = filter.Id, DisplayText = String.IsNullOrWhiteSpace(filter.Description) ? f.Display(new FilterContext { State = FormParametersHelper.ToDynamic(filter.State) }).Text : filter.Description }); } } viewModel.Filters = filterEntries; return(View(viewModel)); }
public ActionResult Edit(int id) { if (!Services.Authorizer.Authorize(Permissions.ManageQueries, T("Not authorized to manage queries"))) { return(new HttpUnauthorizedResult()); } var layoutRecord = _repository.Get(id); if (layoutRecord == null) { return(HttpNotFound()); } var layoutDescriptor = _projectionManager.DescribeLayouts().SelectMany(x => x.Descriptors).FirstOrDefault(x => x.Category == layoutRecord.Category && x.Type == layoutRecord.Type); // Build the form, and let external components alter it. var form = _formManager.Build(layoutDescriptor.Form) ?? Services.New.EmptyForm(); var viewModel = new LayoutEditViewModel { Id = id, QueryId = layoutRecord.QueryPartRecord.Id, Category = layoutDescriptor.Category, Type = layoutDescriptor.Type, Description = layoutRecord.Description, Display = layoutRecord.Display, DisplayType = String.IsNullOrWhiteSpace(layoutRecord.DisplayType) ? "Summary" : layoutRecord.DisplayType, Layout = layoutDescriptor, Form = form, GroupPropertyId = layoutRecord.GroupProperty == null ? 0 : layoutRecord.GroupProperty.Id }; // Bind form with existing values. var parameters = FormParametersHelper.FromString(layoutRecord.State); _formManager.Bind(form, new DictionaryValueProvider <string>(parameters, CultureInfo.InvariantCulture)); #region Load Fields var fieldEntries = new List <PropertyEntry>(); var allFields = _projectionManager.DescribeProperties().SelectMany(x => x.Descriptors); foreach (var field in layoutRecord.Properties) { var fieldCategory = field.Category; var fieldType = field.Type; var f = allFields.FirstOrDefault(x => fieldCategory == x.Category && fieldType == x.Type); if (f != null) { fieldEntries.Add( new PropertyEntry { Category = f.Category, Type = f.Type, PropertyRecordId = field.Id, DisplayText = String.IsNullOrWhiteSpace(field.Description) ? f.Display(new PropertyContext { State = FormParametersHelper.ToDynamic(field.State) }).Text : field.Description, Position = field.Position }); } } viewModel.Properties = fieldEntries.OrderBy(f => f.Position); #endregion return(View(viewModel)); }
public IEnumerable <IHqlQuery> GetContentQueries(QueryPartRecord queryRecord, IEnumerable <SortCriterionRecord> sortCriteria, Dictionary <string, object> tokens) { var availableFilters = DescribeFilters().ToList(); var availableSortCriteria = DescribeSortCriteria().ToList(); if (tokens == null) { tokens = new Dictionary <string, object>(); } // pre-executing all groups foreach (var group in queryRecord.FilterGroups) { var contentQuery = _contentManager.HqlQuery().ForVersion(VersionOptions.Published); // iterate over each filter to apply the alterations to the query object foreach (var filter in group.Filters) { var tokenizedState = _tokenizer.Replace(filter.State, tokens); var filterContext = new FilterContext { Query = contentQuery, State = FormParametersHelper.ToDynamic(tokenizedState) }; string category = filter.Category; string type = filter.Type; // look for the specific filter component var descriptor = availableFilters .SelectMany(x => x.Descriptors) .FirstOrDefault(x => x.Category == category && x.Type == type); // ignore unfound descriptors if (descriptor == null) { continue; } // apply alteration descriptor.Filter(filterContext); contentQuery = filterContext.Query; } // iterate over each sort criteria to apply the alterations to the query object foreach (var sortCriterion in sortCriteria.OrderBy(s => s.Position)) { var sortCriterionContext = new SortCriterionContext { Query = contentQuery, State = FormParametersHelper.ToDynamic(sortCriterion.State) }; string category = sortCriterion.Category; string type = sortCriterion.Type; // look for the specific filter component var descriptor = availableSortCriteria .SelectMany(x => x.Descriptors) .FirstOrDefault(x => x.Category == category && x.Type == type); // ignore unfound descriptors if (descriptor == null) { continue; } // apply alteration descriptor.Sort(sortCriterionContext); contentQuery = sortCriterionContext.Query; } yield return(contentQuery); } }
public IEnumerable <ContentItem> GetContentItems(int queryId, ContentPart part, int skip = 0, int count = 0) { var availableSortCriteria = DescribeSortCriteria().ToList(); var queryRecord = _queryRepository.Get(queryId); if (queryRecord == null) { throw new ArgumentException("queryId"); } var contentItems = new List <ContentItem>(); // prepares tokens Dictionary <string, object> tokens = new Dictionary <string, object>(); if (part != null) { tokens.Add("Content", part.ContentItem); } // aggregate the result for each group query foreach (var contentQuery in GetContentQueries(queryRecord, queryRecord.SortCriteria.OrderBy(sc => sc.Position), tokens)) { contentItems.AddRange(contentQuery.Slice(skip, count)); } if (queryRecord.FilterGroups.Count <= 1) { return(contentItems); } // re-executing the sorting with the cumulated groups var ids = contentItems.Select(c => c.Id).ToArray(); if (ids.Length == 0) { return(Enumerable.Empty <ContentItem>()); } var groupQuery = _contentManager.HqlQuery().Where(alias => alias.Named("ci"), x => x.InG("Id", ids)); // iterate over each sort criteria to apply the alterations to the query object foreach (var sortCriterion in queryRecord.SortCriteria.OrderBy(s => s.Position)) { var sortCriterionContext = new SortCriterionContext { Query = groupQuery, State = FormParametersHelper.ToDynamic(sortCriterion.State) }; string category = sortCriterion.Category; string type = sortCriterion.Type; // look for the specific filter component var descriptor = availableSortCriteria.SelectMany(x => x.Descriptors).FirstOrDefault(x => x.Category == category && x.Type == type); // ignore unfound descriptors if (descriptor == null) { continue; } // apply alteration descriptor.Sort(sortCriterionContext); groupQuery = sortCriterionContext.Query; } return(groupQuery.Slice(skip, count)); }
public void ApplyFilter(FilterContext context) { var queryId = (string)context.State.QueryId; int id = 0; if (!string.IsNullOrWhiteSpace(queryId) && int.TryParse(queryId, out id)) { var queryPart = _contentManager.Get <QueryPart>(id); if (queryPart != null && allFilterProviders.Any()) { var recursionGuardString = (string)context.State.OtherQueriesFilterRecursionGuard ?? ""; var recursionGuard = recursionGuardString .Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries) .Select(int.Parse) .ToList(); // prevent processing an "inner" query if it's the same as the "outer" query recursionGuard.Add(context.QueryPartRecord.Id); if (!recursionGuard.Contains(queryPart.Id)) { // we haven't processed this filter before in this query // prevent processing the same filter recursively several times recursionGuard.Add(queryPart.Id); recursionGuardString = string.Join(",", recursionGuard.Select(i => i.ToString())); var queryRecord = queryPart.Record; // pretend we are a ProjectionManager var tokens = context.Tokens; foreach (var group in queryRecord.FilterGroups) { var contentQuery = context.Query; foreach (var filter in group.Filters) { var tokenizedState = _tokenizer.Replace(filter.State, tokens); var dynState = FormParametersHelper.ToDynamic(tokenizedState); dynState.OtherQueriesFilterRecursionGuard = recursionGuardString; var innerContext = new FilterContext { Query = contentQuery, State = dynState, QueryPartRecord = queryRecord, Tokens = tokens }; string category = filter.Category; string type = filter.Type; var descriptor = AllDescriptors() .FirstOrDefault(d => d.Category == category && d.Type == type); if (descriptor == null) { continue; } // Apply filters descriptor.Filter(innerContext); contentQuery = innerContext.Query; } context.Query = contentQuery; } } else { Logger.Warning(T("Prevent recursive execution of filter with Id {0}.", queryPart.Id).Text); } } } }
protected override void OnDisplaying(Projection element, ElementDisplayingContext context) { var queryId = element.QueryId; var layoutId = element.LayoutId; var query = queryId != null?_contentManager.Get <QueryPart>(queryId.Value) : default(QueryPart); var emptyContentItemsList = Enumerable.Empty <ContentManagement.ContentItem>(); context.ElementShape.ContentItems = emptyContentItemsList; context.ElementShape.BuildShapes = (Func <string, IEnumerable <dynamic> >)(displayType => emptyContentItemsList.Select(x => _contentManager.BuildDisplay(x, displayType))); if (query == null || layoutId == null) { return; } // Retrieving paging parameters. var queryString = _services.WorkContext.HttpContext.Request.QueryString; var pageKey = String.IsNullOrWhiteSpace(element.PagerSuffix) ? "page" : "page-" + element.PagerSuffix; var page = 0; // Default page size. var pageSize = element.ItemsToDisplay; // Don't try to page if not necessary. if (element.DisplayPager && queryString.AllKeys.Contains(pageKey)) { Int32.TryParse(queryString[pageKey], out page); } // If 0, then assume "All", limit to 128 by default. if (pageSize == 128) { pageSize = Int32.MaxValue; } // If pageSize is provided on the query string, ensure it is compatible within allowed limits. var pageSizeKey = "pageSize" + element.PagerSuffix; if (queryString.AllKeys.Contains(pageSizeKey)) { int qsPageSize; if (Int32.TryParse(queryString[pageSizeKey], out qsPageSize)) { if (element.MaxItems == 0 || qsPageSize <= element.MaxItems) { pageSize = qsPageSize; } } } var pager = new Pager(_services.WorkContext.CurrentSite, page, pageSize); // TODO: Investigate this further and see if it makes sense to implement for a Projection Element. //// Generates a link to the RSS feed for this term. //var metaData = _services.ContentManager.GetItemMetadata(part.ContentItem); //_feedManager.Register(metaData.DisplayText, "rss", new RouteValueDictionary { { "projection", part.Id } }); // Execute the query. var contentItems = _projectionManager.GetContentItems(query.Id, pager.GetStartIndex() + element.Skip, pager.PageSize).ToList(); context.ElementShape.ContentItems = contentItems; context.ElementShape.BuildShapes = (Func <string, IEnumerable <dynamic> >)(displayType => contentItems.Select(x => _contentManager.BuildDisplay(x, displayType))); // TODO: Figure out if we need this for a Projection Element, and if so, how. //// Sanity check so that content items with ProjectionPart can't be added here, or it will result in an infinite loop. //contentItems = contentItems.Where(x => !x.Has<ProjectionPart>()).ToList(); // Applying layout. var layout = layoutId != null?_layoutRepository.Get(layoutId.Value) : default(LayoutRecord); var layoutDescriptor = layout == null ? null : _projectionManager.DescribeLayouts().SelectMany(x => x.Descriptors).FirstOrDefault(x => x.Category == layout.Category && x.Type == layout.Type); // Create pager shape. if (element.DisplayPager) { var contentItemsCount = Math.Max(0, _projectionManager.GetCount(query.Id) - element.Skip); var pagerShape = _services.New.Pager(pager) .Element(element) .PagerId(pageKey) .TotalItemCount(contentItemsCount); context.ElementShape.Pager = pagerShape; } // Renders in a standard List shape if no specific layout could be found. if (layoutDescriptor == null) { var contentShapes = contentItems.Select(item => _contentManager.BuildDisplay(item, "Summary")); var list = context.ElementShape.List = _services.New.List(); list.AddRange(contentShapes); return; } var allFielDescriptors = _projectionManager.DescribeProperties().ToList(); var fieldDescriptors = layout.Properties.OrderBy(p => p.Position).Select(p => allFielDescriptors.SelectMany(x => x.Descriptors).Select(d => new { Descriptor = d, Property = p }).FirstOrDefault(x => x.Descriptor.Category == p.Category && x.Descriptor.Type == p.Type)).ToList(); var layoutComponents = contentItems.Select(contentItem => { var contentItemMetadata = _contentManager.GetItemMetadata(contentItem); var propertyDescriptors = fieldDescriptors.Select(d => { var fieldContext = new PropertyContext { State = FormParametersHelper.ToDynamic(d.Property.State), Tokens = new Dictionary <string, object> { { "Content", contentItem } } }; return(new { d.Property, Shape = d.Descriptor.Property(fieldContext, contentItem) }); }); // Apply all settings to the field content, wrapping it in a FieldWrapper shape. var properties = _services.New.Properties( Items: propertyDescriptors.Select( pd => _services.New.PropertyWrapper( Item: pd.Shape, Property: pd.Property, ContentItem: contentItem, ContentItemMetadata: contentItemMetadata ) ) ); return(new LayoutComponentResult { ContentItem = contentItem, ContentItemMetadata = contentItemMetadata, Properties = properties }); }).ToList(); var tokenizedState = _tokenizer.Replace(layout.State, new Dictionary <string, object> { { "Content", context.Content.ContentItem } }); var renderLayoutContext = new LayoutContext { State = FormParametersHelper.ToDynamic(tokenizedState), LayoutRecord = layout, }; if (layout.GroupProperty != null) { var groupPropertyId = layout.GroupProperty.Id; var display = _displayHelperFactory.CreateHelper(new ViewContext { HttpContext = _services.WorkContext.HttpContext }, new ViewDataContainer()); // Index by PropertyWrapper shape. var groups = layoutComponents.GroupBy(x => { var propertyShape = ((IEnumerable <dynamic>)x.Properties.Items).First(p => ((PropertyRecord)p.Property).Id == groupPropertyId); // clear the wrappers, as they shouldn't be needed to generate the grouping key itself // otherwise the DisplayContext.View is null, and throws an exception if a wrapper is rendered (#18558) ((IShape)propertyShape).Metadata.Wrappers.Clear(); string key = Convert.ToString(display(propertyShape)); return(key); }).Select(x => new { Key = x.Key, Components = x }); var list = context.ElementShape.List = _services.New.List(); foreach (var group in groups) { var localResult = layoutDescriptor.Render(renderLayoutContext, group.Components); // Add the Context to the shape. localResult.Context(renderLayoutContext); list.Add(_services.New.LayoutGroup(Key: new MvcHtmlString(group.Key), List: localResult)); } return; } var layoutResult = layoutDescriptor.Render(renderLayoutContext, layoutComponents); // Add the Context to the shape. layoutResult.Context(renderLayoutContext); // Set the List shape to be the layout result. context.ElementShape.List = layoutResult; }
public string GetImageProfileUrl(string path, string profileName, FilterRecord customFilter, ContentItem contentItem) { // try to load the processed filename from cache var filePath = _fileNameProvider.GetFileName(profileName, path); bool process = false; // if the filename is not cached, process it if (string.IsNullOrEmpty(filePath)) { Logger.Debug("FilePath is null, processing required, profile {0} for image {1}", profileName, path); process = true; } // the processd file doesn't exist anymore, process it else if (!_storageProvider.FileExists(filePath)) { Logger.Debug("Processed file no longer exists, processing required, profile {0} for image {1}", profileName, path); process = true; } // if the original file is more recent, process it else { DateTime pathLastUpdated; if (TryGetImageLastUpdated(path, out pathLastUpdated)) { var filePathLastUpdated = _storageProvider.GetFile(filePath).GetLastUpdated(); if (pathLastUpdated > filePathLastUpdated) { Logger.Debug("Original file more recent, processing required, profile {0} for image {1}", profileName, path); process = true; } } } // todo: regenerate the file if the profile is newer, by deleting the associated filename cache entries. if (process) { Logger.Debug("Processing profile {0} for image {1}", profileName, path); ImageProfilePart profilePart; if (customFilter == null) { profilePart = _profileService.GetImageProfileByName(profileName); if (profilePart == null) { return(String.Empty); } } else { profilePart = _services.ContentManager.New <ImageProfilePart>("ImageProfile"); profilePart.Name = profileName; profilePart.Filters.Add(customFilter); } using (var image = GetImage(path)) { var filterContext = new FilterContext { Media = image, FilePath = _storageProvider.Combine("_Profiles", _storageProvider.Combine(profileName, CreateDefaultFileName(path))) }; var tokens = new Dictionary <string, object>(); // if a content item is provided, use it while tokenizing if (contentItem != null) { tokens.Add("Content", contentItem); } foreach (var filter in profilePart.Filters.OrderBy(f => f.Position)) { var descriptor = _processingManager.DescribeFilters().SelectMany(x => x.Descriptors).FirstOrDefault(x => x.Category == filter.Category && x.Type == filter.Type); if (descriptor == null) { continue; } var tokenized = _tokenizer.Replace(filter.State, tokens); filterContext.State = FormParametersHelper.ToDynamic(tokenized); descriptor.Filter(filterContext); } _fileNameProvider.UpdateFileName(profileName, path, filterContext.FilePath); if (!filterContext.Saved) { _storageProvider.TryCreateFolder(_storageProvider.Combine("_Profiles", profilePart.Name)); var newFile = _storageProvider.OpenOrCreate(filterContext.FilePath); using (var imageStream = newFile.OpenWrite()) { using (var sw = new BinaryWriter(imageStream)) { if (filterContext.Media.CanSeek) { filterContext.Media.Seek(0, SeekOrigin.Begin); } using (var sr = new BinaryReader(filterContext.Media)) { int count; var buffer = new byte[8192]; while ((count = sr.Read(buffer, 0, buffer.Length)) != 0) { sw.Write(buffer, 0, count); } } } } } filterContext.Media.Dispose(); filePath = filterContext.FilePath; } } // generate a timestamped url to force client caches to update if the file has changed var publicUrl = _storageProvider.GetPublicUrl(filePath); var timestamp = _storageProvider.GetFile(filePath).GetLastUpdated().Ticks; return(publicUrl + "?v=" + timestamp.ToString(CultureInfo.InvariantCulture)); }