I have a Windows Phone 8 application whereby I am serializing an object to JSON and creating a HTTPWebRequest object and attempting to POST to a WCF Service. The problem which I am facing is that I get a: The remote server returned an error: NotFound.
This is the code in WP8:
var jsonData = JsonConvert.SerializeObject(ReportSightingRequest.Instance);
var uri = new Uri("URLGoesHere");
var webRequest = (HttpWebRequest)WebRequest.Create(uri);
webRequest.Method = "POST";
webRequest.ContentType = "application/json";
webRequest.ContentLength = jsonData.Length;
webRequest.BeginGetRequestStream(ar =>
{
try
{
using (var os = webRequest.EndGetRequestStream(ar))
{
var postData = Encoding.UTF8.GetBytes(jsonData);
os.Write(postData, 0, postData.Length);
}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
webRequest.BeginGetResponse(
ar2 =>
{
try
{
using (var response = webRequest.EndGetResponse(ar2))
using (var reader = new StreamReader(response.GetResponseStream()))
{
var received = reader.ReadToEnd();
}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
}, null);
}, null);
This is what gets spat out in the Output window:
An exception of type 'System.Net.WebException' occurred in System.Windows.ni.dll and wasn't handled before a managed/native boundary
A first chance exception of type 'System.Net.WebException' occurred in System.Windows.ni.dll
An exception of type 'System.Net.WebException' occurred in System.Windows.ni.dll and wasn't handled before a managed/native boundary
System.Net.WebException: The remote server returned an error: NotFound. ---> System.Net.WebException: The remote server returned an error: NotFound.
at System.Net.Browser.ClientHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
at System.Net.Browser.ClientHttpWebRequest.<>c__DisplayClasse.<EndGetResponse>b__d(Object sendState)
at System.Net.Browser.AsyncHelper.<>c__DisplayClass1.<BeginOnUI>b__0(Object sendState)
--- End of inner exception stack trace ---
at System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, Object state)
at System.Net.Browser.ClientHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at [Namespace].<>c__DisplayClass2.<ReportSighting>b__1(IAsyncResult ar2)
The WCF service works fine as there are other devices which use it. Using fiddler to call the request works too and a console app succeeds no problem.
Can anyone see where I am going horribly wrong?
Related
I'm using Nancy to create a web api. I have a signed token that is passed in from the user to authenticate. This authentication is doen in the RequestStartup method in my own Bootstrapper. Now in some cases, for instance when I can't veryfy the signed token I would like to just be able to throw an exception and have that handled byt the OnError hanhdler in Nancy. However an exception thrown before the RequestStartup is finsihed isn't caught. The request generates a 500 error and I would like to return something else with my own error information.
I have the obvious case where I throw an exception but also possibilities of an exception being thrown in the GetIdentity() method.
I'm looking for any input in how to handle this.
protected override void RequestStartup(TinyIoCContainer container, IPipelines pipelines, NancyContext context)
{
base.RequestStartup(container, pipelines, context);
pipelines.OnError.AddItemToStartOfPipeline((ctx, exception) =>
container.Resolve<IErrorHandler>().HandleException(ctx, exception));
var identity = container.Resolve<IAuthenticationController>().GetIdentity();
var configuration = new StatelessAuthenticationConfiguration(_ => identity);
StatelessAuthentication.Enable(pipelines, configuration);
var logManager = new LogManager(context);
pipelines.AfterRequest.AddItemToEndOfPipeline(_ => logManager.Log());
try
{
X509Certificate2 clientCert = context.Request.ClientCertificate as X509Certificate2;
container.Resolve<ICertificateValidator>().Validate(clientCert);
}
catch (Exception ex)
{
throw new MklServerAuthenticationException(ErrorCodes.WrongOrNonexistingCertificate, ex);
}
}
Figured out a way to solve the above problem and thought somebody else might like to know. Replace the line in my code above, containing the GetIdentity() call, with the following:
Identity identity = null;
try
{
identity = container.Resolve<IAuthenticationController>().GetIdentity(requestInfo);
}
catch (Exception ex)
{
var exception = new MklAuthentcationException(ErrorCodes.TokenInvalid, ex);
context.Response = container.Resolve<IErrorHandler>().HandleException(context, exception);
pipelines.BeforeRequest.Invoke(context, CancellationToken.None);
}
I'm using the fact stated in nancy that:
The PreRequest hook is called prior to processing a request. If a hook returns a non-null response then processing is aborted and the response provided is returned.
So by setting a response (my error in this case) on the PreRequest hook and invoking it my error is returned and execution is stopped.
Maybe not the nicest solution... If you can figure out something better please let me know.
I'm trying to send an object type UserEntry to the client.
the route I used was: http://localhost:3027/api/userapi/getinfo?username=myUsername
What is the cause of this error or what is wrong with my code?
[HttpGet, Route("api/userapi/getinfo")]
public async Task<string> getUserInfo([FromUri]string username)
{
UserEntry u = await UserEntry.getUserInfo(username);
return new JavaScriptSerializer().Serialize(u);
}
Here is what inner exception shows:
InnerException: {
Message: "An error has occurred.",
ExceptionMessage: "Invalid operation. The connection is closed.",
ExceptionType: "System.InvalidOperationException",
StackTrace: " at System.Data.SqlClient.SqlConnection.GetOpenConnection() at System.Data.SqlClient.SqlConnection.get_ServerVersion()"
}
I checked and made sure that there was no error in connecting with the database, but it still shows error.
I temporarily solved it by making it synchronous
I solved it by making it synchronous
[HttpGet,Route("api/userapi/getinfo")]
public SimpleUser getUserInfo([FromUri]string username)
{
var ur = new UserRepository();
return ur.getUser(username).First();
}
public IEnumerable<SimpleUser> getUser(string username)
{
UserEntryDBContext context = new UserEntryDBContext();
UserEntry u = context.Users.Where( x => x.username == username).FirstOrDefault();
List<SimpleUser> s = new List<SimpleUser>();
s.Add(new SimpleUser(u));
return s;
}
but I still have no idea what causes the error nor how can I make it asynchronous.
I am trowing Exception from WebApi as shown below
Catch(ex)
{
var rEx = HttpResponseException(r.CreateErrorResponse(HttpStatusCode.NotFound,ex));
throw rEx;
}
My question is "How to catch this Exception in Windows Application";
i.e. to catch this exception from where I am calling Web Api Method????
You will receive response with http code 500 - internal server code. So, to "catch" this exception just check response code in calling app.
That would throw a 404 response back to the client. Assuming you're using WebClient to call this service, it can be done in a couple of ways:
1) You can check for the status of the response like this:
HttpResponseMessage response = await client.GetAsync("api/products/1");
if (response.IsSuccessStatusCode)
{
//write app code.
}
2) Or.. in a try/catch fashion by checking: resp.EnsureSuccessStatusCode(), which would throw an exception if the response is not 200. Like this:
try
{
HttpResponseMessage response = await client.GetAsync("api/products/1");
resp.EnsureSuccessStatusCode(); // Throw if not a success code.
// ...
}
catch (HttpRequestException e)
{
// Handle exception.
}
It is discussed in detail here
I am using ServiceStack (the ServiceStack client is 4.0.12.0).
I have some code as below:
private async Task TestSave()
{
JsonServiceClient client = new JsonServiceClient("http://localhost:60982");
try
{
this.Items = client.Post(new ItemDescUpdateRequest() { Items = this.Items });
}
catch (WebServiceException ex)
{
HandleWebException(ex);
}
}
If I use Post and the server throws an exception. The server exception comes back correctly. I can use ex.ErrorMessage to see the message. However, If I change to:
this.Items = await client.PostAsync(new ItemDescUpdateRequest() { Items = this.Items
the exception does not get handled correctly.
The ResponseBody has data in it as does the ResponseDTO. However ResponseStatus is null. ErrorCode and ErrorMessage get a System.IndexOutOfRangeException error, I am assuming because ResponseStatus is null.
Why doesn't PostAsync work as expected?
When unit testing, I want to check csv formatted results, so I have the following code in my test.
MyDtoReq request = new MyDtoReq();
// ... assign some properties
string url = request.ToUrl("GET");
HttpWebRequest httpReq = (HttpWebRequest)WebRequest.Create(url);
httpReq.Accept = "text/csv";
csv = new StreamReader(httpReq.GetResponse().GetResponseStream()).ReadToEnd();
That works fine, if the request succeeds. But when it fails, it raises a System.Net.WebException that doesn't have the expected WebServiceException.ResponseStatus details. NUnit reports the exception as follows:
Test Name: TestReq
Test FullName: [...].TestReq
Test Source: c:\Users\[...]\UnitTestProject1\ServiceTests.cs : line 261
Test Outcome: Failed
Test Duration: 0:00:27.104
Result Message: System.Net.WebException : The remote server returned an error: (400) Bad Request.
Result StackTrace: at [...].TestReq() in c:\Users\[...]\UnitTestProject1\ServiceTests.cs:line 287
Turns out that this is by design, as most clients requesting csv format are not able to parse a ResponseStatus. In order to see the actual error, I would re-submit the request with format=html in the browser - a frustrating waste of time.
Here's how to get the actual error message from failing csv format requests:
// Declared in test setup
public const string Host = "http://localhost:1337";
private const string BaseUri = Host + "/";
[Test]
public void TestMyDtoReqCsvFormat()
{
MyDtoReq request = new MyDtoReq();
request.startDate = "20130919";
request.endDate = "20130930";
request.source = "Token";
try
{
string requestUrl = request.ToUrl("GET");
HttpWebRequest httpReq = (HttpWebRequest)WebRequest.Create(requestUrl);
httpReq.Accept = "text/csv";
var csv = new StreamReader(httpReq.GetResponse().GetResponseStream()).ReadToEnd();
// assert some facts about the contents of csv
}
catch (Exception)
{
try {
JsonServiceClient client = new JsonServiceClient(BaseUri);
MyDtoReqResponse response = client.Get(request);
// do something if re-request succeeds (i.e. was a transient error)
}
catch (WebServiceException webEx)
{
var message = webEx.ResponseStatus.ErrorCode +
" " + webEx.ResponseStatus.Message.Trim() +
" " + webEx.ResponseStatus.StackTrace.Trim();
throw new WebException(message,webEx);
}
catch (Exception otherEx) {
System.Diagnostics.Debug.WriteLine(otherEx.Message);
throw new Exception(otherEx.Message, otherEx);
}
}
}