I'm setting parameters for a report that I'm showing in ReportViewer control, and the parameters are setting properly and the report is running with the proper parameters, however the actual controls that provide the report criteria at the top of the ReportViewer are not selected. Why aren't the proper items selected in the criteria, even when the report is properly running with the criteria that I set?
ReportParameter month = new ReportParameter("month", "September 2011");
SsrsReportInfo reportInfo = new SsrsReportInfo("Summary", "http://server/ReportServer/", "/MyFolder/Summary", month);
this.reportViewer1.ServerReport.ReportPath = reportInfo.ReportPath;
this.reportViewer1.ServerReport.ReportServerUrl = new Uri(reportInfo.ReportServerUrl);
if (reportInfo.Parameters != null)
{
this.reportViewer1.ServerReport.SetParameters(reportInfo.Parameters);
}
this.reportViewer1.RefreshReport();
Here's the code for the reportInfo class:
/// <summary>
/// SSRS report information for report viewer.
/// </summary>
public class SsrsReportInfo
{
/// <summary>
/// Initializes a new instance of the <see cref="SsrsReportInfo"/> class.
/// </summary>
/// <param name="reportName">Name of the report.</param>
/// <param name="reportServerUrl">The report server URL.</param>
/// <param name="reportPath">The report path.</param>
public SsrsReportInfo(string reportName, string reportServerUrl, string reportPath)
: this(reportName, reportServerUrl, reportPath, null)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="SsrsReportInfo"/> class.
/// </summary>
/// <param name="reportName">Name of the report.</param>
/// <param name="reportServerUrl">The report server URL.</param>
/// <param name="reportPath">The report path.</param>
/// <param name="reportParameters">The report parameters.</param>
public SsrsReportInfo(string reportName, string reportServerUrl, string reportPath, params ReportParameter[] reportParameters)
{
this.ReportName = reportName;
this.ReportServerUrl = reportServerUrl;
this.ReportPath = reportPath;
this.Parameters = reportParameters;
}
/// <summary>
/// Gets or sets the name of the report.
/// </summary>
/// <value>The name of the report.</value>
public string ReportName
{
get;
set;
}
/// <summary>
/// Gets or sets the report server URL.
/// </summary>
/// <value>The report server URL.</value>
public string ReportServerUrl
{
get;
set;
}
/// <summary>
/// Gets or sets the report path.
/// </summary>
/// <value>The report path.</value>
public string ReportPath
{
get;
set;
}
/// <summary>
/// Gets or sets the parameters.
/// </summary>
/// <value>The parameters.</value>
public ReportParameter[] Parameters
{
get;
set;
}
}
Thanks,
Mark
I've figured out the issue here. I had the code setting the path, url, parameters and refreshing the report within a Form constructor. I moved it into the Form.Load event and it works fine now. Reports still run properly, but now the parameters are properly set also within the criteria portion on the top of the ReportViewer.
I had the same usage shown here: http://technet.microsoft.com/es-es/library/aa337089(SQL.90).aspx, however noticed that they did it in the Form.Load event, and I tried that, and it worked. I could probably do it in the ReportViewer.Load event also, the reason for this is probably that the controls aren't drawn up on screen yet before setting the values.
Related
Given this code:
/// <summary>
/// When identity verification has occurred.
/// </summary>
/// <param name="ConsumerId">The id of the consumer</param>
public record IdentityVerificationDecidedEvent(String ConsumerId)
{
}
I thought adding param name would do it, but it only does it on the ctor of the record object. How do I decorate the
String ConsumerId
to get the intellisense comment for
myEvent.ConsumerId
to appear?
Problem Summary
I am trying to create an offline tiled map for a WPF application that uses telerik. The user does not need to zoom in very far. I am having trouble finding a source of tiles that can be implemented with telerik.
What I've tried
I am using RadMap from telerik for WPF. They have an option for implementing tiles from a custom tile provider. I have been trying to follow the solutions given in this forum and this forum. They recommend downloading tiles from Easy OpenStreetMap Downloader, but it the file format does not match the code. It appears in the code, the tiles should be grouped in folders according to zoom level, then in a folder according to x coordinate. However, it looks to me like openstreetmaps downloader groups them by y coordinate only. I either need to get openstreetmaps downloader to save the tiles in this format, or to find another provider that will.
Code
Here is the telerik code that I am trying to base my solution off of:
/// <summary>
/// Tile source which read map tiles from the file system.
/// </summary>
public class FileSystemTileSource : TiledMapSource
{
private string tilePathFormat;
/// <summary>
/// Initializes a new instance of the FileSystemTileSource class.
/// </summary>
/// <param name="tilePathFormat">Format string to access tiles in file system.</param>
public FileSystemTileSource(string tilePathFormat)
: base(1, 20, 256, 256)
{
this.tilePathFormat = tilePathFormat;
}
/// <summary>
/// Initialize provider.
/// </summary>
public override void Initialize()
{
// Raise provider intialized event.
this.RaiseIntializeCompleted();
}
/// <summary>
/// Gets the image URI.
/// </summary>
/// <param name="tileLevel">Tile level.</param>
/// <param name="tilePositionX">Tile X.</param>
/// <param name="tilePositionY">Tile Y.</param>
/// <returns>URI of image.</returns>
protected override Uri GetTile(int tileLevel, int tilePositionX, int tilePositionY)
{
int zoomLevel = ConvertTileToZoomLevel(tileLevel);
string tileFileName = this.tilePathFormat.Replace("{zoom}", zoomLevel.ToString(CultureInfo.InvariantCulture));
tileFileName = tileFileName.Replace("{x}", tilePositionX.ToString(CultureInfo.InvariantCulture));
tileFileName = tileFileName.Replace("{y}", tilePositionY.ToString(CultureInfo.InvariantCulture));
if (File.Exists(tileFileName))
{
return new Uri(tileFileName);
}
else
{
return null;
}
}
}
/// <summary>
/// Map provider which read map tiles from the file system.
/// </summary>
public class FileSystemProvider : TiledProvider
{
/// <summary>
/// Initializes a new instance of the MyMapProvider class.
/// </summary>
/// <param name="tilePathFormat">Format string to access tiles in file system.</param>
public FileSystemProvider(string tilePathFormat)
: base()
{
FileSystemTileSource source = new FileSystemTileSource(tilePathFormat);
this.MapSources.Add(source.UniqueId, source);
}
/// <summary>
/// Returns the SpatialReference for the map provider.
/// </summary>
public override ISpatialReference SpatialReference
{
get
{
return new MercatorProjection();
}
}
}
public MainWindow()
{
InitializeComponent();
this.radMap.Provider = new FileSystemProvider("Path to OpenStreet Images\\{zoom}\\{x}\\os_{x}_{y}_{zoom}.png");
}
I have a List<object> that I want to access in my class.
The list is a property, and has a get and set.
When I want a single item from the list, I want it to lazy load in the single item I am requesting from a database.
To do this - I want to check if the item being requested exists in the list, if not, I want to add it to the list from the database (if it exists in the database) - then I return the list.
The problem is, I don't think the getter knows what items are being 'gotten', it just knows that the list itself is being requested. So while I can easily lazy load in the entire list, I can't "download and cache as you go".
It was looking very neat too - I could expose the list as a property, and let the property handle all of the loading logic.
In less trivial examples, it's a bit more useless I suppose - like if I wanted to run a query - I would always have to do it against the whole data set otherwise I'd miss results.
Currently, I just download and cache every result from the database when the property is called.
Is there a better approach?
Was thinking mainly about pagination. I.e. want items 0-9, items 10-19, etc
Since we're talking about pagination, we must understand, that pagination is neither retrieving single item from the list, nor indexed list access.
Pagination usually allows user to:
fetch data from data source using small portions (pages);
set page size;
fetch next page (next N pages);
fetch previous page (previous N pages);
fetch particular page (go to page N).
Note, that pagination is about reading data, not about inserting new one.
Basically, pagination requires:
paged data source. This can be database, file, in-memory data, that allows to get data portion. E.g. SQL Server allows this via OFFSET... FETCH NEXT in TSQL;
paged data source API to access particular page. E.g. IQueryable<T> and its extensions Skip and Take;
pagination service. It implements pagination logic;
pagination UI controls.
There can be many specific things. Pagination service and UI depends on what framework do you use (ASP .NET, WPF, etc).
Here's the simple pagination service implementation:
/// <summary>
/// Represents paged data source.
/// </summary>
/// <typeparam name="T">
/// Data item type.
/// </typeparam>
public interface IPagedDataSource<T>
{
/// <summary>
/// Fetches particular page from data source.
/// </summary>
/// <param name="pageNumber">
/// Page number.
/// </param>
/// <param name="pageSize">
/// Page size.
/// </param>
/// <returns></returns>
IReadOnlyList<T> GetPage(int pageNumber, int pageSize);
}
/// <summary>
/// Represents paged data source, built on top of <see cref="IQueryable{T}"/> instance.
/// </summary>
/// <typeparam name="T">
/// Data item type.
/// </typeparam>
public sealed class QueryablePagedDataSource<T> : IPagedDataSource<T>
{
private readonly IQueryable<T> query;
/// <summary>
/// Initializes <see cref="QueryablePagedDataSource{T}"/> instance.
/// </summary>
/// <param name="query">
/// <see cref="IQueryable{T}"/> to use as paged data source.
/// </param>
public QueryablePagedDataSource(IQueryable<T> query)
{
this.query = query;
}
/// <summary>
/// Fetches particular page from data source.
/// </summary>
/// <param name="pageNumber">
/// Page number.
/// </param>
/// <param name="pageSize">
/// Page size.
/// </param>
/// <returns></returns>
public IReadOnlyList<T> GetPage(int pageNumber, int pageSize) => query
.Skip(pageNumber * pageSize)
.Take(pageSize)
.ToList();
}
/// <summary>
/// Implements basic pagination logic.
/// </summary>
/// <typeparam name="T">
/// Data item type.
/// </typeparam>
public sealed class Paginator<T>
{
private readonly int pageSize;
private readonly IPagedDataSource<T> dataSource;
private readonly IDictionary<int, IReadOnlyList<T>> pages;
/// <summary>
/// Initializes <see cref="Paginator{T}"/> instance.
/// </summary>
/// <param name="dataSource">
/// Paged data source.
/// </param>
/// <param name="pageSize">
/// Page size.
/// </param>
public Paginator(IPagedDataSource<T> dataSource, int pageSize)
{
this.dataSource = dataSource;
this.pageSize = pageSize;
pages = new Dictionary<int, IReadOnlyList<T>>();
}
/// <summary>
/// Gets current page number.
/// </summary>
public int CurrentPageNumber { get; private set; }
/// <summary>
/// Gets current page.
/// </summary>
public IReadOnlyList<T> CurrentPage
{
get
{
if (pages.Count == 0)
{
NavigateTo(0);
}
return pages[CurrentPageNumber];
}
}
/// <summary>
/// Navigates to particular page.
/// </summary>
/// <param name="pageNumber">
/// Page number to navigate to.
/// </param>
public void NavigateTo(int pageNumber)
{
CurrentPageNumber = pageNumber;
if (!pages.ContainsKey(CurrentPageNumber))
{
var page = dataSource.GetPage(CurrentPageNumber, pageSize);
pages.Add(CurrentPageNumber, page);
}
}
/// <summary>
/// Navigates to the next page.
/// </summary>
public void Next() => NavigateTo(CurrentPageNumber + 1);
/// <summary>
/// Navigates to the previous page.
/// </summary>
public void Previous()
{
if (CurrentPageNumber > 1)
{
NavigateTo(CurrentPageNumber - 1);
}
}
/// <summary>
/// Exports fetched data as a list.
/// </summary>
/// <returns>
/// A list, containing fetched data. Data is ordered by page number.
/// </returns>
public List<T> ToList() => pages
.OrderBy(_ => _.Key)
.SelectMany(_ => _.Value)
.ToList();
}
Try to play with it (e.g. create data source from collection using AsQueryable extension). Maybe it will be useful for you.
Note, that there are no null-checking and range-checking.
In Summary: I Want to replace IFormFile IFormFileCollection with my own classes not attached to Asp .Net because my view models are in different project with poco classes. My custom classes are ICommonFile, ICommonFileCollection, IFormFile (not Asp .net core class) and IFormFileCollection.
i will share it here:
ICommonFile.cs
/// <summary>
/// File with common Parameters including bytes
/// </summary>
public interface ICommonFile
{
/// <summary>
/// Stream File
/// </summary>
Stream File { get; }
/// <summary>
/// Name of the file
/// </summary>
string Name { get; }
/// <summary>
/// Gets the file name with extension.
/// </summary>
string FileName { get; }
/// <summary>
/// Gets the file length in bytes.
/// </summary>
long Length { get; }
/// <summary>
/// Copies the contents of the uploaded file to the <paramref name="target"/> stream.
/// </summary>
/// <param name="target">The stream to copy the file contents to.</param>
void CopyTo(Stream target);
/// <summary>
/// Asynchronously copies the contents of the uploaded file to the <paramref name="target"/> stream.
/// </summary>
/// <param name="target">The stream to copy the file contents to.</param>
/// <param name="cancellationToken">Enables cooperative cancellation between threads</param>
Task CopyToAsync(Stream target, CancellationToken cancellationToken = default(CancellationToken));
}
ICommonFileCollection.cs
/// <inheritdoc />
/// <summary>
/// Represents the collection of files.
/// </summary>
public interface ICommonFileCollection : IReadOnlyList<ICommonFile>
{
/// <summary>
/// File Indexer by name
/// </summary>
/// <param name="name">File name index</param>
/// <returns>File with related file name index</returns>
ICommonFile this[string name] { get; }
/// <summary>
/// Gets file by name
/// </summary>
/// <param name="name">file name</param>
/// <returns>File with related file name index</returns>
ICommonFile GetFile(string name);
/// <summary>
/// Gets Files by name
/// </summary>
/// <param name="name"></param>>
/// <returns>Files with related file name index</returns>
IReadOnlyList<ICommonFile> GetFiles(string name);
}
IFormFile.cs
/// <inheritdoc />
/// <summary>
/// File transferred by HttpProtocol, this is an independent
/// Asp.net core interface
/// </summary>
public interface IFormFile : ICommonFile
{
/// <summary>
/// Gets the raw Content-Type header of the uploaded file.
/// </summary>
string ContentType { get; }
/// <summary>
/// Gets the raw Content-Disposition header of the uploaded file.
/// </summary>
string ContentDisposition { get; }
}
IFormFileCollection.cs
/// <summary>
/// File Collection transferred by HttpProtocol, this is an independent
/// Asp.net core implementation
/// </summary>
public interface IFormFileCollection
{
//Use it when you need to implement new features to Form File collection over HttpProtocol
}
I finally created my model binders successfully, i will share it too:
FormFileModelBinderProvider.cs
/// <inheritdoc />
/// <summary>
/// Model Binder Provider, it inspects
/// any model when the request is triggered
/// </summary>
public class FormFileModelBinderProvider : IModelBinderProvider
{
/// <inheritdoc />
/// <summary>
/// Inspects a Model for any CommonFile class or Collection with
/// same class if exist the FormFileModelBinder initiates
/// </summary>
/// <param name="context">Model provider context</param>
/// <returns>a new Instance o FormFileModelBinder if type is found otherwise null</returns>
public IModelBinder GetBinder(ModelBinderProviderContext context)
{
if (context == null) throw new ArgumentNullException(nameof(context));
if (!context.Metadata.IsComplexType) return null;
var isSingleCommonFile = IsSingleCommonFile(context.Metadata.ModelType);
var isCommonFileCollection = IsCommonFileCollection(context.Metadata.ModelType);
if (!isSingleCommonFile && !isCommonFileCollection) return null;
return new FormFileModelBinder();
}
/// <summary>
/// Checks if object type is a CommonFile Collection
/// </summary>
/// <param name="modelType">Context Meta data ModelType</param>
/// <returns>If modelType is a collection of CommonFile returns true otherwise false</returns>
private static bool IsCommonFileCollection(Type modelType)
{
if (typeof(ICommonFileCollection).IsAssignableFrom(modelType))
{
return true;
}
var hasCommonFileArguments = modelType.GetGenericArguments()
.AsParallel().Any(t => typeof(ICommonFile).IsAssignableFrom(t));
if (typeof(IEnumerable).IsAssignableFrom(modelType) && hasCommonFileArguments)
{
return true;
}
if (typeof(IAsyncEnumerable<object>).IsAssignableFrom(modelType) && hasCommonFileArguments)
{
return true;
}
return false;
}
/// <summary>
/// Checks if object type is CommonFile or an implementation of ICommonFile
/// </summary>
/// <param name="modelType"></param>
/// <returns></returns>
private static bool IsSingleCommonFile(Type modelType)
{
if (modelType == typeof(ICommonFile) || modelType.GetInterfaces().Contains(typeof(ICommonFile)))
{
return true;
}
return false;
}
}
FormFileModelBinder.cs
/// <inheritdoc />
/// <summary>
/// Form File Model binder
/// Parses the Form file object type to a commonFile
/// </summary>
public class FormFileModelBinder : IModelBinder
{
/// <summary>
/// Expression to map IFormFile object type to CommonFile
/// </summary>
private readonly Func<Microsoft.AspNetCore.Http.IFormFile, ICommonFile> _expression;
/// <summary>
/// FormFile Model binder constructor
/// </summary>
public FormFileModelBinder()
{
_expression = x => new CommonFile(x.OpenReadStream(), x.Length, x.Name, x.FileName);
}
/// <inheritdoc />
/// <summary>
/// It Binds IFormFile to Common file, getting the file
/// from the binding context
/// </summary>
/// <param name="bindingContext">Http Context</param>
/// <returns>Completed Task</returns>
// TODO: Bind this context to ICommonFile or ICommonFileCollection object
public Task BindModelAsync(ModelBindingContext bindingContext)
{
dynamic model;
if (bindingContext == null) throw new ArgumentNullException(nameof(bindingContext));
var formFiles = bindingContext.ActionContext.HttpContext.Request.Form.Files;
if (!formFiles.Any()) return Task.CompletedTask;
if (formFiles.Count > 1)
{
model = formFiles.AsParallel().Select(_expression);
}
else
{
model = new FormFileCollection();
model.AddRange(filteredFiles.AsParallel().Select(_expression));
}
bindingContext.Result = ModelBindingResult.Success(model);
return Task.CompletedTask;
}
}
Actually Everything is working good except when i have Nested Models. I share an example of my models I'm using and I'll do some comments with working scenarios and which don't
Test.cs
public class Test
{
//It's Working
public ICommonFileCollection Files { get; set; }
//It's Working
public ICommonFileCollection Files2 { get; set; }
//This is a nested model
public TestExtra TestExtra { get; set; }
}
TestExtra.cs
public class TestExtra
{
//It's not working
public ICommonFileCollection Files { get; set; }
}
Actually when i make a request to my API I've got the following (Screenshot):
I'm sharing a screenshot of my postman request too for clarifying my request is good.
If there is any subjection to make this work with nested model it would be great.
Asp Net Core Model Binder won't bind model with one property only, if you have one property in a class, that property will be null but when you add two or more will bind it. my mistake i had one one property in a nested class. The entire code is correct.
I need create XML comment for return value of method Login. This method returns object type
of Result. This object contains session id if login was successful and if login was unsuccessful contains error message.
I don’t know how decribe this in XML comment.
/// <summary>
/// Login to server
/// </summary>
/// <param name="name">Name of user</param>
/// <param name="password">User password</param>
/// <returns>
/// This method return object type of Result<Account>
/// If login was successful contains sessions
/// If login was unsuccessful contains error
/// </returns>
Result<Account> Login(string name, string password);
/// <summary>
/// Return value of method
/// </summary>
/// <typeparam name="T">Type of return value</typeparam>
public class Result<T>
{
/// <summary>
/// Return message
/// </summary>
public string ResultMessage { get; set; }
/// <summary>
/// Return value
/// </summary>
public T ReturnValue { get; set; }
}
public class Account
{
public string Name{get;set;}
public string Password {get;set;}
public string Session {get;set;
}
Thank you for advices.
You would use:
/// ...
/// This method returns an object of type <see cref="Result{Account}"/>.
/// ...
See cref Attribute.