Wednesday, May 25, 2022

Using WebAuthenticator with .NET Maui

 First create an authorization callback activity inside the Android assets folder: 

namespace MauiApp6.Platforms.Android
{
    [Activity(NoHistory = true, LaunchMode = LaunchMode.SingleTop, Exported = true)]
    [IntentFilter(new[] { Intent.ActionView },
                  Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable },
                  DataScheme = "ultranomadic")]
    internal class AuthCallbackActivity : WebAuthenticatorCallbackActivity
    {

        public override void OnCreate(Bundle savedInstanceState, PersistableBundle persistentState)
        {
            base.OnCreate(savedInstanceState, persistentState);
        }
    }
}

Modify the AndroidManifest.xml file to include this query node inside the manifest node. 

<queries>
<intent>
<action android:name="android.support.customtabs.action.CustomTabsService" />
</intent>
</queries>

Finally, use the web authenticator to login.  

            WebAuthenticatorResult authResult = await WebAuthenticator.Default.AuthenticateAsync(
                new Uri("https://planner.ultranomadic.com/auth?returnUrl=ultranomadic://planner.ultranomadic.com"),
                new Uri("ultranomadic://"));

            string accessToken = authResult?.AccessToken;

            HttpClient client = new HttpClient();
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
            var json = client.GetStringAsync("https://planner.ultranomadic.com/api/testauthget").Result;

Monday, December 27, 2021

Using Platform Specific Code Inside Xamarin.Forms

First declare an interface in the main project. Something like the following: 

namespace myapp
{
    public interface ILoginService
    {
        void DoLogin(); 
    }
}

Implement the interface in a concrete class inside the android project. 

[assembly: Dependency(typeof(myapp.Droid.AndroidLoginService))]
namespace myapp.Droid
{
    
    class AndroidLoginService : myapp.ILoginService
    {
        public void DoLogin()
        {
            /* implement here */
        }
    }
}

Notice the Dependency attribute. This registers the class with the dependency injection engine in Xamarin. Now you can use the implementation in the main project. 

var loginsvc = DependencyService.Get<ILoginService>();
loginsvc.DoLogin();

Hopefully that helps you use platform specific implementations inside Xamarin.Forms. 

Friday, April 24, 2020

Global error handling in ASPNETCore

Add the following to the StartUp.cs

if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
else
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

In the controller add the following:

[AllowAnonymous]
public IActionResult Error()
{
    return View(new ErrorViewModel 
        { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}

For access to the exception, use the IExceptionHandlerPathFeature as in the following code:

var exceptionHandlerPathFeature =
    HttpContext.Features.Get<IExceptionHandlerPathFeature>();
if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
{
    ExceptionMessage = "File error thrown";
}
if (exceptionHandlerPathFeature?.Path == "/index")
{
    ExceptionMessage += " from home page";
}

External Authentication in ASPMVC Net Core

In the StartUp.cs file a few additions are needed to make external authorization work. First, this section needs to be added to the ConfigureServices method:

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options => {
    options.LoginPath = "/auth";
    options.ReturnUrlParameter = "ReturnUrl";
})
.AddGoogle(options => {
    options.ClientId = "[yourclientid]";
    options.ClientSecret = "[yoursecret]";
    options.CallbackPath = "/auth/signin-google";
    options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})

And later on in the Configure method make sure these lines are added.

app.UseAuthentication();
app.UseAuthorization();

Note that /auth/signin-google is not a path supplied by the application. Instead the mvc middleware handles this return and hands control over to /auth/afterauth (as specified in the RedirectUri of the Challenge result. This section goes in the auth controller:

public IActionResult GoogleLogin(string returnUrl= "/")
{
    return new ChallengeResult("Google", new AuthenticationProperties {
        RedirectUri = Url.Content($"/auth/afterauth?provider=Google&returnUrl={returnUrl}")
    });
}

Saturday, April 18, 2020

Easily adding Roles to ASP.NET Core

In the Startup.cs file add the basic authorization middleware. For options, add a new policy. This policy will check for the presence of the admin role claim.

services.AddAuthorization(options => {
   options.AddPolicy("admin", policy => policy.RequireClaim(ClaimTypes.Role,"admin"));
});

In the authentication controller, add the claims to the user.

claims.AddRange(user.Roles.Select(r => new Claim(ClaimTypes.Role, r)));

In the controller you want to secure, add the header to check the policy.

[Authorize("admin")]
public class AdminController : Controller {}

Wednesday, October 30, 2019

Using HTTPS in the ASPNETCORE development server Kestrel

To use SSL with the ASP.net Core development server, Kestrel, first export your certificate to a PFX file. Add the file to your project and then add the following section to your csproj:

  <ItemGroup>
    <None Update="mydomain.pfx">
        <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
  </ItemGroup>

This addition will cause the PFX to be coped to your output directory. After adding this to your csproj, add the following section to your appsettings.json file to use the exported certificate:

"Kestrel": {
    "Endpoints": {
        "HttpsInlineCertFile": {
            "Url": "https://test.mydomain.com",
            "Certificate": {
                "Path": "mydomain.pfx",
                "Password": "mypfxpassword"
            }
        }
    }
}

Poof, you're secure.

Saturday, August 10, 2019

Json Serialzation in Entity Framework (EF Core 2.1)

I've had a number of instances where I want to serialize JSON into a single field in the database. In the past I resorted to a [NotMapped] field which held the complex object and a [JsonIgnore]d field which was serialized in EF to a Text SQL field.

I recently discovered that EF Core 2.1 includes easy value conversions! In the example below, I have a Stay entity which has a serialized Drive object. Drive is declared on SQL Server as a Text column.

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
   base.OnModelCreating(modelBuilder);


   modelBuilder.Entity<Stay>()
   .Property(s => s.Drive)
   .HasConversion(
      d => JsonConvert.SerializeObject(d),
      d => JsonConvert.DeserializeObject<Drive>(d)
   );
}


Viola! No need for the extra fields on the model class.

Monday, May 20, 2019

Using lit-html inside an ASP.MVC .NET Core application with Typescript

This is the process for getting a lit-element component up and running inside and ASP.MVC .NET Core application.


Prerequisites: .NET Core, VSCode, Node. Install these before you start. You should be able to run “dotnet”, “code”, and “npm” successfully from a command line.


Create a project directory.
md Example.Web


Change to the project directory.
cd Example.Web


Create a new ASP.MVC project inside that directory.
dotnet new mvc


Open Visual Studio Code inside the new directory.
code .


Press F5 to start debugging the new app. VSCode will prompt you for an environment. Select “.NET Core” and a launch.json file will be created inside the .vscode directory. If you want to change the way the project launches when you debug, modify this launch.json file.


Press F5 again to start debugging. VSCode should launch your default browser with the web site up and running.


Return to VSCode and open a new terminal. Install lit-element.
npm install lit-element


Npm will create a “node_modules” subdirectory in your project. Just deal with the fact that now you have this folder related to node and don’t try to change the directory. It’s not likely worth it.


Create a scripts folder.
md scripts


Inside the scripts folder use VSCode to create a new file called my-element.ts. The following should be in the file:


import { LitElement, html } from '../node_modules/lit-element/lit-element';
class MyElement extends LitElement {
render(){
  return html`<p>Hello .NET Core and lit-html</p>`;
}
}
customElements.define('my-element', MyElement);


Save the file. Also inside the scripts folder, use VSCode to create another new file called main.js. The following text should be in the file.


import { MyElement } from './my-element';


Save the file. Using your terminal window, install typescript globally if you have not previously used typscript.
npm install -g typescript


Use VSCode to create a file called “tsconfig.json” in the root of your web project. The following text should be in the file.


{
  "compilerOptions": {
      "lib": ["es6"],
      "target": "es6",
      "noImplicitAny": true,
      "removeComments": true,
      "preserveConstEnums": true,
      "sourceMap": true
  },
  "include": [  "scripts" ],
  "exclude": [ "node_modules" ]
}


Run the typescript compiler in a terminal window.
tsc


You may see some errors from the lit-html compilation. I’m not what these are about but it seems safe to ignore them for now. You should now see my-element.js and my-element.map.js inside your scripts folder.


Now install webpack globally using npm in a terminal window if you have not previously used webpack.
npm install -g webpack


Note that the typescript and webpack installs only need to be done once on your machine. For future projects, you will not need to install them again.


Use VSCode to create “webpack.config.js” in the root of your web project. The following text should be in the file


var path = require('path');


module.exports = {
mode: 'development',
entry: './scripts/main.js',
output: {
  path: path.resolve(__dirname, 'wwwroot/js'),
  filename: 'bundle.js'
}
};


This configuration will tell webpack take everything that is referenced in the main.js file and bundle it into a single file inside wwwrooot/js/bundle.js. Run webpack from a terminal.
webpack


You should now see a “bundle.js” file inside wwwroot/js.


Edit the file /Views/Home/Index.html using vscode. Paste the following lines in at the end of the file.


<script type="module" src="/js/bundle.js"></script>
<my-element></my-element>


Return to the browser and you should see your lit-html component on the page.

Monday, April 3, 2017

Publishing to a Nuget Server

First, the Nuget CLI needs to be installed on your machine. Place the .exe in a folder and add that folder to your local path. The nuget CLI exe can be found here: 

https://dist.nuget.org/

Run the following command one time to set the api key permanently for your nuget server. 

nuget setApiKey yourapikey -source http://yournugeturl

Change directories to where your .csproj file is located and run this command: 

nuget spec

The command above will generate a nuspec file. Edit the nuspec file and delete or fill in any elements without $. The $'s indicate variables that will be automatically replaced during the pack process. Do not change those elements. 

Next edit your assembly info for your project:

Edit /properties/AssemblyInfo.cs using Visual Studio

In the assembly info file you'll find all the properties for your project. I recommend that you let Visual Studio supply the build and revision numbers (so 1.0.*) as mentioned in the comments in this file. Make sure other values are set to your liking. 

Next, from a command prompt, run the following command:

nuget pack

This will package up your project and create a .nupkg file for upload to the nuget server. Now you're ready to push your package to the server. Run the following command and you're done: 

nuget push yourpack.nupkg -source http://yournugeturl

Thursday, September 17, 2015

Efficient CSS Using Child-Selectors

So, I'm working away on acaexpress.com and I find myself forgetting this over and over. I figured it would be a good idea to write a blog post about it to remind me there's a better way. 

Here's a typical use of CSS to assign margin to some images: 

<style>
    .issuerpics { margin: 15px; }
</style>

<div style="text-align:center">
    <img src="=logobluecross.png" alt="Blue Cross" class="issuerpics" />
    <img src="=logoaetna.png" alt="Aetna" class="issuerpics" />
    <img src="=logocoventry.png" alt="Coventry One" class="issuerpics" />
    <img src="=logocigna.png" alt="Cigna" class="issuerpics" />
    <img src="~=logouhone.png" alt="United Health One" class="issuerpics" />
</div>

Note that each image has a CSS class assigned to it. It's a logical technique, but not the most elegant one. Below, the parent element (div) is assigned a class and then the CSS is written to style the child elements of that class. It's less code, more readable, and in general more elegant. 

<style>
    .issuerpics img { margin: 15px; }
</style>

<div class="issuerpics" style="text-align:center">
    <img src="=logobluecross.png" alt="Blue Cross" />
    <img src="=logoaetna.png" alt="Aetna" />
    <img src="=logocoventry.png" alt="Coventry One" />
    <img src="=logocigna.png" alt="Cigna" />
    <img src="=logouhone.png" alt="United Health One" />
</div>

In general, it's best to make the code as readable as possible. Less code is usually better as long as it doesn't sacrifice readability. This change accomplishes both. 

Thursday, August 14, 2014

Lime ORM for Android

Hey friends. I wanted to let everyone know I've released a little library called Lime for Android. It's an ORM layer inspired by Microsoft's Entity Framework. I feel it has a few advantages over some of the other layers out there.

  • It's fast. Lime uses reflection to populate objects from cursors, but object inspection is done only once and cached. 
  • It's efficient. Lists of objects are backed by cursors so scrolling through huge data sets only requires conservative memory allocation. 
  • It's flexible. Most layers in Lime are exposed to make using as much or as little as necessary a simple matter of choice. 
  • It's familiar. Lime works with Android's content providers, observers, and loaders. It's all the things you already know, but easier. 
Stop by the Lime site on Bitbucket and take it for a spin. I think you'll dig it. 

Wednesday, July 9, 2014

Pull To Refresh on Android with SwipeRefreshLayout

In March of 2014, without much fanfare, Google added the SwipeRefreshLayout widget to the Android SDK. This addition formalizes the pull-to-refresh mechanism on Android. Let's take a look at how we'll use it.

First, make sure you have R19.1.0 or newer version of the Android Support Library in your project. R20 is the first version of the library to include the new layout. Once it's in your project, create a simple activity layout with the SwipeRefreshLayout at the top of the view hierarchy. While this isn't explicitly necessary, it makes sense that the entire activity be pulled down to refresh.

It is explicitly necessary that this layout have only one child. In this example, we'll make the only child a TextView for simplicity. Here's a look at our activity layout:

<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/layout" 
android:layout_width="match_parent" 
android:layout_height="match_parent">

   <TextView android:id="@+id/text1" 
   android:layout_width="wrap_content" 
   android:layout_height="wrap_content" 
   android:text="@string/hello_world" />

</android.support.v4.widget.SwipeRefreshLayout>


Now that we have the layout added, we'll need a little code to make the refresh happen. The new layout has a method to setOnRefreshListener. So let's take a look at our activity with that listener connected:

public class MainActivity extends Activity { 

   SwipeRefreshLayout layout; 
   TextView text1; 

   OnRefreshListener refreshListener = new OnRefreshListener() { 
      @Override public void onRefresh() { 
         text1.setText(new Date().toString()); 
         layout.setRefreshing(false); 
      } 
   }; 

   @Override protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);
       layout = (SwipeRefreshLayout)findViewById(R.id.layout); 
       text1 = (TextView)findViewById(R.id.text1);
       layout.setOnRefreshListener(refreshListener);
       layout.setColorSchemeResources(color.holo_blue_dark, color.holo_blue_light,color.holo_orange_dark, color.holo_green_light); 
   } 
}


Notice that we need to call layout.setRefreshing(false) when our refresh code is finished. This method stops the animation and let's the layout know that our work is done. Typically this would be called when a loader in the activity completes. 

Also, take a look at SwipeRefreshLayout.setColorSchemeResources. This method allows you to choose 4 colors to be in the animated bar while the layout is refreshing. 

SwipeRefreshLayout is a great addition to the SDK and goes a long way to standardizing a user interaction method. Implementing will give your users comfort that their app is acting in a standard fashion and also save you space on the ActionBar where your refresh button previously would have been!

Thursday, August 9, 2012

Emulating the Nexus 7 Display Properties

Ahh the new Nexus 7 tablet is a sweet piece of hardware! On top of that, it's selling like mad. Are you on the waiting list, but need to make sure your apps are ready for it? This blog post is about creating an emulator image to emulate the display of the Nexus 7.

Before we start, please read the Android developer blog post on getting ready for Nexus 7. It's a good start to our discussion. Getting Your App Ready for Jelly Bean and Nexus 7.

Now that you're up to date, you know the new tablet is one of the first to sport the tvdpi screen density. If your app isn't ready for it, you might be in trouble. So, what do we need to do to set up an emulator for this density?

  1. Open AVD Manager and create a new virtual device named "nexus_7".
  2. Unless you have set up the hardware accelerated emulator set the "Target:" to Android 2.3.3. This will run fast enough to test your apps for the display. Note that you're not creating a real Nexus 7 emulator but this will be sufficient to test your app for the display! If you really want to test Jelly Bean, you'll want to set up the hardware acceleration for your emulator. Hopefully we'll discuss that in another blog post.
  3. Set up a sufficient SD card size. 
  4. Under "Skin:" choose resolution and specify the Nexus 7 resolution of 720 x 1280. Note that we put 720 first because we want the emulator to start up in portrait mode just like the device.
  5. Under "Hardware:", choose an Abstracted LCD density of 213. This is tvdpi!
Now you're set! When you start the emulator you will probably want to set the Launch Options to scale the display to 8 inches, especially if you're on a laptop screen. Now you should be able to test your layouts for the new Nexus 7. Have fun. 


Saturday, February 18, 2012

AT&T Mobile App Hackathon Dallas

I'll be attending the upcoming Hackathon this weekend representing the Dallas GTUG. Get signed up on Eventbrite! There are still a few spots left.

About the Event:
 Mobile App Hackathons is an event geared towards getting your app, business or idea venture to market! We will provide on-the-ground technical support, known as "senseis", from AT&T, Microsoft, Amazon, HTC and others to help you accelerate the execution of your ideas/business, rapidly kickstart a prototype mobile application and spin-off a successful venture.

Cost: FREE
Kickoff: Friday, February 17, 2012 6:00PM-8:00PM
Hackathon: Saturday, February 18, 2012 at 10:00AM-8:00PM
Sign Up: http://mobileappdfw2.eventbrite.com/

Monday, November 7, 2011

Startup Weekend Google Tech Bootcamp

I'm excited to annouce the upcoming SW / GTUG Bootcamp. There will be lots of good Android information and a code jam to get you ready for Startup Weekend. Here are the details:
Startup Weekend - Google Tech Bootcamp
Admission $5
Saturday November 12, 1:00pm - 5:00pm
ng Connect Gravity Centre
2900 West Plano Pkwy Plano, TX 75075
The following topics are on the agenda with more to come soon:
  • Android Cookbook - Scraps and Ideas for Startup Weekend 
  • Getting Started with App Engine
Keep an eye on this page for updates!

Monday, September 26, 2011

Software Versioning

This post describes a strategy for version numbering software builds. We’ll assume that we have 4 digit places to work with. Before we look at how to version a build, let’s look at the audience for each section of the version number. In this example, we’ll use version v1.2.35.76.


Each section of the version has a different “owner”. By investigating what each part of the organization requires from a version number, we can plan a numbering system effectively.

Numbering Versions: 

The first two sections of a version number are owned by marketing. I mean "owned" in that the marketing organization should control what appears here. Imagine that this is the customer-facing section of your version number. From a marketing perspective, code changes may result in an increment from v1.2 to v.1.3 or we may decide to jump to v2.0. If we imagine that marketing owns the first two digits, none of the rest of the business is impacted by these decisions. We can do what's best and most meaningful for the customer.

 The third section (35 in our example) is owned by the Quality Assurance and Testing organization. In most cases, QA will want this number to perpetually increment with each build they receive. So, if they’ve just received version X.X.34.X, they will expect the next version to be X.X.35.X. This number should never reset to 0! Having assigned the 3rd section completely to QA, we can assume they will ignore every other section. Marketing will be free to increment (or decrement) the first two sections and dev can have their way with the fourth.

The fourth section (76 in the example) is owned by the development organization. Each time a build is produced to be shared outside of the developers desk, this number should be incremented. This way if a manager reports an issue, the question “What build do you have?” will always yield a useful answer. This number should also never reset to 0! By constantly incremental this number, dev will always know where a bug occurs when it is reported.

When to Version: 

As we’ve said, the final “build number” section of the version should be incremented each time a build leaves the developers desk. But when do we change the other numbers? The answer is as soon as possible.

For example, let’s say you’ve just delivered v1.2.35.76 to QA. Your very next code change should be to increment the QA section from 35 to 36 because you know that all further changes will be targeting the 36 QA release.

Similarly, as soon as marketing decides that there is funding to deliver a v1.5 of the product, we should increment our first two digits. Anyone can look in our source code system at any time and know that we're contributing code to what will become the revision 1.5.

By incrementing immediately after you generate a release, you’re ensuring that if someone pulls a build at any time, they will have the correct version number.

Thursday, May 5, 2011

Landing Activity Icons The Easy Way

Many Android applications include a landing activity or a "main page" full of icon options. Typically this activity does little more than throw intents to launch other Activities when a user clicks one of the icons. In this post, I'm going to take advantage of the onClick, tag, and drawableTop attributes of TextView to make this work with very little code.

 Let's imagine that I'd like to write a media playing application that includes main activity icons for Music, Photos, and Video. For each icon on the landing activity, I'm going to use just a tiny bit of xml in my layout:

<TextView
android:text="Music"
android:drawableTop="@drawable/icon_music"
style="@style/mainicon"
android:tag="com.example.action.MUSIC"/>


First, you'll notice that the text and drawableTop attributes specify the drawable and the text for the icon. Using drawableTop keeps you from having to define a linear layout for each icon to stack the icon on the text. Here you can do it with just the TextView element and that's all.

Second, notice the style attribute. Here's the style I've defined for a main icon:

<resources>
<style name="mainicon">
<item name="android:layout_width">100dp</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:gravity">center</item>
<item name="android:clickable">true</item>
<item name="android:onClick">click</item>
</style>
</resources>


The obvious bits of style specify the height, width, and gravity. What isn't so obvious is the definition of clickable and onClick. Basically, the onClick attribute is telling every View that has this style to execute the method called "click" in the parent Activity. But wait, hows that going to work? We're telling every icon to run exactly the same code. Here's the code for the click event method:

public void click(View view) {
   String action = (String) view.getTag();
   Intent intent = new Intent(action);
   startActivity(intent);
}


The click method pulls the tag from the view that was clicked and fires an Intent using that string as the action. Take a look again at the XML that defines our music icon. See the tag attribute?

Now, there's one final step to make this work. The AndroidMainifest.xml must be modified so that the music Activity knows how to receive the intent we're throwing. Easy:

<activity android:name=".Music">
<intent-filter>
<action android:name="com.example.action.MUSIC"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>


The intent filter will route all of the action.MUSIC intents to the Music activity. Hopefully this will simplify your code and clean things up a bit Have fun.