I have used the ready made dropbox simple api code and I have included my appkey in the "XXXXXXX" space, and I added the :
Redirect URIs
http://127.0.0.1:52475/ in app consle od drop box:
but it is not working with me, I just need a simle function that I can pass dropbox token and file detination to eighter download or upload, I have used the existing code below or you can get the whole project from https://github.com/dropbox/dropbox-sdk-dotnet/tree/main/dropbox-sdk-dotnet/Examples/SimpleTest
from. If there is other code that can serve the purpose please help
I need a simple nethoed where I can pass parameter like tokens, appkey, file destination, and access the file (Download or upload)
namespace SimpleTest
{
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Dropbox.Api;
using Dropbox.Api.Common;
using Dropbox.Api.Files;
using Dropbox.Api.Team;
partial class Program
{
// Add an ApiKey (from https://www.dropbox.com/developers/apps) here
private const string ApiKey ="xxxxxxxxxxxxxxxxxxx";
// This loopback host is for demo purpose. If this port is not
// available on your machine you need to update this URL with an unused port.
private const string LoopbackHost = "http://127.0.0.1:52475/";
// URL to receive OAuth 2 redirect from Dropbox server.
// You also need to register this redirect URL on https://www.dropbox.com/developers/apps.
private readonly Uri RedirectUri = new Uri(LoopbackHost + "authorize");
// URL to receive access token from JS.
private readonly Uri JSRedirectUri = new Uri(LoopbackHost + "token");
[DllImport("kernel32.dll", ExactSpelling = true)]
private static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetForegroundWindow(IntPtr hWnd);
[STAThread]
static int Main(string[] args)
{
Console.WriteLine("SimpleTest");
var instance = new Program();
try
{
var task = Task.Run((Func<Task<int>>)instance.Run);
task.Wait();
return task.Result;
}
catch(Exception e)
{
Console.WriteLine(e);
throw e;
}
}
private async Task<int> Run()
{
DropboxCertHelper.InitializeCertPinning();
var accessToken = await this.GetAccessToken();
if (string.IsNullOrEmpty(accessToken))
{
return 1;
}
// Specify socket level timeout which decides maximum waiting time when no bytes are
// received by the socket.
var httpClient = new HttpClient(new WebRequestHandler { ReadWriteTimeout = 10 * 1000 })
{
// Specify request level timeout which decides maximum time that can be spent on
// download/upload files.
Timeout = TimeSpan.FromMinutes(20)
};
try
{
var config = new DropboxClientConfig("SimpleTestApp")
{
HttpClient = httpClient
};
var client = new DropboxClient(accessToken, config);
await RunUserTests(client);
// Tests below are for Dropbox Business endpoints. To run these tests, make sure the ApiKey is for
// a Dropbox Business app and you have an admin account to log in.
/*
var client = new DropboxTeamClient(accessToken, userAgent: "SimpleTeamTestApp", httpClient: httpClient);
await RunTeamTests(client);
*/
}
catch (HttpException e)
{
Console.WriteLine("Exception reported from RPC layer");
Console.WriteLine(" Status code: {0}", e.StatusCode);
Console.WriteLine(" Message : {0}", e.Message);
if (e.RequestUri != null)
{
Console.WriteLine(" Request uri: {0}", e.RequestUri);
}
}
return 0;
}
/// <summary>
/// Run tests for user-level operations.
/// </summary>
/// <param name="client">The Dropbox client.</param>
/// <returns>An asynchronous task.</returns>
private async Task RunUserTests(DropboxClient client)
{
await GetCurrentAccount(client);
var path = "/DotNetApi/Help";
var folder = await CreateFolder(client, path);
var list = await ListFolder(client, path);
var firstFile = list.Entries.FirstOrDefault(i => i.IsFile);
if (firstFile != null)
{
await Download(client, path, firstFile.AsFile);
}
var pathInTeamSpace = "/Test";
await ListFolderInTeamSpace(client, pathInTeamSpace);
await Upload(client, path, "Test.txt", "This is a text file");
await ChunkUpload(client, path, "Binary");
}
/// <summary>
/// Run tests for team-level operations.
/// </summary>
/// <param name="client">The Dropbox client.</param>
/// <returns>An asynchronous task.</returns>
private async Task RunTeamTests(DropboxTeamClient client)
{
var members = await client.Team.MembersListAsync();
var member = members.Members.FirstOrDefault();
if (member != null)
{
// A team client can perform action on a team member's behalf. To do this,
// just pass in team member id in to AsMember function which returns a user client.
// This client will operates on this team member's Dropbox.
var userClient = client.AsMember(member.Profile.TeamMemberId);
await RunUserTests(userClient);
}
}
/// <summary>
/// Handles the redirect from Dropbox server. Because we are using token flow, the local
/// http server cannot directly receive the URL fragment. We need to return a HTML page with
/// inline JS which can send URL fragment to local server as URL parameter.
/// </summary>
/// <param name="http">The http listener.</param>
/// <returns>The <see cref="Task"/></returns>
private async Task HandleOAuth2Redirect(HttpListener http)
{
var context = await http.GetContextAsync();
// We only care about request to RedirectUri endpoint.
while (context.Request.Url.AbsolutePath != RedirectUri.AbsolutePath)
{
context = await http.GetContextAsync();
}
context.Response.ContentType = "text/html";
// Respond with a page which runs JS and sends URL fragment as query string
// to TokenRedirectUri.
using (var file = File.OpenRead("index.html"))
{
file.CopyTo(context.Response.OutputStream);
}
context.Response.OutputStream.Close();
}
/// <summary>
/// Handle the redirect from JS and process raw redirect URI with fragment to
/// complete the authorization flow.
/// </summary>
/// <param name="http">The http listener.</param>
/// <returns>The <see cref="OAuth2Response"/></returns>
private async Task<OAuth2Response> HandleJSRedirect(HttpListener http)
{
var context = await http.GetContextAsync();
// We only care about request to TokenRedirectUri endpoint.
while (context.Request.Url.AbsolutePath != JSRedirectUri.AbsolutePath)
{
context = await http.GetContextAsync();
}
var redirectUri = new Uri(context.Request.QueryString["url_with_fragment"]);
var result = DropboxOAuth2Helper.ParseTokenFragment(redirectUri);
return result;
}
/// <summary>
/// Gets the dropbox access token.
/// <para>
/// This fetches the access token from the applications settings, if it is not found there
/// (or if the user chooses to reset the settings) then the UI in <see cref="LoginForm"/> is
/// displayed to authorize the user.
/// </para>
/// </summary>
/// <returns>A valid access token or null.</returns>
private async Task<string> GetAccessToken()
{
Console.Write("Reset settings (Y/N) ");
if (Console.ReadKey().Key == ConsoleKey.Y)
{
Settings.Default.Reset();
}
Console.WriteLine();
var accessToken = Settings.Default.AccessToken;
if (string.IsNullOrEmpty(accessToken))
{
try
{
Console.WriteLine("Waiting for credentials.");
var state = Guid.NewGuid().ToString("N");
var authorizeUri = DropboxOAuth2Helper.GetAuthorizeUri(OAuthResponseType.Token, ApiKey, RedirectUri, state: state);
var http = new HttpListener();
http.Prefixes.Add(LoopbackHost);
http.Start();
System.Diagnostics.Process.Start(authorizeUri.ToString());
// Handle OAuth redirect and send URL fragment to local server using JS.
await HandleOAuth2Redirect(http);
// Handle redirect from JS and process OAuth response.
var result = await HandleJSRedirect(http);
if (result.State != state)
{
// The state in the response doesn't match the state in the request.
return null;
}
Console.WriteLine("and back...");
// Bring console window to the front.
SetForegroundWindow(GetConsoleWindow());
accessToken = result.AccessToken;
var uid = result.Uid;
Console.WriteLine("Uid: {0}", uid);
Settings.Default.AccessToken = accessToken;
Settings.Default.Uid = uid;
Settings.Default.Save();
}
catch (Exception e)
{
Console.WriteLine("Error: {0}", e.Message);
return null;
}
}
return accessToken;
}
/// <summary>
/// Gets information about the currently authorized account.
/// <para>
/// This demonstrates calling a simple rpc style api from the Users namespace.
/// </para>
/// </summary>
/// <param name="client">The Dropbox client.</param>
/// <returns>An asynchronous task.</returns>
private async Task GetCurrentAccount(DropboxClient client)
{
var full = await client.Users.GetCurrentAccountAsync();
Console.WriteLine("Account id : {0}", full.AccountId);
Console.WriteLine("Country : {0}", full.Country);
Console.WriteLine("Email : {0}", full.Email);
Console.WriteLine("Is paired : {0}", full.IsPaired ? "Yes" : "No");
Console.WriteLine("Locale : {0}", full.Locale);
Console.WriteLine("Name");
Console.WriteLine(" Display : {0}", full.Name.DisplayName);
Console.WriteLine(" Familiar : {0}", full.Name.FamiliarName);
Console.WriteLine(" Given : {0}", full.Name.GivenName);
Console.WriteLine(" Surname : {0}", full.Name.Surname);
Console.WriteLine("Referral link : {0}", full.ReferralLink);
if (full.Team != null)
{
Console.WriteLine("Team");
Console.WriteLine(" Id : {0}", full.Team.Id);
Console.WriteLine(" Name : {0}", full.Team.Name);
}
else
{
Console.WriteLine("Team - None");
}
}
/// <summary>
/// Creates the specified folder.
/// </summary>
/// <remarks>This demonstrates calling an rpc style api in the Files namespace.</remarks>
/// <param name="path">The path of the folder to create.</param>
/// <param name="client">The Dropbox client.</param>
/// <returns>The result from the ListFolderAsync call.</returns>
private async Task<FolderMetadata> CreateFolder(DropboxClient client, string path)
{
Console.WriteLine("--- Creating Folder ---");
var folderArg = new CreateFolderArg(path);
try
{
var folder = await client.Files.CreateFolderV2Async(folderArg);
Console.WriteLine("Folder: " + path + " created!");
return folder.Metadata;
}
catch (ApiException<CreateFolderError> e)
{
if (e.Message.StartsWith("path/conflict/folder"))
{
Console.WriteLine("Folder already exists... Skipping create");
return null;
}
else
{
throw e;
}
}
}
/// <summary>
/// Lists the items within a folder inside team space. See
/// https://www.dropbox.com/developers/reference/namespace-guide for details about
/// user namespace vs team namespace.
/// </summary>
/// <param name="client">The Dropbox client.</param>
/// <param name="path">The path to list.</param>
/// <returns>The <see cref="Task"/></returns>
private async Task ListFolderInTeamSpace(DropboxClient client, string path)
{
// Fetch root namespace info from user's account info.
var account = await client.Users.GetCurrentAccountAsync();
if (!account.RootInfo.IsTeam)
{
Console.WriteLine("This user doesn't belong to a team with shared space.");
}
else
{
try
{
// Point path root to namespace id of team space.
client = client.WithPathRoot(new PathRoot.Root(account.RootInfo.RootNamespaceId));
await ListFolder(client, path);
}
catch (PathRootException ex)
{
Console.WriteLine(
"The user's root namespace ID has changed to {0}",
ex.ErrorResponse.AsInvalidRoot.Value);
}
}
}
/// <summary>
/// Lists the items within a folder.
/// </summary>
/// <remarks>This demonstrates calling an rpc style api in the Files namespace.</remarks>
/// <param name="path">The path to list.</param>
/// <param name="client">The Dropbox client.</param>
/// <returns>The result from the ListFolderAsync call.</returns>
private async Task<ListFolderResult> ListFolder(DropboxClient client, string path)
{
Console.WriteLine("--- Files ---");
var list = await client.Files.ListFolderAsync(path);
// show folders then files
foreach (var item in list.Entries.Where(i => i.IsFolder))
{
Console.WriteLine("D {0}/", item.Name);
}
foreach (var item in list.Entries.Where(i => i.IsFile))
{
var file = item.AsFile;
Console.WriteLine("F{0,8} {1}",
file.Size,
item.Name);
}
if (list.HasMore)
{
Console.WriteLine(" ...");
}
return list;
}
/// <summary>
/// Downloads a file.
/// </summary>
/// <remarks>This demonstrates calling a download style api in the Files namespace.</remarks>
/// <param name="client">The Dropbox client.</param>
/// <param name="folder">The folder path in which the file should be found.</param>
/// <param name="file">The file to download within <paramref name="folder"/>.</param>
/// <returns></returns>
private async Task Download(DropboxClient client, string folder, FileMetadata file)
{
Console.WriteLine("Download file...");
using (var response = await client.Files.DownloadAsync(folder + "/" + file.Name))
{
Console.WriteLine("Downloaded {0} Rev {1}", response.Response.Name, response.Response.Rev);
Console.WriteLine("------------------------------");
Console.WriteLine(await response.GetContentAsStringAsync());
Console.WriteLine("------------------------------");
}
}
/// <summary>
/// Uploads given content to a file in Dropbox.
/// </summary>
/// <param name="client">The Dropbox client.</param>
/// <param name="folder">The folder to upload the file.</param>
/// <param name="fileName">The name of the file.</param>
/// <param name="fileContent">The file content.</param>
/// <returns></returns>
private async Task Upload(DropboxClient client, string folder, string fileName, string fileContent)
{
Console.WriteLine("Upload file...");
using (var stream = new MemoryStream(System.Text.UTF8Encoding.UTF8.GetBytes(fileContent)))
{
var response = await client.Files.UploadAsync(folder + "/" + fileName, WriteMode.Overwrite.Instance, body: stream);
Console.WriteLine("Uploaded Id {0} Rev {1}", response.Id, response.Rev);
}
}
/// <summary>
/// Uploads a big file in chunk. The is very helpful for uploading large file in slow network condition
/// and also enable capability to track upload progerss.
/// </summary>
/// <param name="client">The Dropbox client.</param>
/// <param name="folder">The folder to upload the file.</param>
/// <param name="fileName">The name of the file.</param>
/// <returns></returns>
private async Task ChunkUpload(DropboxClient client, string folder, string fileName)
{
Console.WriteLine("Chunk upload file...");
// Chunk size is 128KB.
const int chunkSize = 128 * 1024;
// Create a random file of 1MB in size.
var fileContent = new byte[1024 * 1024];
new Random().NextBytes(fileContent);
using (var stream = new MemoryStream(fileContent))
{
int numChunks = (int)Math.Ceiling((double)stream.Length / chunkSize);
byte[] buffer = new byte[chunkSize];
string sessionId = null;
for (var idx = 0; idx < numChunks; idx++)
{
Console.WriteLine("Start uploading chunk {0}", idx);
var byteRead = stream.Read(buffer, 0, chunkSize);
using (MemoryStream memStream = new MemoryStream(buffer, 0, byteRead))
{
if (idx == 0)
{
var result = await client.Files.UploadSessionStartAsync(body: memStream);
sessionId = result.SessionId;
}
else
{
UploadSessionCursor cursor = new UploadSessionCursor(sessionId, (ulong)(chunkSize * idx));
if (idx == numChunks - 1)
{
await client.Files.UploadSessionFinishAsync(cursor, new CommitInfo(folder + "/" + fileName), memStream);
}
else
{
await client.Files.UploadSessionAppendV2Async(cursor, body: memStream);
}
}
}
}
}
}
/// <summary>
/// List all members in the team.
/// </summary>
/// <param name="client">The Dropbox team client.</param>
/// <returns>The result from the MembersListAsync call.</returns>
private async Task<MembersListResult> ListTeamMembers(DropboxTeamClient client)
{
var members = await client.Team.MembersListAsync();
foreach (var member in members.Members)
{
Console.WriteLine("Member id : {0}", member.Profile.TeamMemberId);
Console.WriteLine("Name : {0}", member.Profile.Name);
Console.WriteLine("Email : {0}", member.Profile.Email);
}
return members;
}
}
}
I have the below code which initiates the browser in each test. However the first Test runs OK correctly starting the browser. The second Test on wards start to fail
public class BrowserFactory
{
private static IWebDriver driver;
public static IWebDriver Driver
{
get
{
if (driver == null)
throw new NullReferenceException("The WebDriver browser instance was not initialized. You should first call the method InitBrowser.");
return driver;
}
set
{
driver = value;
}
}
public static void InitBrowser(string browserName)
{
switch (browserName)
{
case "Firefox":
if (driver == null)
{
driver = new FirefoxDriver();
driver.Manage().Window.Maximize();
}
break;
case "IE":
if (driver == null)
{
driver = new InternetExplorerDriver();
driver.Manage().Window.Maximize();
}
break;
case "Chrome":
if (driver == null)
{
driver = new ChromeDriver();
driver.Manage().Window.Maximize();
}
break;
}
}
And this is how I initiate and quit browser in each test
[TestFixture]
public class AdminUserHasAccessToDashboard
{
[SetUp]
public void GotoHomePage()
{
BrowserFactory.InitBrowser("Chrome");
BrowserFactory.LoadApplication(ConfigurationManager.AppSettings["URL"]);
}
[TearDown]
public void Quit()
{
BrowserFactory.CloseAllDrivers();
}
It looks like you are probably setting driver instance in your first test and other tests are false on if (driver == null), so other instances will never be created. Your code is incomplete so I can't be sure, but it seems to be an issue here.
How are you closing your driver after first test is completed?
Include the method mentioned below in your browser factory and call at the end of each test, or set up before the tests are run then use the single instance for each test and tear down at the end.
public static void Quit(){
if (Driver!= null)
Driver.Quit();
}
I use a static "Driver" class which is referenced in each test class (not each test case)
I include this in each class(they are nunit C# tests)
#region Initialise and clean up
[OneTimeSetUp]
public void Init()
{
Driver.Initialise();
}
[OneTimeTearDown]
public void CleanUp()
{
Driver.Quit();
}
#endregion
Then my driver class is as below, the appstate region wont apply but can be edited to suit your needs.
using System;
using System.Threading;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using AdaptiveAds_TestFramework.PageFrameworks;
namespace AdaptiveAds_TestFramework.Helpers
{
/// <summary>
/// Contains functionality for browser automation.
/// </summary>
public static class Driver
{
#region Variables
private static IWebDriver _instance;
private static Period _waitPeriod;
#endregion//Variables
#region Properties
/// <summary>
/// Browser automation object.
/// </summary>
public static IWebDriver Instance
{
get { return _instance; }
set { _instance = value; SetWait(WaitPeriod); }
}
/// <summary>
/// Duration automation framework must wait before throwing an error.
/// </summary>
public static Period WaitPeriod
{
get { return _waitPeriod; }
set
{
_waitPeriod = value;
SetWait(_waitPeriod);
}
}
#endregion//Properties
#region Methods
#region set-up and tear-down
/// <summary>
/// Sets up a new automation object.
/// </summary>
public static void Initialise()
{
Quit();
Instance = new FirefoxDriver(new FirefoxBinary(ConfigData.FireFoxPath), new FirefoxProfile());
Instance.Manage().Window.Maximize();
WaitPeriod = ConfigData.DefaultWaitPeriod;
}
/// <summary>
/// Disposes of the automation object.
/// </summary>
public static void Quit()
{
if (Instance != null)
Instance.Quit();
}
#endregion //set-up and tear-down
#region NavigableLocations
/// <summary>
/// Navigate browser to a given location.
/// </summary>
/// <param name="location">Location to navigate to.</param>
/// <param name="logInIfNeeded">Logs in if authentication is required.</param>
/// <param name="errorIfNotReached">Errors if the location was not reached.</param>
public static void GoTo(Location location, bool logInIfNeeded, bool errorIfNotReached)
{
// Navigate browser to the location.
Instance.Navigate().GoToUrl(Helper.RouteUrl(location));
Thread.Sleep(500);// wait for system to navigate
bool needToLogIn = false;
if (logInIfNeeded)
{
try
{
IsAt(Location.Login);
needToLogIn = true;
}
catch
{
// Not at login page so Login not needed.
}
if (needToLogIn)
{
LoginPage.LoginAs(ConfigData.Username).WithPassword(ConfigData.Password).Login();
GoTo(location, false, errorIfNotReached);
}
}
if (errorIfNotReached)
{
IsAt(location);
}
}
/// <summary>
/// Ensures the Driver is at the specified location, throws a WebDriverException if at another location.
/// </summary>
/// <param name="location">Location to check the browser is at.</param>
public static void IsAt(Location location)
{
string expected = Helper.RouteUrl(location);
string actual = Instance.Url;
// Check the browser is at the correct location.
if (actual != expected)
{
// Driver is not at the specified location.
throw new WebDriverException("Incorrect location.",
new InvalidElementStateException(
"The given location did not match the browser." +
" Expected \"" + expected + "\" Actual \"" + actual + "\""));
}
ActionWait(Period.None, CheckForLavarelError);
}
/// <summary>
/// Ensures the Driver is not at the specified location, throws a WebDriverException if at the location.
/// </summary>
/// <param name="location">Location to check the browser is not at.</param>
public static void IsNotAt(Location location)
{
string expected = Helper.RouteUrl(location);
string actual = Instance.Url;
// Check the browser is not at the correct location.
if (actual == expected)
{
// Driver is at the specified location.
throw new WebDriverException("Incorrect location.",
new InvalidElementStateException(
"The given location matched the browser."));
}
}
#endregion//NavigableLocations
#region WaitHandling
/// <summary>
/// Performs an action with a temporary wait period.
/// </summary>
/// <param name="waitPeriod">Period to wait while executing action.</param>
/// <param name="action">Action to execute.</param>
public static void ActionWait(Period waitPeriod, Action action)
{
// Store the current wait period
Period previousPeriod = WaitPeriod;
// Run task with given wait period
SetWait(waitPeriod);
action();
// Revert to the old wait period
SetWait(previousPeriod);
}
/// <summary>
/// Updates the Automation instance wait period.
/// </summary>
/// <param name="waitPeriod">New wait period.</param>
private static void SetWait(Period waitPeriod)
{
int miliseconds;
ConfigData.WaitPeriods.TryGetValue(waitPeriod, out miliseconds);
// Set the drivers instance to use the wait period.
if (Instance != null)
{
Instance.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromMilliseconds(miliseconds));
}
}
#endregion//WaitHandling
#region AppState
/// <summary>
/// Checks that the website hasn't crashed from the back end.
/// </summary>
public static void CheckForLavarelError()
{
bool error = false;
try
{
Instance.FindElement(By.ClassName("exception_message"));
error = true;
}
catch
{
// all good, could not find error content.
}
if (error)
{
throw new Exception("Lavarel threw an error");
}
}
/// <summary>
/// Clicks on the main menu button to open or close the main menu.
/// </summary>
public static void OpenCloseMenuBar()
{
try
{
IWebElement menuButton = Instance.FindElement(By.Name(ConfigData.MainMenuButtonName));
menuButton.Click();
}
catch (Exception e)
{
throw new NoSuchElementException("Could not find the Menu button element.", e);
}
}
/// <summary>
/// Asserts the logged in state agents the parameter.
/// </summary>
/// <param name="checkLoggedIn">Parameter to check agents logged in state.</param>
public static void LoggedIn(bool checkLoggedIn)
{
OpenCloseMenuBar();
bool signInFound;
bool signOutFound;
bool isLoggedIn = false;
try { Instance.FindElement(By.Name(ConfigData.SignInName)); signInFound = true; }
catch { signInFound = false; }
try { Instance.FindElement(By.Name(ConfigData.SignOutName)); signOutFound = true; }
catch { signOutFound = false; }
if (!signInFound && !signOutFound)
{
throw new ElementNotVisibleException("Unable to assert state due to unavailability of SignIn/Out links.");
}
if (signOutFound) isLoggedIn = true;
if (signInFound) isLoggedIn = false;
if (isLoggedIn != checkLoggedIn)
{
throw new Exception($"Logged in Expected: {checkLoggedIn} Actual: {isLoggedIn}");
}
}
/// <summary>
/// Signs out of the system.
/// </summary>
/// <param name="errorIfAlreadySignedOut">Determines whether to throw an error if already signed out.</param>
public static void SignOut(bool errorIfAlreadySignedOut = true)
{
try
{
LoggedIn(true);
}
catch (Exception)
{
if (errorIfAlreadySignedOut)
{
throw;
}
return;
}
IWebElement signOut = Instance.FindElement(By.Name(ConfigData.SignOutName));
signOut.Click();
Thread.Sleep(500);// wait for system to logout
}
#endregion//AppState
#endregion//Methods
}
}
There are lot of threads with the same error but I could not find a suitable answer so putting it again.
I have a wcf service and I have error handling in place and when I test the service from the wcftestclient all I get is this error info and not the original error that actually occurred.
The creator of this fault did not specify a Reason. Server stack trace: at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc) at ...
I am not sure why its not returning me the actual error. My error handling code is given below.
/// <summary>
/// Gets the holidays.
/// </summary>
/// <returns>List<HolidayProfile></returns>
[OperationContract]
[FaultContract(typeof(ExceptionFaultContract))]
List<HolidayProfile> GetHolidays();
public List<HolidayProfile> GetHolidays()
{
List<HolidayProfile> holidayProfileList = new List<HolidayProfile>();
try
{
customerBL = new CustomerBL(new CustomerRepository());
holidayProfileList = customerBL.GetHolidays();
}
catch (CustomException ex)
{
throw new FaultException<ExceptionFaultContract>(DBHelper.MapException(ex));
}
return holidayProfileList;
}
I have used two custom Exception classes here. One which is derived from Exception and other is the one which will be passed between the service and client
/// <summary>
/// Class CustomException.
/// </summary>
/// <seealso cref="System.Exception" />
public class CustomException : Exception
{
/// <summary>
/// Gets or sets the error code.
/// </summary>
/// <value>The error code.</value>
public string ErrorCode { get; set; }
/// <summary>
/// Gets or sets the error detail.
/// </summary>
/// <value>The error detail.</value>
public string ErrorDescription { get; set; }
/// <summary>
/// Gets or sets the error number.
/// </summary>
/// <value>The error number.</value>
public int ErrorNumber { get; set; }
}
and another which is the datacontract.
/// <summary>
/// Class ExceptionFaultContract.
/// </summary>
[DataContract]
public class ExceptionFaultContract : Exception
{
/// <summary>
/// Gets or sets the error code.
/// </summary>
/// <value>The error code.</value>
[DataMember]
public string ErrorCode { get; set; }
/// <summary>
/// Gets or sets the error number.
/// </summary>
/// <value>The error number.</value>
[DataMember]
public int ErrorNumber { get; set; }
/// <summary>
/// Gets or sets the error description.
/// </summary>
/// <value>The error description.</value>
[DataMember]
public string ErrorDescription { get; set; }
}
My method in the dataacess.
public List<HolidayProfile> GetHolidays()
{
Initializations
try
{
Code here...
}
catch (OracleException ox)
{
throw (DBHelper.HandleOracleException(ox));
}
catch (Exception ex)
{
throw (DBHelper.HandleException1(ex));
}
finally
{
if (connection != null)
connection.Close();
if (command != null)
command = null;
if (dataAdapter != null)
dataAdapter = null;
dataSet.Dispose();
}
return holidayProfileList;
}
My helper class which does the mapping.
/// <summary>
/// Handles the exception.
/// </summary>
/// <param name="ex">The ex.</param>
/// <returns>ExceptionFaultContract.</returns>
public static CustomException HandleException(Exception ex)
{
CustomException customException = new CustomException();
customException.ErrorDescription = ex.Message;
return customException;
}
/// <summary>
/// Maps the exception.
/// </summary>
/// <param name="ex">The ex.</param>
/// <returns>ExceptionFaultContract.</returns>
public static ExceptionFaultContract MapException(CustomException ex)
{
ExceptionFaultContract exceptionFaultContract = new ExceptionFaultContract();
exceptionFaultContract.ErrorCode = ex.ErrorCode;
exceptionFaultContract.ErrorNumber = ex.ErrorNumber;
exceptionFaultContract.ErrorDescription = ex.ErrorDescription;
return exceptionFaultContract;
}
I m getting an error if I m using the ExceptionFaultContract to be returned from data access ("Error : should be a type derived from exception") and If I try to derive the same from Exception another error saying it cannot be both serializable and derived member or something like that..
I tried lot of things nothing is clear to me...could somebody please help.
In my application i discovered that sometimes the Close() for a WCF-call/channels trowed errors.
And i did a little research on the subject and borrowed some code on the internet to get me started.
And now, I wonder is this the right way to go? or should i improve the solution or maybe implement something totally different?
Generic-Class/Static Class:
public class SafeProxy<Service> : IDisposable where Service : ICommunicationObject
{
private readonly Service _proxy;
public SafeProxy(Service s)
{
_proxy = s;
}
public Service Proxy
{
get { return _proxy; }
}
public void Dispose()
{
if (_proxy != null)
_proxy.SafeClose();
}
}
public static class Safeclose
{
public static void SafeClose(this ICommunicationObject proxy)
{
try
{
proxy.Close();
}
catch
{
proxy.Abort();
}
}
}
This is how i make calls to the WCF:
(The WCFReference is a Service Reference pointing to the WCF service adress)
using (var Client = new SafeProxy<WCFReference.ServiceClient>(new WCFReference.ServiceClient()))
{
Client.Proxy.Operation(info);
}
Here's a quick little extension method I use to safely interact with a WCF service from the client:
/// <summary>
/// Helper class for WCF clients.
/// </summary>
internal static class WcfClientUtils
{
/// <summary>
/// Executes a method on the specified WCF client.
/// </summary>
/// <typeparam name="T">The type of the WCF client.</typeparam>
/// <typeparam name="TU">The return type of the method.</typeparam>
/// <param name="client">The WCF client.</param>
/// <param name="action">The method to execute.</param>
/// <returns>A value from the executed method.</returns>
/// <exception cref="CommunicationException">A WCF communication exception occurred.</exception>
/// <exception cref="TimeoutException">A WCF timeout exception occurred.</exception>
/// <exception cref="Exception">Another exception type occurred.</exception>
public static TU Execute<T, TU>(this T client, Func<T, TU> action) where T : class, ICommunicationObject
{
if ((client == null) || (action == null))
{
return default(TU);
}
try
{
return action(client);
}
catch (CommunicationException)
{
client.Abort();
throw;
}
catch (TimeoutException)
{
client.Abort();
throw;
}
catch
{
if (client.State == CommunicationState.Faulted)
{
client.Abort();
}
throw;
}
finally
{
try
{
if (client.State != CommunicationState.Faulted)
{
client.Close();
}
}
catch
{
client.Abort();
}
}
}
}
I call it as such:
var result = new WCFReference.ServiceClient().Execute(client => client.Operation(info));
Hi i am working on creating sqlconnectivity class and i come across a problem when i tried to update the whole dataset after editing it in datagridview. Can Please anyone sugguest why i cant seem to abel to update my dataset. Here is my Class code which i used to fetch datset and update dataset.
public class clssql
{
#region private sqlvariabels
private static string _sqlconnectionstring;
private SqlDataAdapter _sqldataadapter;
private SqlCommand _sqlcommand;
private SqlConnection _sqlconnection;
private SqlCommandBuilder _sqlcommandbuilder;
private SqlTransaction _sqlTransaction;
private DataSet _ds;
private bool _Transctionbinded=false;
private string _errorstring;
#endregion
/// <summary>
/// Constructor for clssql
/// </summary>
public clssql()
{
_sqlconnectionstring = GenerateSQLConnectionString(false);
_sqlconnection = new SQLConnection(_sqlconnectionstring);
}
/// <summary>
/// BindsTransaction to the Object
/// </summary>
public void BindTransaction()
{
_Transctionbinded = true;
_sqlconnection.Open();
_sqlTransaction = _sqlconnection.BeginTransaction();
_sqlcommand.Transaction = _sqlTransaction;
}
/// <summary>
/// Releases the transaction
/// </summary>
public void ReleaseTransaction()
{
if (_errorstring=="")
{
_Transctionbinded = false;
_sqlTransaction.Commit();
_sqlconnection.Close();
}
else
{
}
_sqlTransaction = null;
}
/// <summary>
/// Generate sqlconnection string.
/// </summary>
/// <param name="hardcoded">set to true if you want hardcoded string and not from app.config generated</param>
/// <returns></returns>
public static string GenerateSQLConnectionString(bool hardcoded = false)
{
StringBuilder connstring = new StringBuilder();
if (hardcoded)
{
return #"Data Source=MAYA-PC\SQLExpress;Initial Catalog=BankDB;Persist Security Info=True;User ID=sa;Password=sql123";
}
else
{
try
{
connstring.Append("Data Source=" + ConfigurationManager.AppSettings["DataSource"] + ";");
connstring.Append("Initial Catalog=" + ConfigurationManager.AppSettings["InitialCatalog"] + ";");
connstring.Append("Persist Security Info=True;");
connstring.Append("User ID=" + ConfigurationManager.AppSettings["UserID"] + ";");
connstring.Append("Password=" + ConfigurationManager.AppSettings["Password"] + ";");
return connstring.ToString();
}
catch (Exception)
{
throw;
}
}
}
/// <summary>
/// Executes an SQL Command Text.
/// </summary>
/// <param name="Query">Query to execute</param>
/// <returns>Returns the Number of Rows Affected</returns>
public int ExecuteNonQuery(string Query)
{
try
{
int rec;
if (_Transctionbinded)
{
//Do Nothing
}
else
{
_sqlconnection.Open();
}
//_sqlconnection = new SqlConnection(_sqlconnectionstring);
_sqlcommand.CommandText = Query;
_sqlcommand.CommandType = CommandType.Text;
rec = _sqlcommand.ExecuteNonQuery();
if (_Transctionbinded)
{
//Do Nothing
}
else
{
_sqlconnection.Close();
}
return rec;
}
catch (Exception ex)
{
if (_Transctionbinded)
{
_errorstring = ex.Message;
}
else
{
_sqlconnection.Close();
}
throw;
}
}
/// <summary>
/// Directly Executes an SQL Command
/// </summary>
/// <param name="_sqlcommand"></param>
/// <returns></returns>
public int ExecuteCommand(SqlCommand _sqlcommand)
{
try
{
int rec;
if (_Transctionbinded)
{
//Do Nothing
}
else
{
_sqlconnection.Open();
}
_sqlcommand.Connection = _sqlconnection;
rec =_sqlcommand.ExecuteNonQuery();
if (_Transctionbinded)
{
//Do Nothing
}
else
{
_sqlconnection.Close();
}
return rec;
}
catch (Exception ex)
{
if (_Transctionbinded)
{
_errorstring = ex.Message;
}
else
{
_sqlconnection.Close();
}
throw;
}
}
/// <summary>
/// Get Dataset From Query
/// </summary>
/// <param name="SelectQuery"></param>
/// <returns></returns>
public DataSet GetDataset(string SelectQuery)
{
try
{
if (_Transctionbinded)
{
//Do Nothing
}
else
{
_sqlconnection = new SqlConnection(_sqlconnectionstring);
_sqlconnection.Open();
}
_sqlcommand = new SqlCommand(SelectQuery, _sqlconnection);
_sqldataadapter = new SqlDataAdapter(_sqlcommand);
_sqlcommandbuilder = new SqlCommandBuilder(_sqldataadapter);
_ds = new DataSet();
_sqldataadapter.Fill(_ds);
if (_Transctionbinded)
{
//Do Nothing
}
else
{
_sqlconnection.Close();
}
return _ds;
}
catch (Exception)
{
throw;
}
}
/// <summary>
/// Updates Dataset
/// </summary>
/// <param name="ds"></param>
/// <returns></returns>
public int UpdateDataset(DataSet ds)
{
int rec;
try
{
if (_Transctionbinded)
{
//Do Nothing
}
else
{
_sqlconnection.Open();
}
if (ds.HasChanges()) {
ds.AcceptChanges();
}
_sqldataadapter.UpdateCommand = _sqlcommandbuilder.GetUpdateCommand(true);
_sqldataadapter.InsertCommand = _sqlcommandbuilder.GetInsertCommand(true);
_sqldataadapter.DeleteCommand = _sqlcommandbuilder.GetDeleteCommand(true);
rec = _sqldataadapter.Update(ds);
if (_Transctionbinded)
{
//Do Nothing
}
else
{
_sqlconnection.Close();
}
return rec;
}
catch (Exception ex)
{
if (_Transctionbinded)
{
_errorstring = ex.Message;
}
else
{
_sqlconnection.Close();
}
throw;
}
}
}
Well i have putted my whole class here but The getdataset and update dataset are the only one that matters no need for transctions right now just for future refrences.
In the same Project when i tried this code the after editing datagridview the dataset was updated correctly. i tried and tried but dont understand why it works on the below code and doesnt work on above code..
private void LoadClick(object sender, EventArgs e)
{
string connectionString = #"Data Source=MAYA-PC\SQLExpress;Initial Catalog=CrystalTutorial;Persist Security Info=True;User ID=sa;Password=sql123";
string sql = "Select * From Customer_Orders";
SqlConnection connection = new SqlConnection(connectionString);
connection.Open();
sCommand = new SqlCommand(sql, connection);
sAdapter = new SqlDataAdapter(sCommand);
sBuilder = new SqlCommandBuilder(sAdapter);
sDs = new DataSet();
sAdapter.Fill(sDs, "Stores");
sTable = sDs.Tables["Stores"];
connection.Close();
dataGridView1.DataSource = sDs.Tables["Stores"];
dataGridView1.ReadOnly = true;
btnsave.Enabled = false;
dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
}
private void new_btn_Click(object sender, EventArgs e)
{
dataGridView1.ReadOnly = false;
btnsave.Enabled = true;
btnnew.Enabled = false;
btndelete.Enabled = false;
}
private void delete_btn_Click(object sender, EventArgs e)
{
if (MessageBox.Show("Do you want to delete this row ?", "Delete", MessageBoxButtons.YesNo) == DialogResult.Yes)
{
dataGridView1.Rows.RemoveAt(dataGridView1.SelectedRows[0].Index);
sAdapter.Update(sTable);
}
}
private void save_btn_Click(object sender, EventArgs e)
{
sAdapter.Update(sTable);
dataGridView1.ReadOnly = true;
btnsave.Enabled = false;
btnnew.Enabled = true;
btndelete.Enabled = true;
}
You should not call the AcceptChanges method before the Update. You will find the explanation to this in the Order of using AcceptChanges and TableAdapter.Update thread.