|
Good idea.. Thanks
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
You might also need to consider the server's limit on the number of simultaneous transfers. If you're lucky, your excess transfers will just queue, but I wouldn't count on it.
Cheers,
Peter
Software rusts. Simon Stephenson, ca 1994. So does this signature. me, 2012
|
|
|
|
|
When you're using a third-party library, it helps if you tell us which one.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
It really doesn't matter. The code I posted works. However, FYI, since you asked, I'm using this.[^]
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
I am trying to extract the IDs or Names from a string and insert them in the first cell of each row and put the rest of the string in the remaining cells of each row.
For instance if I have the following string
{ID:AA, Make:ABC, Year:1995},{ID:BB, Make:BBC, Year:2000},{Name:XD, Make:DHS, Year:2006}
The data in the array will look like the following after extracting the IDs or Names, inserting them into the first cell of each row, then putting the rest of the string in the remaining cell of each row. The vertical bars represent the cells of the array.
|ID:AA|Make:ABC, Year:1995|
|ID:BB|Make:BBC, Year:2000|
|ID:XD|Make:DHS, Year:2006|
I have tried the following but its giving me the IndexOutOfRange exception.
string testString = "{ID:AA, Make:ABC, Year:1995},{ID:BB, Make:BBC, Year:2000},{Name:XD, Make:DHS, Year:2006}";
string[] outerArray = Regex.Split(testString, "},{");
string[,] innerArray = new string[2, outerArray.Length];
string idPattern = "^(ID)(.*?),";
string namePattern = "^(Class)(.*?),";
for (int i = 0; i < outerArray.Length; i++)
{
outerArray[i] = outerArray[i].Replace("{", "").Replace("}", "");
for (int y = 0; y < innerArray.Length; y++)
{
for (int x = 0; x < innerArray.Length; x++)
{
var matched_ID = Regex.Match(outerArray[i], idPattern);
var matched_Name = Regex.Match(outerArray[i], namePattern);
if (matched_ID.Success)
{
innerArray[x, y] = (matched_ID.Value).Replace(",", "");
}
else if (matched_Name.Success)
{
innerArray[x, y] = (matched_Name.Value).Replace(",", "");
}
if (outerArray[i].Length > 0 && !outerArray[i].Contains("ID:") && !outerArray[i].Contains("Name:"))
{
innerArray[x, y] = outerArray[i];
}
outerArray[i] = outerArray[i].Replace(matched_ID.Value, "");
outerArray[i] = outerArray[i].Replace(matched_Name.Value, "");
}
}
}
modified 20-Sep-16 12:47pm.
|
|
|
|
|
Are you sure?
If I copy and paste your code I get
An unhandled exception of type 'System.ArgumentException' occurred in mscorlib.dll
Additional information: String cannot be of zero length.
On this line:
outerArray[i] = outerArray[i].Replace(matched_Class.Value, "");
Because matched_Class didn't succeed but you don't check for it - because Matched_ID did.
Use the debugger and you should see what I mean.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
 Thank you so much for replying. I have made some modifications to my code and now it's giving me IndexOutOfRange Exception.
Please see my modified code below.
string testString = "{ID:AA, Make: ABC, Year:1995},{ID:BB, Make:BBC, Year:2000},{Name: PDA, Make: DHS, Year:2006}";
string[] outerArray = Regex.Split(testString, "},{");
string[,] innerArray = new string[2, outerArray.Length];
string idPattern = "^(ID)(.*?),";
string namePattern = "^(Class)(.*?),";
for (int i = 0; i < outerArray.Length; i++)
{
outerArray[i] = outerArray[i].Replace("{", "").Replace("}", "");
for (int y = 0; y < innerArray.Length; y++)
{
for (int x = 0; x < innerArray.Length; x++)
{
var matched_ID = Regex.Match(outerArray[i], idPattern);
var matched_Name = Regex.Match(outerArray[i], namePattern);
if (matched_ID.Success)
{
innerArray[x, y] = (matched_ID.Value).Replace(",", "");
}
else if (matched_Name.Success)
{
innerArray[x, y] = (matched_Name.Value).Replace(",", "");
}
if (outerArray[i].Length > 0 && !outerArray[i].Contains("ID:") && !outerArray[i].Contains("Name:"))
{
innerArray[x, y] = outerArray[i];
}
if(matched_ID.Success)
{
outerArray[i] = outerArray[i].Replace(matched_ID.Value, "");
}
else if (matched_Name.Success)
{
outerArray[i] = outerArray[i].Replace(matched_Name.Value, "");
}
}
}
}
|
|
|
|
|
MadDashCoder wrote: now it's giving me IndexOutOfRange Exception. This is a very, very simple error to fix and debug. You should be able to fix it faster than it takes to post this message.
Put a breakpoint and step through the code and you'll see exactly what is happening.
There are only 10 types of people in the world, those who understand binary and those who don't.
|
|
|
|
|
As RyanDev says: the debugger makes it obvious.
You declare the array as
string[,] innerArray = new string[2, outerArray.Length];
So what value is in x when the error occurs?
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
MadDashCoder wrote: y < innerArray.Length
x < innerArray.Length
For a multi-dimensional array, the Length property returns the total number of elements in the array.
The total number of elements in all the dimensions of the Array; zero if there are no elements in the array.
If you have a 2 × 5 array, the Length will be 10. Obviously, that's not a valid upper limit for either dimension in the array.
Try changing your loops to:
for (int y = 0; y < innerArray.GetLength(1); y++)
{
for (int x = 0; x < innerArray.GetLength(0); x++)
{
...
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Or you could try something different:
string testString = "{ID:AA, Make:ABC, Year:1995},{ID:BB, Make:BBC, Year:2000},{Name:XD, Make:DHS, Year:2006}";
string[] rows = testString.Split( new string[] { "},{", "{", "}" }, StringSplitOptions.RemoveEmptyEntries );
string[,] array = new string[ rows.Length, 2 ];
for ( int i = 0; i < rows.Length; i++ ) {
string[] cols = rows[ i ].Split( new char[] { ',' } );
array[ i, 0 ] = cols[ 0 ].Replace( "Name", "ID" );
array[ i, 1 ] = cols[ 1 ] + ", " + cols[ 2 ];
}
|
|
|
|
|
Does anyone know how to login to an SSO website with winforms?
We have an API through http behind an SSO. I would like to test this API through a real application, it works in the browser. Basically the API returns images, JSON, XML stuff through GET depending on the URL you give.
We did a test through linux command lines and this inferred a two step process, login using the credentials and then using the received tokenid for each request.
If I know which classes to look at, would already be helpful. (looking at System.Security.* now, but I can't make any sense of it.) Tutorials usually write their own SSO stuff ,whereas I am working with an existing one (we don't manage).
[UPDATE]
I receive the token now on the first request, now I have to use that somehow to get to the API. I tried:
wrGETURL.Headers.Add(HttpRequestHeader.Authorization, "Basic " + tokenid);
(and variations) but this doesn't work
[/UPDATE]
thanks.
modified 20-Sep-16 8:04am.
|
|
|
|
|
Hello all. I have a C# Winforms application. A form has a report viewer control. The Reports and Stored Procedures exist on the report server. Right now we can run the application and display the reports just fine. Everything is working.
But now we have a new requirement. The reports display several tablix controls and each tablix is connected to an embedded dataset, which in turn gets is data from a stored procedure. The new requirement is to point the dataset to another stored procedure.
The C# application already has the following capability. It reads the SQL from an existing SP. It adds a WHERE clause to the query and then saves the modified query as the same stored procedure name with _modified at the end of the name. For example, an original stored procedure is called SP1. The new stored procedure is SP1_modified. The modified SP has a where clause in it. So, I want to change the embedded dataset (SP1) to point to SP1_modified. The dataset names are the same as the stored procedure names.
After the report is rendered in the reportviewer control, I want to change the datasets back to point to SP1, for example. The _modified stored procedures will be deleted from the server.
We can already do most of this. The only thing I have not figured out is how to point the embedded dataset to a different stored procedure. Thanks for your help.
|
|
|
|
|
You can configure a dataset before "loading" it.
The SSRS object model's dataset has a Query property used to specify: a stored procedure; text command; whatever.
Just like in ADO.NET.
|
|
|
|
|
Hi Gerry. Thanks for your reply. That is good news. I figured that there had to be a way, but I am still a little confused about how to set the values.
Our reports can have multiple Embedded datasets. Using SQL Server Management Studio, I have browsed the tables and System Views and cannot find anything that would give me a clue about what Embedded datasets are defined in each report.
So I guess in C# I need to get a reference to a report on the server and then it would be really nice if I could create a foreach loop and loop through each of the datasets that are Embedded in the report and change the stored procedure or SQL as you stated.
Can you help me figure out how to get a reference to the report and loop through its Embedded datasets?
Thanks!
|
|
|
|
|
I don't know what your run-time looks like.
Sometimes the dataset is created in code (Windows Forms); sometimes there's an XML definition (BI Studio; DevExpress; SSRS).
In any case, a global solution find on "dataset" will usually locate the references.
For code, you usually do any customizing in the constructor of the report's "host"; that usually gets run before any related generated code access.
For XML, you can pre-parse the definitions (using say LINQ-to-XML) before running the report.
|
|
|
|
|
Hi Gerry. Thanks for your feedback. I have actually come to a decision as to how to handle this. I have started the work on this, but I haven't finished it yet. I will come back and post my solution once it is finished.
Basically my plan is to:
download the report as an rdl (XML file) to local computer in folder under .exe. (This works).
Modify the XML with the _NEW stored procedures. (Working on this)
Save the rdl as OriginalName_New.rdl
Upload OriginalName_New.rdl to server. (This works)
Render OriginalName_New in the report viewer control.
Once the user closes the form, delete OriginalName_New from server (This works)
Delete all of the _New datasets from report server that were used by the report. (This works)
Delete rdl file.
Thanks.
|
|
|
|
|
Sounds great! Glad to hear things are moving along. You now also have a convenient way of "logging" user activity to the server.
|
|
|
|
|
Thanks. Here is the code which handles modifying the Embeded Dataset to point to a different stored procedure. This code requires that you add a web reference to ReportingService2010.
What this code does not show is the following: Earlier in the code we read the SQL from a stored procedure and allow the user to pick some criteria and add a WHERE clause to the query. The new sql is then saved to a new stored procedure which includes the name of the original stored procedure plus _New.
So the goal here is to get the report to use the _New stored procedures. The datasets are embedded and must be repointed to the _New stored procedures.
The following code runs everything. At this time, the user has selected the report that they want to view.
string LocalPath = "";
if (DownloadReport(reportViewer1.ServerReport.ReportPath, out LocalPath))
{
string newPath = "";
if (LoopThroughDatasetsXML(LocalPath, out newPath))
{
CreateReports(cbMOE.Text + "_New", newPath, reportViewer1.ServerReport.ReportPath);
}
}
private bool DownloadReport(string reportPath, out string LocalFolder)
{
bool ret = true;
ReportingService2010.ReportingService2010 rs = new ReportingService2010.ReportingService2010();
rs.Url = "http://" + m_dbSettings.serverName + "/" + m_dbSettings.reportDbName + "/ReportService2010.asmx";
rs.Credentials = System.Net.CredentialCache.DefaultCredentials;
byte[] reportDefinition = null;
XmlDocument doc = new XmlDocument();
try
{
reportDefinition = rs.GetItemDefinition(reportPath);
MemoryStream stream = new MemoryStream(reportDefinition);
reportPath = reportPath.Replace(@"/", @"\");
LocalFolder = Directory.GetCurrentDirectory();
LocalFolder = LocalFolder + @"\TrialData\DataAccess\Reports" + reportPath + ".rdl";
string Folder = Path.GetDirectoryName(LocalFolder);
if (!Directory.Exists(Folder))
{
Directory.CreateDirectory(Folder);
}
doc.Load(stream);
doc.Save(LocalFolder);
}
catch (Exception ex)
{
ret = false;
MessageBox.Show("Problem saving reports. " + ex.Message);
throw ex;
}
return ret;
}
private bool LoopThroughDatasetsXML(string reportPath, out string NewFilename)
{
bool ret = true;
NewFilename = "";
List<SP> sp = new List<SP>();
XDocument doc = XDocument.Load(reportPath);
XNamespace ns = doc.Root.Name.Namespace;
try
{
foreach (XElement xe in doc.Descendants(ns + "DataSet"))
{
SP p = new SP();
string commandtext = xe.Element(ns + "Query").Element(ns + "CommandText").Value;
xe.Element(ns + "Query").Element(ns + "CommandText").Value = commandtext + "_New";
XAttribute a = xe.Attribute("Name");
p.SPName = commandtext;
p.DatasetName = a.Value;
sp.Add(p);
}
}
catch (Exception ex)
{
ret = false;
MessageBox.Show("Problem looping through rdl and updating to _New Stored Procedures.\n\n" + ex.Message);
}
if (ret)
{
try
{
if (sp.Count > 0)
{
NewFilename = reportPath.Substring(0, reportPath.Length - 4) + "_New.rdl";
doc.Save(NewFilename);
}
}
catch (Exception ex)
{
ret = false;
MessageBox.Show("Problem saving modified rdl.\n\n" + ex.Message);
}
}
return ret;
}
private void CreateReports(string reportName, string definitionPath, string parentFolder)
{
ReportingService2010.ReportingService2010 rsc = new ReportingService2010.ReportingService2010();
rsc.Credentials = System.Net.CredentialCache.DefaultCredentials;
rsc.Url = "http://" + m_dbSettings.serverName + "/" + m_dbSettings.reportDbName + "/ReportService2010.asmx";
Byte[] definition = null;
ReportingService2010.Warning[] warnings = null;
try
{
FileStream stream = File.OpenRead(definitionPath);
definition = new Byte[stream.Length];
stream.Read(definition, 0, (int)stream.Length);
stream.Close();
}
catch (IOException e)
{
MessageBox.Show(e.Message);
}
try
{
parentFolder = parentFolder.Replace(cbMOE.Text, "");
parentFolder = parentFolder.Substring(0, parentFolder.Length - 1);
reportName = reportName.Replace(".rdl", "");
rsc.CreateCatalogItem("Report", reportName, parentFolder, true, definition, null, out warnings);
}
catch (Exception ex)
{
MessageBox.Show("Problem uploading report. " + ex.Message);
}
}
|
|
|
|
|
Looks good. I would suggest making things more "fine-grained" / modular (once prototyping is complete).
There are opportunities to create: a "dataset parser"; a "report creator"; etc.... that will make reusability and streaming easier / simpler.
You may find some of this should happen on the server and not "off-loaded".
|
|
|
|
|
Thanks Gerry. Yes, I am still tweaking things a bit, but it initially looks good and is working.
Take Care,
David
|
|
|
|
|
|
please give me a valid article link which show me with sample code to show SSRS report in asp.net from report server when SSRS report is deployed to report server. thanks
tbhattacharjee
|
|
|
|
|
|
That's what he asked for - a valid link.
".45 ACP - because shooting twice is just silly" - JSOP, 2010
- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010
- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
|
|
|
|
|