Cyotek Development Bloghttps://devblog.cyotek.com/tag/mantisbt/atom.xml2018-03-30T15:55:08ZUsing the MantisBT REST API when hosted on IISurn:uuid:49741060-f6cc-4982-b2cb-bf12fbb9e6682018-03-30T15:55:08Z2018-03-30T15:55:08Z<p>I'm currently in the process of moving our hosting services from
one provider to another; although some parts of cyotek.com
infrastructure runs on Microsoft Azure, a fair chunk uses more
traditional hosting. Our <a href="https://mantisbt.org/" rel="external nofollow noopener">MantisBT</a> instance is one such
service that I recently migrated.</p>
<p>Previously the instance was hosted on Linux, now it's on
Windows. The initial migration seemed to have gone well and so
I'd moved onto the next sub-domain on the list.</p>
<p>This morning however I noticed the error logs were listing that
cyotek.com wasn't able to display product road maps. On testing,
I was getting <code>404</code> responses for any calls to the REST API on
the migrated MantisBT instance.</p>
<h2 id="apache-redirects">Apache Redirects</h2>
<p>The REST API in MantisBT makes use of Apache's <strong>mod_rewrite</strong>
module to rewrite any URI to <code>/api/rest/</code> to
<code>/api/rest/index.php</code> using the following rules in <code>.htaccess</code></p>
<figure class="lang-bat highlight"><figcaption><span>bat</span></figcaption><pre class="code">
# Based <span class="keyword">on</span> Slim Framework recommendation @ http://docs.slimframework.com/routing/rewrite/
RewriteEngine <span class="keyword">On</span>
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]
</pre>
</figure>
<p>Of course, IIS doesn't support <code>.htaccess</code> files and so these
rewrites never occur, hence the <code>404</code>.</p>
<h2 id="redirecting-in-iis">Redirecting in IIS</h2>
<p>IIS has its own version of <strong>mod_rewrite</strong>, the <strong>URL Rewrite</strong>
module, although it isn't installed by default. You can find how
to install this module in a <a href="/post/installing-the-url-rewrite-module-into-internet-information-services">previous post</a>.</p>
<p>Once installed, you can add rewrite rules to <code>web.config</code> either
via the IIS Manager GUI, or by directly editing the
configuration - this post will cover both approaches.</p>
<h2 id="importing.htaccess-rules">Importing .htaccess rules</h2>
<p>I briefly spoke about manually modifying <code>web.config</code> to add
rewrite rules in our post on <a href="/post/redirecting-to-https-when-using-iis-behind-a-load-balancer">Redirecting to HTTPS when using
IIS behind a load balancer</a>. This time I'm going to describe
how to import the rewrite rules of a <code>.htaccess</code> file directly
into IIS.</p>
<ul>
<li><p>Firstly, open IIS manager and then navigate to the
<strong>api/rest</strong> folder of your MantisBT installation</p>
</li>
<li><p>Next open the <strong>URL Rewrite</strong> section.</p>
</li>
<li><p>Click the <strong>Import Rules...</strong> option in the Actions sidebar.</p>
</li>
<li><p>In the <strong>Configuration file</strong> field, select the <code>.htaccess</code>
file located in the local <code>api/rest</code> folder and then click
<strong>Import</strong>.</p>
</li>
<li><p>Verify that the <strong>Rewrite rules</strong> field displays the
appropriate redirect and that <strong>Converted Rules</strong> indicates
that the rule was successfully imported.</p>
<figure class="screenshot" ><a href="https://images.cyotek.com/image/devblog/mantisbt-iis-rewrite-1c.png" class="gallery" title="Importing .htaccess rules into IIS" ><img src="https://images.cyotek.com/image/thumbnail/devblog/mantisbt-iis-rewrite-1c.png" alt="Importing .htaccess rules into IIS" decoding="async" loading="lazy" /></a><figcaption>Importing .htaccess rules into IIS</figcaption></figure></li>
<li><p>In the Actions sidebar, click <strong>Apply</strong> to save the changes,
then click <strong>Back to Rules</strong> to return to to the main <strong>URL
Rewrite</strong> section listing the imported rule.</p>
<figure class="screenshot" ><a href="https://images.cyotek.com/image/devblog/mantisbt-iis-rewrite-1d.png" class="gallery" title="The imported configuration" ><img src="https://images.cyotek.com/image/thumbnail/devblog/mantisbt-iis-rewrite-1d.png" alt="The imported configuration" decoding="async" loading="lazy" /></a><figcaption>The imported configuration</figcaption></figure></li>
</ul>
<p>That should be all that is required; the REST API calls should
now rewrite and succeed. To quickly test that all is well, open
up <code>http://yourinstantURL/api/rest/projects/</code> in your browser -
if you get a 401 error, then the redirect is working correctly.</p>
<h2 id="manually-updating-the-configuration">Manually updating the configuration</h2>
<p>If your instance is hosted remotely you might not have direct
access to IIS Manager or be able to remotely connect to it.
Below is the complete <code>web.config</code> file used to enable
redirects, simply copy it to the <code>/api/rest</code> folder of your
MantisBT instance.</p>
<figure class="lang-xml highlight"><figcaption><span>xml</span></figcaption><pre class="code">
<span class="symbol">&lt;?</span><span class="name">xml</span> <span class="name">version</span><span class="symbol">=</span><span class="symbol">&quot;</span><span class="attribute">1.0</span><span class="symbol">&quot;</span> <span class="name">encoding</span><span class="symbol">=</span><span class="symbol">&quot;</span><span class="attribute">UTF-8</span><span class="symbol">&quot;</span><span class="symbol">?&gt;</span>
<span class="symbol">&lt;</span><span class="name">configuration</span><span class="symbol">&gt;</span>
 <span class="symbol">&lt;</span><span class="name">system.webServer</span><span class="symbol">&gt;</span>
 <span class="symbol">&lt;</span><span class="name">rewrite</span><span class="symbol">&gt;</span>
 <span class="symbol">&lt;</span><span class="name">rules</span><span class="symbol">&gt;</span>
 <span class="symbol">&lt;</span><span class="name">rule</span> <span class="name">name</span><span class="symbol">=</span><span class="symbol">&quot;</span><span class="attribute">API Redirect</span><span class="symbol">&quot;</span> <span class="name">stopProcessing</span><span class="symbol">=</span><span class="symbol">&quot;</span><span class="attribute">true</span><span class="symbol">&quot;</span><span class="symbol">&gt;</span>
 <span class="symbol">&lt;</span><span class="name">match</span> <span class="name">url</span><span class="symbol">=</span><span class="symbol">&quot;</span><span class="attribute">^</span><span class="symbol">&quot;</span> <span class="name">ignoreCase</span><span class="symbol">=</span><span class="symbol">&quot;</span><span class="attribute">false</span><span class="symbol">&quot;</span> <span class="symbol">/&gt;</span>
 <span class="symbol">&lt;</span><span class="name">conditions</span> <span class="name">logicalGrouping</span><span class="symbol">=</span><span class="symbol">&quot;</span><span class="attribute">MatchAll</span><span class="symbol">&quot;</span><span class="symbol">&gt;</span>
 <span class="comment">&lt;!--# Based on Slim Framework recommendation @ http://docs.slimframework.com/routing/rewrite/--&gt;</span>
 <span class="symbol">&lt;</span><span class="name">add</span> <span class="name">input</span><span class="symbol">=</span><span class="symbol">&quot;</span><span class="attribute">{REQUEST_FILENAME}</span><span class="symbol">&quot;</span> <span class="name">matchType</span><span class="symbol">=</span><span class="symbol">&quot;</span><span class="attribute">IsFile</span><span class="symbol">&quot;</span> <span class="name">ignoreCase</span><span class="symbol">=</span><span class="symbol">&quot;</span><span class="attribute">false</span><span class="symbol">&quot;</span> <span class="name">negate</span><span class="symbol">=</span><span class="symbol">&quot;</span><span class="attribute">true</span><span class="symbol">&quot;</span> <span class="symbol">/&gt;</span>
 <span class="symbol">&lt;/</span><span class="name">conditions</span><span class="symbol">&gt;</span>
 <span class="symbol">&lt;</span><span class="name">action</span> <span class="name">type</span><span class="symbol">=</span><span class="symbol">&quot;</span><span class="attribute">Rewrite</span><span class="symbol">&quot;</span> <span class="name">url</span><span class="symbol">=</span><span class="symbol">&quot;</span><span class="attribute">index.php</span><span class="symbol">&quot;</span> <span class="name">appendQueryString</span><span class="symbol">=</span><span class="symbol">&quot;</span><span class="attribute">true</span><span class="symbol">&quot;</span> <span class="name">logRewrittenUrl</span><span class="symbol">=</span><span class="symbol">&quot;</span><span class="attribute">true</span><span class="symbol">&quot;</span> <span class="symbol">/&gt;</span>
 <span class="symbol">&lt;/</span><span class="name">rule</span><span class="symbol">&gt;</span>
 <span class="symbol">&lt;/</span><span class="name">rules</span><span class="symbol">&gt;</span>
 <span class="symbol">&lt;/</span><span class="name">rewrite</span><span class="symbol">&gt;</span>
 <span class="symbol">&lt;/</span><span class="name">system.webServer</span><span class="symbol">&gt;</span>
<span class="symbol">&lt;/</span><span class="name">configuration</span><span class="symbol">&gt;</span>
</pre>
</figure>
<h2 id="update-history">Update History</h2>
<ul>
<li>2018-03-30 - First published</li>
<li>2020-11-22 - Updated formatting</li>
</ul>

<p><small>
All content <a href="https://devblog.cyotek.com/copyright-and-trademarks">Copyright (c) by Cyotek Ltd</a> or its respective writers. Permission to reproduce news and web log entries and other RSS feed content in unmodified form without notice is granted provided they are not used to endorse or promote any products or opinions (other than what was expressed by the author) and without taking them out of context. Written permission from the copyright owner must be obtained for everything else.<br />Original URL of this content is https://devblog.cyotek.com/post/using-the-mantisbt-rest-api-when-hosted-on-iis .
</small></p>Richard Mosshttps://www.cyotek.com/richard.moss@cyotek.comAnnouncing MantisSharp, a .NET client for using the MantisBT REST APIurn:uuid:333839c8-ea35-4ed7-b124-2eac848bb2d22017-07-10T18:28:52Z2017-07-10T18:28:52Z<p>I've released a new open source project named MantisSharp, a
simple .NET client for working with the recently introduced REST
API for <a href="https://mantisbt.org/" rel="external nofollow noopener">Mantis Bug Tracker</a>.</p>
<p>The library is just getting started and is missing various
functions (hello documentation!) but it seems to be usable - as
well as the WinForms sample browser that I was using for
development testing, I also tested it in an ASP.NET MVC
application, both locally and then remotely using the
development version of cyotek.com.</p>
<p>It's probably not ready for prime time, I need to add docs,
samples and finally get serious about using await/async, plus
get a .NET Standard build done. But I think it's getting off to
a good start.</p>
<p>The GitHub repository can be found at
<a href="https://github.com/cyotek/MantisSharp">https://github.com/cyotek/MantisSharp</a> - the <a href="https://github.com/cyotek/MantisSharp/blob/master/README.md" rel="external nofollow noopener">readme</a> has
lots of extra details so I'm not going to repeat it here.</p>
<h2 id="why-create-this-library">Why create this library?</h2>
<p>Originally I wanted to use the MantisBT REST API to
automatically generate the product roadmaps on cyotek.com -
currently these are manual, and looking at the last modification
dates on the content entries shows the latest update was in
2015. Ouch. As I've been properly planning releases in our
MantisBT instance, it made sense to use that data. However, I
don't want to open access (anonymous or otherwise) to the
MantisBT instance itself, hence deciding to use the new API they
added recently.</p>
<p>I wasn't planning create a full blown library, I thought I'd
just load the JSON into a <code>dynamic</code> and grab what I needed that
way. But that untyped code offended me so much (and oddly enough
there didn't seem to be another client out there from a <em>very</em>
brief check of NuGet) that in the end it was inevitable.</p>
<p>Assuming more than just me uses this library I'd love to hear
your feedback.</p>
<h2 id="getting-started">Getting Started</h2>
<p>As well as the source, you can grab precompiled binaries via a
NuGet package</p>
<figure class="lang-bat highlight"><figcaption><span>bat</span></figcaption><pre class="code">
Install-Package MantisSharp -Pre
</pre>
</figure>
<p>The package includes builds for .NET 3.5, 4.0, 4.5 and 4.6. 4.7
will follow when I pave my machine and get the Creators Update,
.NET Standard will follow as soon as I actually add it as a
target and resolve any API issues.</p>
<p>Then just create an instance of the <code>MantisClient</code>, passing the
base URI where your MantisBT installation is hosted, along with
an API key. Also note that by default the REST API is disabled
and needs to be explicitly switched on for external access.
(There's a <a href="https://github.com/cyotek/MantisSharp/wiki" rel="external nofollow noopener">wiki page</a> which tells you how).</p>
<figure class="lang-csharp highlight"><figcaption><span>csharp</span></figcaption><pre class="code">
MantisClient client <span class="symbol">=</span> <span class="keyword">new</span> MantisClient<span class="symbol">(</span><span class="string">&quot;YOUR_MANTIS_URI&quot;</span><span class="symbol">,</span> <span class="string">&quot;YOUR_API_KEY&quot;</span><span class="symbol">)</span><span class="symbol">;</span>

<span class="comment">// list all projects</span>
<span class="keyword">foreach</span> <span class="symbol">(</span>Project project <span class="keyword">in</span> client<span class="symbol">.</span>GetProjects<span class="symbol">(</span><span class="symbol">)</span><span class="symbol">)</span>
<span class="symbol">{</span>
 Console<span class="symbol">.</span>WriteLine<span class="symbol">(</span>project<span class="symbol">.</span>Name<span class="symbol">)</span><span class="symbol">;</span>
<span class="symbol">}</span>

<span class="comment">// list all issues</span>
<span class="keyword">foreach</span> <span class="symbol">(</span>Issue issue <span class="keyword">in</span> client<span class="symbol">.</span>GetIssues<span class="symbol">(</span><span class="symbol">)</span><span class="symbol">)</span>
<span class="symbol">{</span>
 Console<span class="symbol">.</span>WriteLine<span class="symbol">(</span>issue<span class="symbol">.</span>Summary<span class="symbol">)</span><span class="symbol">;</span>
<span class="symbol">}</span>

<span class="comment">// list issues for a single project</span>
<span class="keyword">var</span> issues <span class="symbol">=</span> client<span class="symbol">.</span>GetIssues<span class="symbol">(</span><span class="number">4</span><span class="symbol">)</span><span class="symbol">;</span> <span class="comment">// or pass in a Project reference</span>

<span class="comment">// get a single issue</span>
Issue issue <span class="symbol">=</span> client<span class="symbol">.</span>GetIssue<span class="symbol">(</span><span class="number">52</span><span class="symbol">)</span><span class="symbol">;</span>
</pre>
</figure>
<h2 id="known-issues">Known Issues</h2>
<p>There's still outstanding work to do, some of which is detailed
in the readme. I also haven't done much testing yet, and our
MantisBT database is currently quite small, so I don't know how
the library will perform under bigger databases.</p>
<h2 id="examples">Examples</h2>
<figure class="screenshot" ><a href="https://images.cyotek.com/image/devblog/mantissharp-1b.png" class="gallery" title="An example of the WinForms demonstration application" ><img src="https://images.cyotek.com/image/thumbnail/devblog/mantissharp-1b.png" alt="An example of the WinForms demonstration application" decoding="async" loading="lazy" /></a><figcaption>An example of the WinForms demonstration application</figcaption></figure><figure class="screenshot" ><a href="https://images.cyotek.com/image/devblog/mantissharp-1a.png" class="gallery" title="An example of creating a roadmap type page using the REST API" ><img src="https://images.cyotek.com/image/thumbnail/devblog/mantissharp-1a.png" alt="An example of creating a roadmap type page using the REST API" decoding="async" loading="lazy" /></a><figcaption>An example of creating a roadmap type page using the REST API</figcaption></figure><h2 id="update-history">Update History</h2>
<ul>
<li>2017-07-10 - First published</li>
<li>2020-11-22 - Updated formatting</li>
</ul>

<p><small>
All content <a href="https://devblog.cyotek.com/copyright-and-trademarks">Copyright (c) by Cyotek Ltd</a> or its respective writers. Permission to reproduce news and web log entries and other RSS feed content in unmodified form without notice is granted provided they are not used to endorse or promote any products or opinions (other than what was expressed by the author) and without taking them out of context. Written permission from the copyright owner must be obtained for everything else.<br />Original URL of this content is https://devblog.cyotek.com/post/announcing-mantissharp-a-net-client-for-using-the-mantisbt-rest-api .
</small></p>Richard Mosshttps://www.cyotek.com/richard.moss@cyotek.com