How to retrieve custome error message in Web Client request? - c#

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);

Related

How to attach file (pdf) to SOAP response?

My code (testing):
[WebMethod]
public string SoapWithAttachment(string suggestionId, int agentId)
{
byte[] bytes = null;
elemPoliciesWS.suggestionPaymentResult returnPolicyFile = new elemPoliciesWS.suggestionPaymentResult();
elemPoliciesWS.suggestion sug = new elemPoliciesWS.suggestion();
if (elem.State.ToString().ToLower() == "faulted")
{
elem = new elemPoliciesWS.IelemPoliciesWSClient();
}
sug = elem.GetSuggestionDetailsBySuggestionId(suggestionId);
if (sug != null)
{
sug.EncodedSuggestionIdStr = EncodeSuggestionId(suggestionId.ToLower());
if (sug.AgentId == agentId)
{
try
{
returnPolicyFile = elem.getPolicyMekif(sug);
bytes = Convert.FromBase64String(returnPolicyFile.Suggestion.PolicySpecificationBase64StringPDF);
File.WriteAllBytes(#"C:\Logs\file.pdf", bytes);
}
catch (Exception ex)
{
LogWriter.WriteToLog("SoapWithAttachment", " Exeception StackTrace: ", ex.StackTrace);
}
}
}
return returnPolicyFile.Suggestion.PolicySpecificationBase64StringPDF; }
Currently in SOAP response I have string in base64 format:
<SoapWithAttachmentResponse xmlns="http://ayl-vdev/webservices/">
<SoapWithAttachmentResult>JVBERi0xLjYNJeLjz9MNCjY1IDAgb2JqDTw8L0.....</SoapWithAttachmentResult>
</SoapWithAttachmentResponse>
As result I have on local machine a correct pdf file.
How can I attach this file to SOAP response that it will be downloadable to clients PC?

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

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;
}

Get a black/no image with asp.net web api

I'am posting an image from a console application to a asp.net web api. I'am getting a file in the folder but the image is black (no image). Do I have something wrong in my code?
public class UploadController : ApiController
{
[System.Web.Mvc.HttpPost]
public string Upload()
{
var request = HttpContext.Current.Request;
var filePath = Path.Combine(HttpContext.Current.Server.MapPath("~/Uploads/"), request.Headers["filename"]);
try
{
using (var fs = new System.IO.FileStream(filePath, System.IO.FileMode.Create))
{
request.InputStream.CopyTo(fs);
}
}
catch (Exception e)
{
return e.Message;
}
return "uploaded";
}
}
Edit
My console app
http://pastebin.com/VsnDMYpb
try this. This works for me. I used this for multiple file upload
var httpRequest = HttpContext.Current.Request;
foreach (string file in httpRequest.Files)
{
var postedFile = httpRequest.Files[file];
var filePath = HttpContext.Current.Server.MapPath("~/Uploads/" + postedFile.FileName);
postedFile.SaveAs(filePath);
}
Use Request.Content.ReadAsMultipartAsync
public Task<IQueryable<HDFile>> Post()
{
try
{
var uploadFolderPath = HostingEnvironment.MapPath("~/App_Data/" + UploadFolder);
log.Debug(uploadFolderPath);
if (Request.Content.IsMimeMultipartContent())
{
var streamProvider = new WithExtensionMultipartFormDataStreamProvider(uploadFolderPath);
var task = Request.Content.ReadAsMultipartAsync(streamProvider).ContinueWith<IQueryable<HDFile>>(t =>
{
if (t.IsFaulted || t.IsCanceled)
{
throw new HttpResponseException(HttpStatusCode.InternalServerError);
}
var fileInfo = streamProvider.FileData.Select(i =>
{
var info = new FileInfo(i.LocalFileName);
return new HDFile(info.Name, Request.RequestUri.AbsoluteUri + "?filename=" + info.Name, (info.Length / 1024).ToString());
});
return fileInfo.AsQueryable();
});
return task;
}
else
{
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable, "This request is not properly formatted"));
}
}
catch (Exception ex)
{
log.Error(ex);
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.BadRequest, ex.Message));
}
}
The code I get from this post

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

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");

Categories