I'm currently developing an app for windows phone 8.1 with Azure. (I wouldn't really recommend this to you after my experiences). Anyway... I've got Multiple Controller classes in it who really do the same (Check if something in my database already exists and if not it creates it). The problem I have has to be in the Read() function which checks the database if an entry already exists:
public async void Read(Device device)
{
IMobileServiceTable mobileServiceTable = Connect();
MobileServiceCollection<Device, Device> devices = null;
try
{
devices = await mobileServiceTable.MobileServiceClient.GetTable<Device>().Where(d => d.Manufacturer == device.Manufacturer && d.Model == device.Model).ToCollectionAsync();
}
catch (Exception e)
{
if (_onDeviceControllerListener != null)
{
_onDeviceControllerListener.OnError(ControllerError.Error.ReadFromDatabase, e.ToString());
}
return;
}
if (_onDeviceControllerListener != null && devices != null)
{
_onDeviceControllerListener.OnRead(devices);
}
}
This one works perfectly how it should but the oder one which is basically just a copy throws a NullReferenceException by the line "apps = await mobileServiceTab...":
public async void Read(Model.App app)
{
IMobileServiceTable mobileServiceTable = Connect();
MobileServiceCollection<Model.App, Model.App> apps = null;
try {
apps = await mobileServiceTable.MobileServiceClient.GetTable<Model.App>().Where(a => a.HardwareId == app.HardwareId && a.PackageId == app.PackageId).ToCollectionAsync();
}
catch (Exception e)
{
if (_onAppControllerListener != null)
{
_onAppControllerListener.OnError(ControllerError.Error.ReadFromDatabase, e.ToString());
}
return;
}
if (_onAppControllerListener != null)
{
_onAppControllerListener.OnRead(apps);
}
}
Does somebody know what the problem is?
Thanks for helping
You can add a try...catch block and check for the "MobileServiceInvalidOperationException" exception. Also take a look at the callstack to find out what's happening.
A fiddler trace would also let you know if you made a successful call to the Mobile Service to retrieve the data. Then you can determine if the issue lies in how you handle the data in your code.
Take another look at your MobileServiceContext class and ensure all properties are accounted for especially the properties that use the "Model.App" class. E.g
public virtual DbSet<Model.App> SomeProperty { get; set; }
Hope this helps.
Related
I`m using SQLite with multi-threading,my program is working fine but I wish to make it faster. I read that SQLite has 3 threads modes
that can be set compile time(https://www.sqlite.org/threadsafe.html) where the default is "Serialized" but from what I read, the "Multi-thread" would be faster for me.
What I don't understand is how to set SQLite to "Multi-thread" mode in Visual Studio 2013.Anyone know how can I do this? I already found questions talking about this subject but none of them showed clearly how to set this mode.
This is how to make sqlite work in multiple threads.
Use BlockingCollection with ThreadPool.QueueUserWorkItem.
Any database query are queued and executed in FIFO (First In First Out) order.
Now the database is never locked while doing any SQL transaction from any thread.
This is an example in C#.
public class DatabaseQueueBus
{
private BlockingCollection<TransportBean> _dbQueueBus = new BlockingCollection<TransportBean>(new ConcurrentQueue<TransportBean>());
private CancellationTokenSource __dbQueueBusCancelToken;
public CancellationTokenSource _dbQueueBusCancelToken { get => __dbQueueBusCancelToken; set => __dbQueueBusCancelToken = value; }
public DatabaseQueueBus()
{
_dbQueueBusCancelToken = new CancellationTokenSource();
DatabaseQueue();
}
public void AddJob(TransportBean dto)
{
_dbQueueBus.Add(dto);
}
private void DatabaseQueue()
{
ThreadPool.QueueUserWorkItem((param) =>
{
try
{
do
{
string job = "";
TransportBean dto = _dbQueueBus.Take(_dbQueueBusCancelToken.Token);
try
{
job = (string)dto.DictionaryTransBean["job"];
switch (job)
{
case "SaveClasse":
//Save to table here
break;
case "SaveRegistrant":
//Save Registrant here
break;
}
}
catch (Exception ex)
{//TODO: Handle this exception or not
}
} while (_dbQueueBusCancelToken.Token.IsCancellationRequested != true);
}
catch (OperationCanceledException)
{
}
catch (Exception ex)
{
}
});
}
}
I am currently trying to develop simple web application for my IoT school project. As for now it should only call direct methods from my Raspberry.
I am using Azure SDK for C#.
This is how code looks like:
Controller:
public ActionResult changeState(int? id, bool enable)
{
string conn_str = (from u in db.Users join h in db.Hubs on
u.Hub.HubId equals h.HubId
where u.UserName == User.Identity.Name select h.connection_str).First();
Cloud2Device c2d = new Cloud2Device(conn_str);
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Rp rp = db.Rps.SingleOrDefault(r => r.RpId == id);
if (rp == null)
{
return HttpNotFound();
}
//IoT stuff
try
{
c2d.EnableRaspberry("myDeviceId").Wait();
}
catch(Exception ex)
{
//do something
}
rp.is_enabled = enable;
db.SaveChanges();
return RedirectToAction("Index");
}
IoT utils:
public class Cloud2Device
{
private ServiceClient s_serviceClient;
public Cloud2Device(string conn_str)
{
s_serviceClient = ServiceClient.CreateFromConnectionString(conn_str);
}
public async Task EnableRaspberry(string deviceId)
{
var methodInvocation = new CloudToDeviceMethod("EnableRaspberry") { ResponseTimeout = TimeSpan.FromSeconds(2) };
var response = await s_serviceClient.InvokeDeviceMethodAsync(deviceId, methodInvocation);
Debug.WriteLine(response.GetPayloadAsJson());
}
}
The problem is that from the debug output I can see that exception Microsoft.Azure.Devices.Common.Exceptions.DeviceNotFoundException
was thrown however it is not handled by try-catch block.
console output
Application Insights Telemetry (unconfigured): "name":"Microsoft.ApplicationInsights.Dev.RemoteDependency","time":"2018-05-29T12:04:59.4748528Z","tags":{"ai.internal.sdkVersion":"rddf:2.2.0-738","ai.internal.nodeName":"5CG6455YJ4.ericsson.se","ai.cloud.roleInstance":"5CG6455YJ4.ericsson.se"},"data":{"baseType":"RemoteDependencyData","baseData":{"ver":2,"name":"/twins/myDeviceId/methods","id":"8/ZMgqG4iNc=","data":"https://utiliothub.azure-devices.net/twins/myDeviceId/methods?api-version=2017-10-15","duration":"00:00:01.2380000","resultCode":"404","success":false,"type":"Http","target":"utiliothub.azure-devices.net","properties":{"DeveloperMode":"true"}}}}
Exception thrown:'Microsoft.Azure.Devices.Common.Exceptions.DeviceNotFoundException' in Microsoft.Azure.Devices.dll
Exception thrown:'Microsoft.Azure.Devices.Common.Exceptions.DeviceNotFoundException' in mscorlib.dll
The thread 0x3834 has exited with code 0 (0x0).
Can anyone advise how I can catch and handle this exception in my application ? Thanks in advance for answer.
I'm not sure that error output is actually an exception being thrown up to your code. It could be ApplicationInsights just logging. However, I think the code is frozen due to calling Wait and blocking the return from the async method.
Make the controller method return type Task<ActionResult>, make that method async, then use await c2d.EnableRaspberry("myDeviceId"); to call that method.
See if doing that results in an exception (or success).
I've been using azure table storage for years, and I'm not sure what the "proper" way to do this is with the newest WindowsAzure.Storage library, version 5.0.1-preview (for use in a new ASP.NET 5 application):
Problem:
Given a partition key and row key, delete the row without checking for existence first, and without failing if it does not exist.
Current Solution: This code works... but the exception handling is confusing:
public async Task DeleteRowAsync(CloudTable table, string partition, string row)
{
var entity = new DynamicTableEntity(partition, row);
entity.ETag = "*";
var op = TableOperation.Delete(entity);
try
{
await table.ExecuteAsync(op);
}
catch (Exception ex)
{
var result = RequestResult.TranslateFromExceptionMessage(ex.Message);
if (result == null || result.HttpStatusCode != 404)
throw ex;
}
}
Questions:
The exception itself pointed me to this TranslateFromExceptionMessage method... I can't find a whole lot of information on that and WrappedStorageException (the type of the exception that is thrown). Is this some kind of new/preferred way to check for 404 errors on storage exceptions? Does anyone know if all storage exceptions will now use this, or do I need to write code to test and figure it out?
There is an InnerException of type StorageException. Presumably our older code that used StorageException.RequestInformation.HttpStatusCode could access this inner exception in the same way. Is that "OK", or is parsing these new XML error messages better or more robust somehow?
Is there a different approach altogether that I should be considering for this case?
If you are using the latest client (Azure.Data.Tables), the delete method automatically swallows 404 responses and does not throw. This approach avoids the need to write code that introduces race conditions (checking first before performing an operations) or having to handle this condition with a try/catch block.
If you want to know if the operation actually deleted a table or it didn't exist, you can inspect the Status property of the response.
Response response = await tableClient.DeleteAsync();
if (response.Status == (int)HttpStatusCode.NotFound)
{
// entity didn't exist)
}
The RequestResult.TranslateFromExceptionMessage method is now marked [Obsolete] and I wanted a way to ignore 404's myself.
Based on your tip to check out the RequestInformation.HttpStatusCode I came up with the following:
try
{
await table.ExecuteAsync(op);
}
catch (StorageException storEx)
{
if (storEx.RequestInformation.HttpStatusCode != 404)
{
throw;
}
}
There is a similar approach found in the AspNet WebHooks project when configured to use Azure Table Storage. Take a look at the Microsoft.Aspnet.WebHooks.custom.AzureStorage StorageManager class.
I'm not sure this adds much on top of what you'd already found, but they handle everything without throwing an exception and always return a status code so you can react to that as necessary.
One difference here is they pass in the table and the operation to a multi-purpose ExecuteAsync method, rather than having one specifically for delete, but that's just an implementation detail.
Relevant code from their example:
public async Task<TableResult> ExecuteAsync(CloudTable table, TableOperation operation)
{
if (table == null)
{
throw new ArgumentNullException(nameof(table));
}
if (operation == null)
{
throw new ArgumentNullException(nameof(operation));
}
try
{
var result = await table.ExecuteAsync(operation);
return result;
}
catch (Exception ex)
{
var errorMessage = GetStorageErrorMessage(ex);
var statusCode = GetStorageStatusCode(ex);
var message = string.Format(CultureInfo.CurrentCulture, AzureStorageResources.StorageManager_OperationFailed, statusCode, errorMessage);
_logger.Error(message, ex);
return new TableResult { HttpStatusCode = statusCode };
}
}
public string GetStorageErrorMessage(Exception ex)
{
if (ex is StorageException storageException && storageException.RequestInformation != null)
{
var status = storageException.RequestInformation.HttpStatusMessage != null ?
storageException.RequestInformation.HttpStatusMessage + " " :
string.Empty;
var errorCode = storageException.RequestInformation.ExtendedErrorInformation != null ?
"(" + storageException.RequestInformation.ExtendedErrorInformation.ErrorMessage + ")" :
string.Empty;
return status + errorCode;
}
else if (ex != null)
{
return ex.Message;
}
return string.Empty;
}
public int GetStorageStatusCode(Exception ex)
{
return ex is StorageException se && se.RequestInformation != null ? se.RequestInformation.HttpStatusCode : 500;
}
I have implemented several "stock" Microsoft Code Analysis rules. However they were lacking in one area that they didn't have detection in a catch to see if logging was implemented.
So my test project has these two methods. I would expect to see one of them raise my custom error while the other passes.
public void CatchTestNoLogging()
{
try
{ string A = "adsf"; }
catch (Exception ex)
{ throw; }
}
public void CatchTestLogging()
{
try
{ string A = "adsf"; }
catch (Exception ex)
{
log.Error("Test Error");
throw;
}
}
My custom rule is able to detect if there is a catch but I can't see how I detect if the Logging is used?
This is a SNIP of the custom rule:
if (iList[i].OpCode == OpCode._Catch)
{
isCatchExists = true; //this gets hit as I want
//so the question is what can I do to detect if logging is implemented in the catch?
}
Just a quick pointer on how I access would be great.
Thank You
Well,
It's not perfect but here is what I got. I knew / had a framework from Google of how to look for a catch block...Well that's half what I needed so I started there and that code looked like this:
if (item.OpCode == OpCode._Catch)
{
isCatchExists = true;
}
So I stepped through in the debugger to see what a catch with logging (log4net) looked like compared to no logging and see if something tangible jumps out. Well I did find this:
Exploring the log4net object I see this:
So I didn't see a way to determine that the log.error was in the catch but I can determine if there is one present. SO I wrote this:
public override ProblemCollection Check(Member member)
{
Method method = member as Method;
bool isCatchExists = false;
bool isLogError = false;
if(method != null)
{
//Get all the instrections of the method.
InstructionCollection iList = method.Instructions;
foreach (Instruction item in iList)
{
#region Check For Catch
if (item.OpCode == OpCode._Catch)
{
isCatchExists = true;
}
#endregion
#region Check for Error Logging (log4net)
if (item.Value != null)
{
if (item.OpCode == OpCode.Callvirt && item.Value.ToString() == "log4net.ILog.Error")
{
isLogError = true;
}
}
#endregion
}
if (isCatchExists && !isLogError)
{
Problems.Add(new Problem(this.GetNamedResolution("AddLogging", member.FullName)));
}
}
return this.Problems;
}
This works but with some caveats.
This is hardcoded to log4net.
a. I don't like the hard code but I would likely add a different rule for other logging methodologies anyway.
I can't determine if the log.error is IN the catch block.
a. So a person could have a log.error in the try block and my rule would pass it.
In the below code i got an error "Object reference not set to an instance of an object" in the line of the 'if' condition. Can any one help me with what is wrong with my code.
public string MemberLogOut()
{
string ret = string.Empty;
try
{
if (HttpContext.Current.Session.Count > 0)
HttpContext.Current.Session.Clear();
ret="1";
}
catch (SqlException ex)
{
throw new Exception(ex.Message);
ret="2";
}
return ret;
}
As long as you have System.Web referenced in your using statements, then you should be able to use this:
if (Session != null) {Session.Clear();}
Or
if (Session != null) {Session.Abandon();}
Im not sure why you would you return a string which holds an integer though. A boolean value would make more sense, but you really shouldn't need anything in this context.
Also, your exception handler is attempting to catch a sqlexception, which could also be a source of an object reference error, as you don't appear to have any SQL objects in this function.
I'd probably do this following:
protected bool MemberLogOut()
{
try {
if (Session != null) {Session.Abandon();}
//do any logging and additional cleanup here
return true;
} catch {
return false;
}
}
Edit: if you are in fact calling from outside of your web project, you can just pass the current httpcontext to the following method:
protected bool MemberLogOut(HttpContext context)
{
try {
if (context != null && context.Session != null) {
context.Session.Abandon();
}
//do any logging and additional cleanup here
return true;
} catch (Exception ex) {
//log here if necessary
return false;
}
}
Can any one help me with what is wrong with my code
I guess that you are running this code outside an ASP.NET application. HttpContext.Current exists only inside the context of a web application. If you ever attempt to run this code outside (for example in a console, desktop, unit test, ...) it's never gonna work.
So if this is some sort of code that is in a class library intended to be reused across different applications you will have to remove the dependency on the HttpContext from it.
Side remark: your if condition seems kinda useless as you are doing exactly the same thing in the else as well as in the if -> clearing the session.
try that code
public string MemberLogOut()
{
string ret = string.Empty;
try
{
if (HttpContext.Current.Session!=null)
{HttpContext.Current.Session.Clear();}
}
catch (SqlException ex)
{
throw new Exception(ex.Message);
}
return "1";
}