Dailycode.info

Short solution for short problems

iOS: Check if device is iPad or not

I have some screen that have different behaviour depending if its an iPad or not. Because iPad screen is a lot larger,  for iPhone I sometimes use a sub screen to lookup certain data, as for on the iPad I can keep it on screen. Not to easily check for iPad add these two lines to your class, or if used in different classes add it to your precompiled header file:

#define IDIOM    UI_USER_INTERFACE_IDIOM()

#define IPAD     UIUserInterfaceIdiomPad

Now you can check for iPad like this:

if (IDIOM == IPAD)

{

    iPad      

}

else

{

    iPhone

}


.Net WebAPI: add time zone suffix to datetime in JSON

On iOS, my JSON formatter needed to have the UTC format for date times. But My .Net WebAPI by default just formatted the date like this:

"timeStamp":"2015-01-04T00:00:00"

now just by adding these lines to the WebApiConfig.cs:

var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;

json.SerializerSettings.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc;

the date times got the correct format:

"timeStamp":"2015-01-04T00:00:00Z"


.Net WebAPI: A potentially dangerous Request.Path value was detected from the client (:).

Ever got this error?

A potentially dangerous Request.Path value was detected from the client (:).

I was trying to give a datetime in the url as parameter to a REST service. but when I used data time, the following error occurred.

http://localhost/Users/GetPlanForDate/2015-1-5%2008:00

First I changed the route, making the date a querystring.

http://localhost/Users/GetPlanForDate?date=2015-1-5%2008:00

This worked fine, but then I would have to change to many routes. So finally the solution came up.

I could just remove the ':' as potentially dangerous sign. The can be done in the web.config of your project:

Change this line:

<httpRuntime targetFramework="4.5" />

into this:

<httpRuntime targetFramework="4.5" requestPathInvalidCharacters="&lt;,&gt;,*,%,&amp;,\,?" />

Now the time using the ':' will be passed to your web api.

Some functions have the datetime as first parameter, but have more following, like this:

http://localhost/Users/GetPlanForDate/2015-1-5%2008:00/1

So in this case it's nice that you can use the Route parameters for datetime.

[Route("Users/GetPlanForDate/{date}/{shift}")]

public GalvaSFIMobileDataLayer.GP_MES_ShiftPlans GetPlanForDate(DateTime date, int shift)

{

            //GetMESHeaders(OperationContext.Current);

            return PL.GetPlanForDate(date, shift);

}


AngularJS - WebAPI: No 'Access-Control-Allow-Origin'

Got this error: XMLHttpRequest cannot load http://localhost:777/api/products/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:777' is therefore not allowed access. The response had HTTP status code 405.

It was not so easy to sfind out what the problem was, but then it had something to do with enabling cross origin requests. When you are developing WebAPI back end that is not on the same uri as the front end angular JS site, it could be that you have this error. I even got it on my local host, using different ports for the 2 sites. Simple solution, which will help to secure the WebAPI.

You will first have to allow the cros origin requests in your WebApiconfig.cs:

config.EnableCors();

If VS gives problems, then use the nuget package manager to add this


Then first add this code to the WebApiConfig:

config.EnableCors();

And then you will have to allow ip to connect to your webapi in your controllers like this:

// GET: api/Products/Mark  
[EnableCors("http://localhost:778","*","*")] 
public List<Product> GetProduct()
You can also allow all methods in your API by putting the EnableCors attribute above the class:

using System.Web.Http.Cors;

namespace MyProject.Controllers

{

    [EnableCors("http://localhost:778", "*", "*")]

    public class UsersController : ApiController


iOS: How to add a precompiled header file

Sounds stupid, since before this was default behaviour. Now a project starts without. Adding can sometimes be a pain, since just adding the file is not enough. 

This post helped me to the solution, although I head to change 1 more thing.

So the thing was to open the Build settings in xcode of your target. You will see a search box on the upper right corner.

Search for: GCC_PRECOMPILE_PREFIX_HEADER and set it to Yes.

Next search for: GCC_PREFIX_HEADER and add the name of the file including the extension ".pch".

Now it was still not compiling, because the file was not in the root directory of where the project file was, but rather in a subdirectory. So I had to put in the value:

MyProgram/MyProgramPrefixHeader.pch

Now everything compiled again and the prefix header is loaded!


LINQ: Left outer join (non relational DB)

If you want to get data en detail data, from for example Routes. You will need to select the data and the details and then select only the distinct records. If your model framework support relations (Foreing key) then it easier to accomplish with LINQ. But in my case the relations were not set in the object model.

So this is how I get all routes with a detail that have a certain status, or routes that have no details:

var routes = from r in Ents.Routes

                from rd in Ents.RouteDetails.Where(s => s.RouteID == r.RouteID).DefaultIfEmpty()

                where (rd.Status == 10 || rd.Status == null)

select r;

 

var distinctRoutes = routes.Distinct<Routes>();

I cannot use the join with LINQ because there are no relations between the objects, so I select all routes with details that have status 10 or routes that have no details. The .DefaultIfEmpty will add an empty RouteDetail object to the list if it has no detail. So in the were I can check for null, then it includes the Routes that have no details. Now there can be duplicates because some routes have more detials. If we only select the Routes (select r) then the object with different details have the same Route object, so the distinct at the end will clear the duplicates.

 


VS 2010/2012 crashes when opening designer.

This can be a really time eating problem. In my case this problem came suddenly, in a class that didn't change for a long time. 

The error looked something like this:

Faulting application name: devenv.exe, version: 10.0.40219.1, time stamp: 0x4d5f2a73

Faulting module name: KERNELBASE.dll, version: 6.1.7601.18409, time stamp: 0x53159a86

Exception code: 0xe0434352

Fault offset: 0x0000c42d

Faulting process id: 0x1898

Faulting application start time: 0x01d00d526a76a093

Faulting application path: C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe

Faulting module path: C:\Windows\syswow64\KERNELBASE.dll

Report Id: f6f5bf23-7945-11e4-afad-02004e435049

When you experience this kind of behavior, it could be that an add-in is causing the problem or some update of software. In our case this didn't help.

So at the end we found that is was a problem in the page load of a form, it gets executed when you open the designer. We had some code that went to the database. The strange this is that this worked for years and now suddenly it starts crashing on all development PC's. The solution to this problem is to prevent the code from being run at design time by using the System.ComponentModel.LicenseManager.UsageMode:

Private Sub BaseForm_Load(ByVal sender As Object, ByVal e As System.EventArgs)

Handles Me.Load

    Try

       If System.ComponentModel.LicenseManager.UsageMode = System.ComponentModel.LicenseUsageMode.Runtime Then

          HandleFormDisableButtons()

          Translate()

       End If

    Catch ex As Exception

ExceptionHandling.ShowException(ex)

    End Try

 

End Sub


.Net: using dynamic columns in orderby with LINQ

I have a LINQ query that uses dynamic order by columns. The web client passes an array of key value objects and based on these objects I want to order the LINQ query.

After some googling around I found that the System.Linq.Dynamic namespace has the solution to this!

Add the Linq.Dynamic using the nuget package manager.

Then add the namespace to your class:

using System.Linq.Dynamic;

Now I dynamically build the order by string:

string orderby = String.Join(", ", orderByList.Select(o => o.Key + " " + o.Value ));

For example the orderby string holds this value “SalesOrder DESC CustomerName DESC”. Next we just add the string to the orderby, because you added the namespace in your class, the extensions is available and you can pass a string to the orderby:

List<PlanOrders> lst = PlanEnts.PlanOrders.Where(p => (p.PlanStatus < 100)).OrderBy(orderby).ToList();


LINQ: Group by multiple properties and select only max per group.

I want to get some records from an existing list. The records have to be delivered=false, then from these records I only want the record with the maximum sales order position.

The records could look like this: (ShipID,  SalesOrder, created, createdby, modified, modifiedby)

8431  35602577830  2014-10-15 08:48:29.750  Deraeve Mark @ CORDOBA  2014-10-15 08:57:30.543  MDeraeve@GPA.MES.009

8431  35602577840  2014-10-15 08:48:35.497  Deraeve Mark @ CORDOBA  2014-10-15 08:57:30.553  MDeraeve@GPA.MES.009

8432  24500068130  2014-10-15 09:02:54.577  Deraeve Mark @ CORDOBA  2014-10-15 09:03:45.313  MDeraeve@GPA.MES.009

8433  35602579130  2014-10-15 09:03:13.167  Deraeve Mark @ CORDOBA  2014-10-15 09:03:40.630  MDeraeve@GPA.MES.009

8434  35602583730  2014-10-15 14:32:22.790  Deraeve Mark @ CORDOBA  2014-10-15 14:32:22.790  Deraeve Mark @ CORDOBA

8434  35602583740  2014-10-15 14:32:22.803  Deraeve Mark @ CORDOBA  2014-10-15 14:32:22.803  Deraeve Mark @ CORDOBA

So I only want the get these records at the end:

8431  35602577840  2014-10-15 08:48:29.750  Deraeve Mark @ CORDOBA  2014-10-15 08:57:30.553  MDeraeve@GPA.MES.009

8432  24500068130  2014-10-15 09:02:54.577  Deraeve Mark @ CORDOBA  2014-10-15 09:03:45.313  MDeraeve@GPA.MES.009

8433  35602579130  2014-10-15 09:03:13.167  Deraeve Mark @ CORDOBA  2014-10-15 09:03:40.630  MDeraeve@GPA.MES.009

8434  35602583740  2014-10-15 14:32:22.790  Deraeve Mark @ CORDOBA  2014-10-15 14:32:22.803  Deraeve Mark @ CORDOBA

Now the LINQ query how to get this:

public List<GP_MES_ShippingToDo> GetShippingToDoOrders()

{

var query = Ents.GP_MES_ShippingToDo.Where(s => s.Delivered == false)

                .GroupBy(x => new { x.ShipID, x.SalesOrder })

                .Select(group => group.Where(x => x.SalesOrderPos == group.Max(y => y.SalesOrderPos))

                 .FirstOrDefault());

return query.ToList();

}

 

 


iOS: Unhandled exception handling

Application crashes are very frustrating, especially if you do not know what happened. Lets says a memory problem on an old iPad 2 or recently we had a missing storyboard, but the app only crashed when archived and deployed, not when we were debugging. Probably some files were not cleaned and still  there in debug mode. Anyway, a very easy way to capture any unhandled exception is to add this small piece of code to your app delegate:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{

    NSSetUncaughtExceptionHandler(&onUncaughtException);

Then add the onUncaughtException method and do whatever you want to do with it. I write the error to the internal DB, so later I can see on the client what happened.

void onUncaughtException(NSException* exception)

{

  NSLog(@"uncaught exception: %@", exception.description);

  NSArray *backtrace = [exception callStackSymbols];

  NSString *version = [[UIDevicecurrentDevice] systemVersion];

  NSString *message = [NSStringstringWithFormat:@"OS: %@.\nSummary:%@\nBacktrace:\n%@",

                       version,

                       exception.description,

                       backtrace];

  

  [DBStoreCreateErrorLog:@"Uncaught exception occurred"AndText:message];

}