Error accessing wcf service asynchronously in c# .net: unauthorised - c#

I am building a standard odata client using: Microsoft.Data.Services.Client.Portable Windows 8 VS2013
I have added a service reference to the project (TMALiveData) with authorisation. Now I want to retrieve data but when I do I get the following error: DataServiceQueryException.InvalidOperationException
I looked at the DataServiceQueryResult object the status code is: System.Net.HttpStatusCode.Unauthorized
When I added the reference it asked me for my credentials, so I assumed this would be sent with each query, but it clearly isn't. How do I add the credentials (password and username) in the DataServiceQuery object? Below is my current code:
public class testLSCon
{
static string mResult;
public static string result { get { return mResult; } }
public static void testREADLiveConnection()
{
Uri tmaLiveDataRoot = new Uri("https://xxx.azurewebsites.net/xxx.svc/");
TMLiveData.TMALiveData mLiveData = new TMLiveData.TMALiveData(tmaLiveDataRoot);
mResult = null;
DataServiceQuery<TMLiveData.JobType> query = (DataServiceQuery<TMLiveData.JobType>)mLiveData.JobTypes.Where(c => c.IsActive == true);
mResult = "Trying to READ the data";
try
{
query.BeginExecute(OnQueryComplete, query);
}
catch (Exception ex)
{
mResult = "Error on beginExecute: " + ex.Message;
}
}
private static void OnQueryComplete(IAsyncResult result)
{
DataServiceQuery<TMLiveData.JobType> query = (DataServiceQuery<TMLiveData.JobType>) result.AsyncState;
mResult = "Done!";
try
{
foreach (TMLiveData.JobType jobType in query.EndExecute(result))
{
mResult += jobType.JobType1 + ",";
}
}
catch (DataServiceClientException ex)
{
mResult = "Error looping for items: (DataServiceClientException)" + ex.Message;
}
catch (DataServiceQueryException ex2)
{
mResult = "Error looping for items: (DataServiceQueryException)" ;
}
catch (Exception ex3)
{
mResult = "Error looping for items: (general exception)" + ex3.Message;
}
}
}

You can either set it to the credentials of the current user (so the credentials of the user the client is running as)
mLiveData.Credentials = CredentialCache.DefaultCredentials;
or if you need to impersonate another user you can use this (obviously swap the strings for the details you need - maybe passed in from config.
mLiveData.Credentials = new System.Net.NetworkCredential("UserName", "Password", "Domain");

Related

Cannot invoke method or retrieve property from null object. Object returned by the following call stack is null

I'm using CSOM and azure functions to create site collection.My workflow is first using GetAzureADAppOnlyAuthenticatedContext to get admin clientcontext,after site being created.Get the site collections clientcontext and then set site property such as add user to group,site owner etc.
It works well when debug local,but sometimes got error below:
Cannot invoke method or retrieve property from null object. Object returned by the following call stack is null. \"AssociatedOwnerGroup\r\nRootWeb\r\nSite\r\nMicrosoft.SharePoint.SPContext.Current\r\n\""
and my code like this:
public ClientContext GetAzureADOnlyClientContext(string SiteUrl, string appId, string tenant, X509Certificate2 certificate,bool isadmin)
{
ClientContext newClientContext;
try
{
newClientContext = new AuthenticationManager().GetAzureADAppOnlyAuthenticatedContext(SiteUrl, appId, tenant, certificate);
if (!isadmin)
{
Web web = newClientContext.Web;
newClientContext.Load(web, w => w.Url);
}
newClientContext.ExecuteQuery();
return newClientContext;
}
catch (Exception ex)
{
newClientContext = null;
if (_logHelper != null)
{
_logHelper.writeLog("GetAzureADContextError:"+ex.Message, TraceLevel.Error, ex);
}
return null;
}
}
in main function
while (ctxNew == null && count <= Constants.NEWSITE_TRYCOUNT)
{
logHelper.writeLog(string.Format("Site is being provisioned, waiting for {0} seconds ({1})", Constants.NEWSITE_SLEEP_SECONDS, count));
Thread.Sleep((int)Constants.NEWSITE_SLEEP_SECONDS * 2000);
//ctxNew = spHelper.GetClientContextByCredential(cred, true);
ctxNew = spHelper.GetAzureADOnlyClientContext(hostUrl, spAzureAppId, spTenant, certificate,false);
count++;
}
if (ctxNew == null)
{
logHelper.writeLog("New site collection could not be retrieved from " + hostUrl);
}
else
{
logHelper.writeLog("New site collection is created.");
Thread.Sleep((int)Constants.NEWSITE_SLEEP_SECONDS * 1000);
processRequestHelper = new ProcessRequestHelper(admClientContext, ctxNew, tenant, siteCreationInfo, log);
processRequestHelper.UpdateSite();
logHelper.writeLog(hostUrl + " has been updated.");
}
public void UpdateSite()
{
_logHelper.writeLog("Updating " + _newClientContext.Url);
string description = _siteProperties.Description;
string[] siteOwners = _siteProperties.BusinessOwnerEmail.Split(';');
string[] members = _siteProperties.MemberEmails.ToArray();
_tenant.SetSiteAdmin(_newClientContext.Url, _siteProperties.TechnicalOwnerEmail, true);
_adminClientContext.ExecuteQuery();
if (siteOwners.Length > 0)
{
AddGroupUser(_newClientContext.Site.RootWeb.AssociatedOwnerGroup, siteOwners);
}
if (members.Length > 0)
{
AddGroupUser(_newClientContext.Site.RootWeb.AssociatedMemberGroup, members);
}
if (!string.IsNullOrWhiteSpace(description))
{
_newClientContext.Site.RootWeb.Description = description;
_newClientContext.Site.RootWeb.Update();
}
try
{
if (_newClientContext.HasPendingRequest)
{
_newClientContext.ExecuteQuery();
}
_logHelper.writeLog("Site updated!");
}
catch (Exception ex)
{
_logHelper.writeLog("Update site error:"+ex.Message, TraceLevel.Error, ex);
throw;
}
}
private void AddGroupUser(Group grp, string[] usernameArr)
{
foreach (string username in usernameArr)
{
try
{
_logHelper.writeLog("Add User " + username + " to group.");
User user = _newClientContext.Web.EnsureUser(username);
_newClientContext.Load(user);
grp.Users.AddUser(user);
_newClientContext.ExecuteQuery();
}
catch (Exception ex)
{
_logHelper.writeLog("Add User " + username + ": " + ex.Message, TraceLevel.Error, ex);
}
}
}
It seems that sometimes the clientconetxt goes null in azure funtion

Best way to get the error from a class method to web api call

I have a class that works in inserting the data correctly but this function is communicating with a webapi.
How do i return the exception information to the web api probably from a shared libary?
public void AddStockTransfer(StockTransfer item)
{
using (var connection = new SqlConnection(ConfigurationManager.AppSettings["DataConnectionLive"]))
{
connection.Open();
string insertQuery = #"
INSERT INTO[fuel].[StockTransfer]
([StockTransferGuid]
,[StockItemId]
,[Quantity]
,[SourceWarehouseId]
,[SourceBin]
,[TargetWarehouseId]
,[TargetBin]
,[DateTimeCreated]
,[DateTimeLastUpdated]
,[StockTransferStatus]
,[StatusMessage])
VALUES (#StockTransferGuid,#StockItemId,#Quantity,#SourceWarehouseId,#SourceBin,#TargetWarehouseId,#TargetBin,#DateTimeCreated,#DateTimeLastUpdated,#StockTransferStatus,#StatusMessage)";
var mydate = DateTime.Now;
var mydate2 = DateTime.Now;
var result = connection.Execute(insertQuery, new
{
item.StockTransferGuid,
item.StockItemId,
item.Quantity,
item.SourceWarehouseId,
item.SourceBin,
item.TargetWarehouseId,
item.TargetBin,
mydate,
mydate2,
item.StockTransferStatus,
item.StatusMessage
});
}catch (Exception ex)
{
logger.Warn("Connection string is " + connection.ConnectionString.ToString());
logger.Warn("Error occoured on add stock transfer funciton " + ex.Message.ToString());
}
}
}
I want to pass what the logger is seeing, and pass it to my web method.
[HttpPost]
public ActionResult Create(StockTransfer stockTrans)
{
try
{
database.AddStockTransfer(stockTrans);
}
catch (Exception ex)
{
logger.Warn("Error on Create ex");
}
return Json(true);
}

Site not working Error if the function is not working

I have a function which checks and authenticates the User and on that basis the data is displayed to the respective User. And the function name is Get_AuthenticateUser_Ums(strUserName);
I call this function on Page_load. This function contains a web service. Now what I want is whenever the service is not working or has some issue, I want that the site should not be displayed to the user and message should prompt as The service is down, so couldnt load the site.
Below is my code
if (!IsPostBack)
{
Get_AuthenticateUser_Ums(strUserName); }
And function
private void Get_AuthenticateUser_Ums(string strUserName)
{
try
{
strReturnMessage = string.Empty;
Boolean bolReturn = ObjUMS.AuthenticateApplicationAccess(strUserName, strAppUrl, out strReturnMessage);
if (bolReturn)
{
DataSet dsUserGroups = new DataSet();
dsUserGroups = ObjUMS.GetUserAppDetailsbyUserNameApplicationUrl(strUserName, strAppUrl, out strReturnMessage);
if (dsUserGroups.Tables[1] != null && dsUserGroups.Tables[1].Rows.Count > 0)
{
string strSubGroupName = dsUserGroups.Tables[1].Rows[0]["SUBGROUP_NAME"].ToString();
if (strSubGroupName == "UBR Requester")
{
if (dsUserGroups.Tables[2] != null && dsUserGroups.Tables[2].Rows.Count > 0)
{
string[] allStates = dsUserGroups.Tables[2].AsEnumerable().Select(r => r.Field<string>("BOUNDARY_VALUE")).ToArray();
ViewState["States"] = string.Join(",", allStates);
}
}
else
{
Response.Redirect("~/NotAuthorize.aspx", false);
}
}
else
{
Response.Redirect("~/NotAuthorize.aspx", false);
}
}
else
{
Response.Redirect("~/NotAuthorize.aspx", false);
}
}
catch (Exception ex)
{
throw ex;
}
}
you can create a Method to check connection using the url to svc , and which returns a boolean based on that you can able to see whether the Service is up or not
public bool checkConnection(){
var url = "http://nvmbd1bkh150v02/UMSService/UserProvider.svc";
bool tosend = false;
try
{
var myRequest = (HttpWebRequest)WebRequest.Create(url);
var response = (HttpWebResponse)myRequest.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
{
tosend = true ;
// it's at least in some way responsive
// but may be internally broken
// as you could find out if you called one of the methods for real
Debug.Write(string.Format("{0} Available", url));
}
else
{
tosend = false;
// well, at least it returned...
Debug.Write(string.Format("{0} Returned, but with status: {1}",
url, response.StatusDescription));
}
}
catch (Exception ex)
{
// not available at all, for some reason
Debug.Write(string.Format("{0} unavailable: {1}", url, ex.Message));
}
return tosend;
}

How to retrieve custome error message in Web Client request?

Server side code to return file
[HttpGet]
public HttpResponseMessage GetVersionList(string Credentials, string VersionNumber)
{
try
{
string UserLoginStatus = objUtility.LoginUser(objUtility.GetUserName(Credentials), objUtility.GetPassWord(Credentials));
if (UserLoginStatus == "OK")
{
var path = objUtility.GetFileName(VersionNumber);
if (path != null)
{
return FileAsAttachment(path, VersionNumber + ".exe");
}
else
{
return Request.CreateErrorResponse(HttpStatusCode.OK, "File Not Found.");
}
}
else
{
// Return reason why it failed.
// It could be not authorized user, Not Active user, UID/Password wrong etc.
// Store into UserLoginStatus variable and pass show to client
return Request.CreateResponse<string>(HttpStatusCode.OK, UserLoginStatus);
}
}
catch (System.Exception ex)
{
return Request.CreateResponse<string>(HttpStatusCode.OK, ex.Message);
}
}
// Win app code to download file
using (WebClient webClient = new WebClient())
{
try
{
webClient.DownloadFile(serverUrl, (txtPath.Text + "\\" + txtVersion.Text + ".exe"));
}
catch (WebException wex)
{
// Show error message here
}
}
}
catch (Exception ex)
{
lblStatus.Text = ex.InnerException + " <br> " + ex.Message;
}
}
This is how I did it recently for a rest service I wrote for a POS. (myErrorType is just a dummy for whatever class you are actually using...)
using (var response = request.GetResponse())
{
using (var reader = new StreamReader(response.GetResponseStream()))
{
var reply = reader.ReadToEnd();
myErrorType result = Newtonsoft.Json.JsonConvert.DeserializeObject<myErrorType>(reply);
return result.Status;
// do something with the results
}
}
To Throw a custom error :
myErrorType errresponse = new myErrorType();//dummy class, create your own...
throw new WebFaultException<myErrorType>(errresponse, HttpStatusCode.BadRequest);

How can I use User Agent to detect request is Coming from desktop or mobile?

Here Is My method where I am getting userdetails who logging my application.I want to check the request is coming from desktop or mobile,using User agent.How can I do this?
public UserDetails Authenticate()
{
try
{
_logger.Info("authenticating...");
var message = OperationContext.Current.RequestContext.RequestMessage;
var request = (HttpRequestMessageProperty)message.Properties[HttpRequestMessageProperty.Name];
string token = request.Headers[HttpRequestHeader.Authorization];
var base64decodedtoken = this.Base64Decode(token);
UserBLL user = new UserBLL();
var userdetails = user.GetUserDetails(base64decodedtoken, true);
if (userdetails.UserId > 0)
{
_logger.Info("authentication successfull... for user id" + userdetails.UserId);
int i = user.AuditUserLogin(userdetails.Email);
}
else
{
_logger.Info("Unauthorised Access" + userdetails.Email);
}
return userdetails;
}
catch (Exception ex)
{
_logger.Error("Error Occured in Authentication Service", ex);
ErrorData errorData = new ErrorData("Error Occured ", ex.Message);
throw new WebFaultException<ErrorData>(errorData, HttpStatusCode.Unauthorized);
}
}
Please refer to this MDN article for your answer.
Basically, the mobile/desktop detection by user-agent is not suggested, but if you have to get your work sorted in this way, you can also refer to this link

Categories