> ## Documentation Index
> Fetch the complete documentation index at: https://help.cryptolens.io/llms.txt
> Use this file to discover all available pages before exploring further.

# .NET: ExtensionMethods

> Signatures, models and behavior for SKM.V3.ExtensionMethods in the .NET SDK 4.0.54.

The extension methods are not thought to be used through this class, but instead
through the relevant objects that they affect. Please see the examples below.

**Namespace:** `SKM.V3`\
**Version:** 4.0.54. Both packages; all six documented target frameworks.

<CodeGroup>
  ```csharp C# theme={null}
  public static class ExtensionMethods
  ```

  ```vb VB.NET theme={null}
  Public Module ExtensionMethods
  ```
</CodeGroup>

## Loading a Saved Response

Use `SKM.V3`, `SKM.V3.Methods` and `SKM.V3.Models` (with `using` in C# or `Imports` in VB.NET). Replace `YOUR_RSA_PUBLIC_KEY` with your RSA public key. `licensefile.skm` is the file saved earlier; `3` is the example maximum age in days. Loading verifies the signature, and the next call adds the age check. This example does not check expiry or machine binding; see [Offline Verification](/examples/offline-verification).

<CodeGroup>
  ```csharp C# theme={null}
  string rsaPublicKey = "YOUR_RSA_PUBLIC_KEY";
  var license = new LicenseKey().LoadFromFile("licensefile.skm", rsaPublicKey);

  if (license.HasValidSignature(rsaPublicKey, 3).IsValid())
  {
      Console.WriteLine("Signature and signed cache age checked.");
  }
  else
  {
      Console.WriteLine("Could not use this cached response.");
  }
  ```

  ```vb VB.NET theme={null}
  Dim rsaPublicKey As String = "YOUR_RSA_PUBLIC_KEY"
  Dim license = New LicenseKey().LoadFromFile("licensefile.skm", rsaPublicKey)

  If license.HasValidSignature(rsaPublicKey, 3).IsValid() Then
      Console.WriteLine("Signature and signed cache age checked.")
  Else
      Console.WriteLine("Could not use this cached response.")
  End If
  ```
</CodeGroup>

## Methods

<a id="contains-115b988413" />

### Contains(List\<DataObject>, string)

Checks if the list contains an object with a specific name.

<CodeGroup>
  ```csharp C# theme={null}
  public static bool Contains(this List<DataObject> dataObjects, string name)
  ```

  ```vb VB.NET theme={null}
  Public Shared Function Contains(dataObjects As List(Of DataObject), name As String) As Boolean
  ```
</CodeGroup>

**Parameters**

| Name | Type | Description |
| - | - | - |
| `dataObjects` | `List` of [`DataObject`](/libraries/dotnet-reference/data-object) | |
| `name` | `string` | The name of the data object |

**Returns:** `bool`. True if the data object with the specific name exists and false otherwise.

<a id="get-053ca64adb" />

### Get(List\<DataObject>, string)

Returns a data object with the specified name.

<CodeGroup>
  ```csharp C# theme={null}
  public static DataObject Get(this List<DataObject> dataObjects, string name)
  ```

  ```vb VB.NET theme={null}
  Public Shared Function [Get](dataObjects As List(Of DataObject), name As String) As DataObject
  ```
</CodeGroup>

**Parameters**

| Name | Type | Description |
| - | - | - |
| `dataObjects` | `List` of [`DataObject`](/libraries/dotnet-reference/data-object) | |
| `name` | `string` | The name of the data object |

**Returns:** [`DataObject`](/libraries/dotnet-reference/data-object). The data object if the data object with the specific name exists and null otherwise.

<a id="has-feature-5fc9e84425" />

### HasFeature(LicenseKey, int)

Checks so that a certain Feature is enabled (i.e. it's set to TRUE).

<CodeGroup>
  ```csharp C# theme={null}
  public static LicenseKey HasFeature(this LicenseKey licenseKey, int featureNumber)
  ```

  ```vb VB.NET theme={null}
  Public Shared Function HasFeature(licenseKey As LicenseKey, featureNumber As Integer) As LicenseKey
  ```
</CodeGroup>

**Parameters**

| Name | Type | Description |
| - | - | - |
| `licenseKey` | [`LicenseKey`](/libraries/dotnet-reference/license-key) | The license object to check or use. |
| `featureNumber` | `int` | The feature number, eg. feature1, feature 2, etc. FeatureNumber can be 1,2,...,8. |

**Returns:** [`LicenseKey`](/libraries/dotnet-reference/license-key). A key information object if the condition is satisfied. Null otherwise.

<a id="has-not-expired-338055362e" />

### HasNotExpired(LicenseKey, bool, bool)

Checks the expiry using the device UTC clock and this helper's whole-day comparison.

<CodeGroup>
  ```csharp C# theme={null}
  public static LicenseKey HasNotExpired(this LicenseKey licenseKey, bool checkWithInternetTime = false, bool allowUsagOnExpirationDate = true)
  ```

  ```vb VB.NET theme={null}
  Public Shared Function HasNotExpired(licenseKey As LicenseKey, Optional checkWithInternetTime As Boolean = False, Optional allowUsagOnExpirationDate As Boolean = True) As LicenseKey
  ```
</CodeGroup>

**Parameters**

| Name | Type | Description |
| - | - | - |
| `licenseKey` | [`LicenseKey`](/libraries/dotnet-reference/license-key) | The license object to check or use. |
| `checkWithInternetTime` | `bool` | If set to true, we will also check that the local<br />    time (on the client computer) has not been changed (using SKM.TimeCheck). |
| `allowUsagOnExpirationDate` | `bool` | If set to true, the user will not be able to use the license on the expiration date <br />    (i.e. null will be returned on the expiration date). |

**Returns:** [`LicenseKey`](/libraries/dotnet-reference/license-key). The original LicenseKey when the check passes; null otherwise.

**Checks:** With `allowUsagOnExpirationDate=true`, the helper accepts `(Expires - DateTime.UtcNow).Days >= 0`; with false it requires `.Days > 0`. These whole-day rules are not an exact timestamp comparison.

For an exact expiry deadline, compare `DateTime.UtcNow` with `Expires`. `checkWithInternetTime=true` also calls the legacy internet-time helper; it requires connectivity and is not an offline trusted-time design.

<a id="has-not-feature-d0d9367b21" />

### HasNotFeature(LicenseKey, int)

Checks so that a certain Feature is disabled (i.e. it's set to FALSE).

<CodeGroup>
  ```csharp C# theme={null}
  public static LicenseKey HasNotFeature(this LicenseKey licenseKey, int featureNumber)
  ```

  ```vb VB.NET theme={null}
  Public Shared Function HasNotFeature(licenseKey As LicenseKey, featureNumber As Integer) As LicenseKey
  ```
</CodeGroup>

**Parameters**

| Name | Type | Description |
| - | - | - |
| `licenseKey` | [`LicenseKey`](/libraries/dotnet-reference/license-key) | The license object to check or use. |
| `featureNumber` | `int` | The feature number, eg. feature1, feature 2, etc. FeatureNumber can be 1,2,...,8. |

**Returns:** [`LicenseKey`](/libraries/dotnet-reference/license-key). A key information object if the condition is satisfied. Null otherwise.

<a id="has-valid-signature-20d1135b86" />

### HasValidSignature(LicenseKey, string)

Checks the license signature and, when supplied, the signed response age.

<CodeGroup>
  ```csharp C# theme={null}
  public static LicenseKey HasValidSignature(this LicenseKey licenseKey, string rsaPublicKey)
  ```

  ```vb VB.NET theme={null}
  Public Shared Function HasValidSignature(licenseKey As LicenseKey, rsaPublicKey As String) As LicenseKey
  ```
</CodeGroup>

**Parameters**

| Name | Type | Description |
| - | - | - |
| `licenseKey` | [`LicenseKey`](/libraries/dotnet-reference/license-key) | The license object to check or use. |
| `rsaPublicKey` | `string` | The public key (RSA). It can be found here: [https://app.cryptolens.io/User/Security](https://app.cryptolens.io/User/Security) |

**Returns:** [`LicenseKey`](/libraries/dotnet-reference/license-key). The original LicenseKey when the checks pass; null otherwise.

**Checks:** The overload with `signatureExpirationInterval` rejects a response when the whole-day component of `DateTime.UtcNow - SignDate` reaches that interval. A null interval omits the age check.

The interval is in days and is separate from license expiry. The age check uses the device clock; a signed timestamp does not prevent clock rollback. Saving the file again does not reset SignDate.

<a id="has-valid-signature-ece18f11a8" />

### HasValidSignature(LicenseKey, string, int?)

Checks the license signature and, when supplied, the signed response age.

<CodeGroup>
  ```csharp C# theme={null}
  public static LicenseKey HasValidSignature(this LicenseKey licenseKey, string rsaPublicKey, int? signatureExpirationInterval)
  ```

  ```vb VB.NET theme={null}
  Public Shared Function HasValidSignature(licenseKey As LicenseKey, rsaPublicKey As String, signatureExpirationInterval As Integer?) As LicenseKey
  ```
</CodeGroup>

**Parameters**

| Name | Type | Description |
| - | - | - |
| `licenseKey` | [`LicenseKey`](/libraries/dotnet-reference/license-key) | The license object to check or use. |
| `rsaPublicKey` | `string` | The public key (RSA). It can be found here: [https://app.cryptolens.io/User/Security](https://app.cryptolens.io/User/Security) |
| `signatureExpirationInterval` | `Nullable<Int32>` | If the license key was signed,<br />    this method will check so that no more than "signatureExpirationInterval" days have passed since the last activation. |

**Returns:** [`LicenseKey`](/libraries/dotnet-reference/license-key). The original LicenseKey when the checks pass; null otherwise.

**Checks:** The overload with `signatureExpirationInterval` rejects a response when the whole-day component of `DateTime.UtcNow - SignDate` reaches that interval. A null interval omits the age check.

The interval is in days and is separate from license expiry. The age check uses the device clock; a signed timestamp does not prevent clock rollback. Saving the file again does not reset SignDate.

<a id="is-blocked-bee4f97458" />

### IsBlocked(LicenseKey)

Checks so that a they key is blocked.

<CodeGroup>
  ```csharp C# theme={null}
  public static LicenseKey IsBlocked(this LicenseKey licenseKey)
  ```

  ```vb VB.NET theme={null}
  Public Shared Function IsBlocked(licenseKey As LicenseKey) As LicenseKey
  ```
</CodeGroup>

**Parameters**

| Name | Type | Description |
| - | - | - |
| `licenseKey` | [`LicenseKey`](/libraries/dotnet-reference/license-key) | The license object to check or use. |

**Returns:** [`LicenseKey`](/libraries/dotnet-reference/license-key). A key information object if the condition is satisfied. Null otherwise.

<a id="is-not-blocked-bb55cc9452" />

### IsNotBlocked(LicenseKey)

Checks so that a they key is not blocked.

<CodeGroup>
  ```csharp C# theme={null}
  public static LicenseKey IsNotBlocked(this LicenseKey licenseKey)
  ```

  ```vb VB.NET theme={null}
  Public Shared Function IsNotBlocked(licenseKey As LicenseKey) As LicenseKey
  ```
</CodeGroup>

**Parameters**

| Name | Type | Description |
| - | - | - |
| `licenseKey` | [`LicenseKey`](/libraries/dotnet-reference/license-key) | The license object to check or use. |

**Returns:** [`LicenseKey`](/libraries/dotnet-reference/license-key). A key information object if the condition is satisfied. Null otherwise.

<a id="is-on-right-machine-95540e7ac4" />

### IsOnRightMachine(LicenseKey, bool, bool)

Checks whether the license lists the expected machine or process identity.

<CodeGroup>
  ```csharp C# theme={null}
  public static LicenseKey IsOnRightMachine(this LicenseKey licenseKey, bool isFloatingLicense = false, bool allowOverdraft = false)
  ```

  ```vb VB.NET theme={null}
  Public Shared Function IsOnRightMachine(licenseKey As LicenseKey, Optional isFloatingLicense As Boolean = False, Optional allowOverdraft As Boolean = False) As LicenseKey
  ```
</CodeGroup>

**Parameters**

| Name | Type | Description |
| - | - | - |
| `licenseKey` | [`LicenseKey`](/libraries/dotnet-reference/license-key) | The license object to check or use. |
| `isFloatingLicense` | `bool` | |
| `allowOverdraft` | `bool` | If floating licensing is enabled with overdraft, this parameter should be set to true.<br />     You can enable overdraft by setting [`MaxOverdraft`](/libraries/dotnet-reference/models/activate-model#max-overdraft-ac4eb42989) to a value greater than 0. |

**Returns:** [`LicenseKey`](/libraries/dotnet-reference/license-key). The LicenseKey for a match, or null otherwise.

**Checks:** Matches activation identifiers only; it does not verify the signature or check a floating-seat deadline.

For new integrations, use an explicit machine code or `Helpers.IsOnRightMachinePI`. The overload without a machine code uses the older SHA1-based Windows helper. Machine binding is meaningful when Maximum Number of Machines is greater than zero.

<a id="is-on-right-machine-227e6f6cdc" />

### IsOnRightMachine(LicenseKey, Func\<string, string>, bool, bool)

Checks whether the license lists the expected machine or process identity.

<CodeGroup>
  ```csharp C# theme={null}
  public static LicenseKey IsOnRightMachine(this LicenseKey licenseKey, Func<string, string> hashFunction, bool isFloatingLicense = false, bool allowOverdraft = false)
  ```

  ```vb VB.NET theme={null}
  Public Shared Function IsOnRightMachine(licenseKey As LicenseKey, hashFunction As Func(Of String, String), Optional isFloatingLicense As Boolean = False, Optional allowOverdraft As Boolean = False) As LicenseKey
  ```
</CodeGroup>

**Parameters**

| Name | Type | Description |
| - | - | - |
| `licenseKey` | [`LicenseKey`](/libraries/dotnet-reference/license-key) | The license object to check or use. |
| `hashFunction` | `Func<String,String>` | A hash function used to hash the current computer's parameters. |
| `isFloatingLicense` | `bool` | If this is a floating license, this parameter has to be set to true.<br />     You can enable floating licenses by setting [`FloatingTimeInterval`](/libraries/dotnet-reference/models/activate-model#floating-time-interval-d289bcb738)<br />     to a value greater than 0. |
| `allowOverdraft` | `bool` | If floating licensing is enabled with overdraft, this parameter should be set to true.<br />     You can enable overdraft by setting [`MaxOverdraft`](/libraries/dotnet-reference/models/activate-model#max-overdraft-ac4eb42989) to a value greater than 0. |

**Returns:** [`LicenseKey`](/libraries/dotnet-reference/license-key). The LicenseKey for a match, or null otherwise.

**Checks:** Matches activation identifiers only; it does not verify the signature or check a floating-seat deadline.

For new integrations, use an explicit machine code or `Helpers.IsOnRightMachinePI`. The overload without a machine code uses the older SHA1-based Windows helper. Machine binding is meaningful when Maximum Number of Machines is greater than zero.

<a id="is-on-right-machine-a76f1a1bfc" />

### IsOnRightMachine(LicenseKey, string, bool, bool)

Checks whether the license lists the expected machine or process identity.

<CodeGroup>
  ```csharp C# theme={null}
  public static LicenseKey IsOnRightMachine(this LicenseKey licenseKey, string machineCode, bool isFloatingLicense = false, bool allowOverdraft = false)
  ```

  ```vb VB.NET theme={null}
  Public Shared Function IsOnRightMachine(licenseKey As LicenseKey, machineCode As String, Optional isFloatingLicense As Boolean = False, Optional allowOverdraft As Boolean = False) As LicenseKey
  ```
</CodeGroup>

**Parameters**

| Name | Type | Description |
| - | - | - |
| `licenseKey` | [`LicenseKey`](/libraries/dotnet-reference/license-key) | The license object to check or use. |
| `machineCode` | `string` | a unique machine identifier |
| `isFloatingLicense` | `bool` | If this is a floating license, this parameter has to be set to true.<br />     You can enable floating licenses by setting [`FloatingTimeInterval`](/libraries/dotnet-reference/models/activate-model#floating-time-interval-d289bcb738)<br />     to a value greater than 0. |
| `allowOverdraft` | `bool` | If floating licensing is enabled with overdraft, this parameter should be set to true.<br />     You can enable overdraft by setting [`MaxOverdraft`](/libraries/dotnet-reference/models/activate-model#max-overdraft-ac4eb42989) to a value greater than 0. |

**Returns:** [`LicenseKey`](/libraries/dotnet-reference/license-key). The LicenseKey for a match, or null otherwise.

**Checks:** Matches activation identifiers only; it does not verify the signature or check a floating-seat deadline.

For new integrations, use an explicit machine code or `Helpers.IsOnRightMachinePI`. The overload without a machine code uses the older SHA1-based Windows helper. Machine binding is meaningful when Maximum Number of Machines is greater than zero.

<a id="is-valid-fab17f3b82" />

### IsValid(LicenseKey)

Returns true when the license object is not null.

<CodeGroup>
  ```csharp C# theme={null}
  public static bool IsValid(this LicenseKey licenseKey)
  ```

  ```vb VB.NET theme={null}
  Public Shared Function IsValid(licenseKey As LicenseKey) As Boolean
  ```
</CodeGroup>

**Parameters**

| Name | Type | Description |
| - | - | - |
| `licenseKey` | [`LicenseKey`](/libraries/dotnet-reference/license-key) | The license object to check or use. |

**Returns:** `bool`. True for a non-null LicenseKey; false for null.

**Checks:** This overload performs no signature, expiry, blocking, feature or machine check.

Use it to finish a chain of checks that return the license on success and null on failure.

<a id="is-valid-fc247a882b" />

### IsValid(LicenseKey, string)

Checks that the license is not null and has a valid signature.

<CodeGroup>
  ```csharp C# theme={null}
  public static bool IsValid(this LicenseKey licenseKey, string rsaPublicKey)
  ```

  ```vb VB.NET theme={null}
  Public Shared Function IsValid(licenseKey As LicenseKey, rsaPublicKey As String) As Boolean
  ```
</CodeGroup>

**Parameters**

| Name | Type | Description |
| - | - | - |
| `licenseKey` | [`LicenseKey`](/libraries/dotnet-reference/license-key) | The license object to check or use. |
| `rsaPublicKey` | `string` | The public key (RSA). It can be found here: [https://app.cryptolens.io/User/Security](https://app.cryptolens.io/User/Security) |

**Returns:** `bool`. True when the object is non-null and the signature check succeeds; false otherwise.

**Checks:** Verifies the signature. It does not check expiry, blocking, features or machine binding.

<a id="load-from-file-fb29b7671b" />

### LoadFromFile(LicenseKey, string, string)

Reads a saved license file and loads its JSON.

<CodeGroup>
  ```csharp C# theme={null}
  public static LicenseKey LoadFromFile(this LicenseKey licenseKey, string file = "licensekey.skm", string RSAPubKey = null)
  ```

  ```vb VB.NET theme={null}
  Public Shared Function LoadFromFile(licenseKey As LicenseKey, Optional file As String = "licensekey.skm", Optional RSAPubKey As String = Nothing) As LicenseKey
  ```
</CodeGroup>

**Parameters**

| Name | Type | Description |
| - | - | - |
| `licenseKey` | [`LicenseKey`](/libraries/dotnet-reference/license-key) | The license object to check or use. |
| `file` | `string` | The entire path including file name, i.e. c:\folder\file.txt |
| `RSAPubKey` | `string` | Your account's RSA public key. |

**Returns:** [`LicenseKey`](/libraries/dotnet-reference/license-key). A new LicenseKey, or null when reading, parsing or verification fails.

**Checks:** Uses `LoadFromString`. The default `RSAPubKey=null` does not verify serialized LicenseKey JSON; pass your RSA public key.

The default filename is `licensekey.skm`. Assign the returned object; the receiver is not updated.

<a id="load-from-string-7fc8ce58c7" />

### LoadFromString(LicenseKey, string, string)

Loads a license from a saved JSON string.

<CodeGroup>
  ```csharp C# theme={null}
  public static LicenseKey LoadFromString(this LicenseKey licenseKey, string RSAPubKey, string serializedLicenseObject)
  ```

  ```vb VB.NET theme={null}
  Public Shared Function LoadFromString(licenseKey As LicenseKey, RSAPubKey As String, serializedLicenseObject As String) As LicenseKey
  ```
</CodeGroup>

**Parameters**

| Name | Type | Description |
| - | - | - |
| `licenseKey` | [`LicenseKey`](/libraries/dotnet-reference/license-key) | The license object to check or use. |
| `RSAPubKey` | `string` | Your account's RSA public key. |
| `serializedLicenseObject` | `string` | The saved JSON response. |

**Returns:** [`LicenseKey`](/libraries/dotnet-reference/license-key). A new LicenseKey, or null for a caught parsing or verification failure.

**Checks:** A RawResponse is verified through `LicenseKey.FromResponse`. For serialized LicenseKey JSON, a supplied RSA public key enables verification; a null RSA public key only deserializes that format.

Supply your RSA public key when loading a license for use. This method does not enforce a maximum cache age, expiry, blocking, features or machine binding.

<a id="register-event-ce2aa93677" />

### RegisterEvent(LicenseKey, string, Event)

Registers a usage event for this license.

<CodeGroup>
  ```csharp C# theme={null}
  public static void RegisterEvent(this LicenseKey licenseKey, string token, Event eventObj)
  ```

  ```vb VB.NET theme={null}
  Public Shared Sub RegisterEvent(licenseKey As LicenseKey, token As String, eventObj As [Event])
  ```
</CodeGroup>

**Parameters**

| Name | Type | Description |
| - | - | - |
| `licenseKey` | [`LicenseKey`](/libraries/dotnet-reference/license-key) | The license object to check or use. |
| `token` | `string` | An access token with RegisterEvent permission is required. |
| `eventObj` | [`Event`](/libraries/dotnet-reference/models/event) | See [`Event`](/libraries/dotnet-reference/models/event). |

**Returns:** `void`. No return value. This convenience method discards the API result.

**Checks:** No signature or license-policy checks.

**Failure Behavior:** API failures are not returned to the caller. Use `AI.RegisterEvent` when you need its result.

The overload without a machine code calls the older `Helpers.GetMachineCode()` helper. Both overloads copy the event name, feature name, currency and value; they do not forward `Event.Time` or `Event.Metadata`. These methods are present in all documented builds, including .NET Standard.

<a id="register-event-78b5e23057" />

### RegisterEvent(LicenseKey, string, Event, string)

Registers a usage event for this license.

<CodeGroup>
  ```csharp C# theme={null}
  public static void RegisterEvent(this LicenseKey licenseKey, string token, Event eventObj, string machineCode)
  ```

  ```vb VB.NET theme={null}
  Public Shared Sub RegisterEvent(licenseKey As LicenseKey, token As String, eventObj As [Event], machineCode As String)
  ```
</CodeGroup>

**Parameters**

| Name | Type | Description |
| - | - | - |
| `licenseKey` | [`LicenseKey`](/libraries/dotnet-reference/license-key) | The license object to check or use. |
| `token` | `string` | An access token with RegisterEvent permission is required. |
| `eventObj` | [`Event`](/libraries/dotnet-reference/models/event) | See [`Event`](/libraries/dotnet-reference/models/event). |
| `machineCode` | `string` | The machine or process identifier used for this activation. |

**Returns:** `void`. No return value. This convenience method discards the API result.

**Checks:** No signature or license-policy checks.

**Failure Behavior:** API failures are not returned to the caller. Use `AI.RegisterEvent` when you need its result.

The overload without a machine code calls the older `Helpers.GetMachineCode()` helper. Both overloads copy the event name, feature name, currency and value; they do not forward `Event.Time` or `Event.Metadata`. These methods are present in all documented builds, including .NET Standard.

<a id="save-as-string-ea0468b180" />

### SaveAsString(LicenseKey)

Serializes the license for storage.

<CodeGroup>
  ```csharp C# theme={null}
  public static string SaveAsString(this LicenseKey licenseKey)
  ```

  ```vb VB.NET theme={null}
  Public Shared Function SaveAsString(licenseKey As LicenseKey) As String
  ```
</CodeGroup>

**Parameters**

| Name | Type | Description |
| - | - | - |
| `licenseKey` | [`LicenseKey`](/libraries/dotnet-reference/license-key) | The license object to check or use. |

**Returns:** `string`. JSON containing the original RawResponse when it is available; otherwise JSON containing the LicenseKey object.

**Checks:** Saving does not verify the license or change its signed timestamp.

<a id="save-to-file-0155b6d530" />

### SaveToFile(LicenseKey)

Saves the serialized license to a file.

<CodeGroup>
  ```csharp C# theme={null}
  public static LicenseKey SaveToFile(this LicenseKey licenseKey)
  ```

  ```vb VB.NET theme={null}
  Public Shared Function SaveToFile(licenseKey As LicenseKey) As LicenseKey
  ```
</CodeGroup>

**Parameters**

| Name | Type | Description |
| - | - | - |
| `licenseKey` | [`LicenseKey`](/libraries/dotnet-reference/license-key) | The license object to check or use. |

**Returns:** [`LicenseKey`](/libraries/dotnet-reference/license-key). The original LicenseKey on success, or null when saving fails.

The overload without a filename uses `licensekey.skm`. Saving does not renew the license or restart an offline allowance.

<a id="save-to-file-4d8ddce458" />

### SaveToFile(LicenseKey, string)

Saves the serialized license to a file.

<CodeGroup>
  ```csharp C# theme={null}
  public static LicenseKey SaveToFile(this LicenseKey licenseKey, string file)
  ```

  ```vb VB.NET theme={null}
  Public Shared Function SaveToFile(licenseKey As LicenseKey, file As String) As LicenseKey
  ```
</CodeGroup>

**Parameters**

| Name | Type | Description |
| - | - | - |
| `licenseKey` | [`LicenseKey`](/libraries/dotnet-reference/license-key) | The license object to check or use. |
| `file` | `string` | The entire path including file name, i.e. c:\folder\file.txt |

**Returns:** [`LicenseKey`](/libraries/dotnet-reference/license-key). The original LicenseKey on success, or null when saving fails.

The overload without a filename uses `licensekey.skm`. Saving does not renew the license or restart an offline allowance.

## FAQ

<AccordionGroup>
  <Accordion title="What Does IsValid Check?" id="isvalid">
    `IsValid()` returns true when the object is not null. It is often the last call in a chain such as `license.HasFeature(1).IsValid()`; the preceding helper performs the feature check.

    `IsValid(RSAPubKey)` also verifies the signature. Neither overload adds expiry, blocking, product or machine checks. See the [Key Verification FAQ](/examples/key-verification#faq).
  </Accordion>

  <Accordion title="Can I Load a License Without an RSA Public Key?" id="loading-without-rsa">
    The serialized `LicenseKey` format can be loaded without one, but its signature is then **not verified**. Supply your RSA public key when loading a file used to authorize your application. The `RawResponse` format always goes through `FromResponse` and cannot be verified without a suitable key.

    Loading returns a new object, so assign the result. It does not update the receiver.
  </Accordion>

  <Accordion title="Does Saving a File Restart Its Offline Allowance?" id="offline-age">
    No. `HasValidSignature(RSAPubKey, 3)` uses the signed `SignDate`, not the file modification time. In 4.0.54 it rejects a response when its age in whole days is at least 3. This is separate from license expiry and a floating-seat deadline.

    The check uses the device clock. A signed timestamp prevents alteration of that timestamp; it does not provide trustworthy current time, so clock rollback can defeat the age check. See [Offline Verification](/examples/offline-verification).
  </Accordion>

  <Accordion title="Does HasNotExpired Enforce an Exact Expiry Time?" id="expiry-rounding">
    No. Version 4.0.54 uses the whole-day component of `Expires - DateTime.UtcNow`. Its default `allowUsagOnExpirationDate=true` can accept a time less than one day after `Expires`. With false, it requires a positive whole-day component. If your policy uses an exact timestamp, compare `DateTime.UtcNow` with `Expires` directly.
  </Accordion>
</AccordionGroup>

[.NET SDK Reference](/libraries/dotnet-api) · [Reviewed Source Revision](https://github.com/Cryptolens/cryptolens-dotnet/tree/30aaf399ba53d9a111bee896c35bf557fa219394)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.