<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>ActionMethodSelectorAttribute | no dogma blog</title><link>https://nodogmablog.bryanhogan.net/tag/actionmethodselectorattribute/</link><atom:link href="https://nodogmablog.bryanhogan.net/tag/actionmethodselectorattribute/index.xml" rel="self" type="application/rss+xml"/><description>ActionMethodSelectorAttribute</description><generator>Wowchemy (https://wowchemy.com)</generator><language>en-us</language><lastBuildDate>Tue, 15 Aug 2017 00:00:00 +0000</lastBuildDate><image><url>https://nodogmablog.bryanhogan.net/media/icon_hu9c23d68d4e9f1f9acfa8237e5c2ea674_3344_512x512_fill_lanczos_center_3.png</url><title>ActionMethodSelectorAttribute</title><link>https://nodogmablog.bryanhogan.net/tag/actionmethodselectorattribute/</link></image><item><title>Multiple Get Methods with the Action Method Selector Attribute in .NET Core</title><link>https://nodogmablog.bryanhogan.net/2017/08/multiple-get-methods-with-the-action-method-selector-attribute-in-net-core/</link><pubDate>Tue, 15 Aug 2017 00:00:00 +0000</pubDate><guid>https://nodogmablog.bryanhogan.net/2017/08/multiple-get-methods-with-the-action-method-selector-attribute-in-net-core/</guid><description>&lt;p>&lt;em>Full source code available &lt;a href="media/ActionDescriptorRoutingCore.zip">here&lt;/a>.&lt;/em>&lt;/p>
&lt;p>In .Net Core Web Api it is not possible for the routing mechanism to distinguish between the following action methods.&lt;/p>
&lt;p>&lt;code>public string GetSomething(int id, int something)&lt;/code>&lt;/p>
&lt;p>and&lt;/p>
&lt;p>&lt;code>public string GetAnother(int id, int another)&lt;/code>&lt;/p>
&lt;p>But with the help of an &lt;code>ActionMethodSelectorAttribute&lt;/code> we can tell the methods apart.&lt;/p>
&lt;h3 id="step-1">Step 1&lt;/h3>
&lt;p>Add a new class called &lt;code>QueryStringConstraint&lt;/code> and inherit from &lt;code>ActionMethodSelectorAttribute&lt;/code>.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-csharp" data-lang="csharp">&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1&lt;/span>&lt;span>&lt;span style="color:#00f">public&lt;/span> &lt;span style="color:#00f">class&lt;/span> &lt;span style="color:#000">QueryStringConstraint&lt;/span> : &lt;span style="color:#000">ActionMethodSelectorAttribute&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2&lt;/span>&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3&lt;/span>&lt;span> &lt;span style="color:#00f">public&lt;/span> &lt;span style="color:#00f">override&lt;/span> &lt;span style="color:#00f">bool&lt;/span> &lt;span style="color:#000">IsValidForRequest&lt;/span>(&lt;span style="color:#000">RouteContext&lt;/span> &lt;span style="color:#000">routeContext&lt;/span>, &lt;span style="color:#000">ActionDescriptor&lt;/span> &lt;span style="color:#000">action&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4&lt;/span>&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5&lt;/span>&lt;span> &lt;span style="color:#000">IList&lt;/span>&amp;lt;&lt;span style="color:#000">ParameterDescriptor&lt;/span>&amp;gt; &lt;span style="color:#000">methodParameters&lt;/span> = &lt;span style="color:#000">action&lt;/span>.&lt;span style="color:#000">Parameters&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6&lt;/span>&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7&lt;/span>&lt;span> &lt;span style="color:#000">ICollection&lt;/span>&amp;lt;&lt;span style="color:#00f">string&lt;/span>&amp;gt; &lt;span style="color:#000">queryStringKeys&lt;/span> = &lt;span style="color:#000">routeContext&lt;/span>.&lt;span style="color:#000">HttpContext&lt;/span>.&lt;span style="color:#000">Request&lt;/span>.&lt;span style="color:#000">Query&lt;/span>.&lt;span style="color:#000">Keys&lt;/span>.&lt;span style="color:#000">Select&lt;/span>(&lt;span style="color:#000">q&lt;/span> =&amp;gt; &lt;span style="color:#000">q&lt;/span>.&lt;span style="color:#000">ToLower&lt;/span>()).&lt;span style="color:#000">ToList&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8&lt;/span>&lt;span> &lt;span style="color:#000">IList&lt;/span>&amp;lt;&lt;span style="color:#00f">string&lt;/span>&amp;gt; &lt;span style="color:#000">methodParamNames&lt;/span> = &lt;span style="color:#000">methodParameters&lt;/span>.&lt;span style="color:#000">Select&lt;/span>(&lt;span style="color:#000">mp&lt;/span> =&amp;gt; &lt;span style="color:#000">mp&lt;/span>.&lt;span style="color:#000">Name&lt;/span>.&lt;span style="color:#000">ToLower&lt;/span>()).&lt;span style="color:#000">ToList&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9&lt;/span>&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10&lt;/span>&lt;span> &lt;span style="color:#00f">foreach&lt;/span> (&lt;span style="color:#00f">var&lt;/span> &lt;span style="color:#000">methodParameter&lt;/span> &lt;span style="color:#00f">in&lt;/span> &lt;span style="color:#000">methodParameters&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11&lt;/span>&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12&lt;/span>&lt;span> &lt;span style="color:#00f">if&lt;/span> (&lt;span style="color:#000">methodParameter&lt;/span>.&lt;span style="color:#000">ParameterType&lt;/span>.&lt;span style="color:#000">Name&lt;/span>.&lt;span style="color:#000">Contains&lt;/span>(&lt;span style="color:#5a2">&amp;#34;Nullable&amp;#34;&lt;/span>))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13&lt;/span>&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14&lt;/span>&lt;span> &lt;span style="color:#888;font-style:italic">//check if the query string has a parameter that is not in the method params&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15&lt;/span>&lt;span> &lt;span style="color:#00f">foreach&lt;/span>(&lt;span style="color:#00f">var&lt;/span> &lt;span style="color:#000">q&lt;/span> &lt;span style="color:#00f">in&lt;/span> &lt;span style="color:#000">queryStringKeys&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16&lt;/span>&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17&lt;/span>&lt;span> &lt;span style="color:#00f">if&lt;/span> (&lt;span style="color:#000">methodParamNames&lt;/span>.&lt;span style="color:#000">All&lt;/span>(&lt;span style="color:#000">mp&lt;/span> =&amp;gt; &lt;span style="color:#000">mp&lt;/span> != &lt;span style="color:#000">q&lt;/span>))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18&lt;/span>&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">19&lt;/span>&lt;span> &lt;span style="color:#00f">return&lt;/span> &lt;span style="color:#00f">false&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">20&lt;/span>&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">21&lt;/span>&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">22&lt;/span>&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">23&lt;/span>&lt;span> &lt;span style="color:#00f">if&lt;/span>(&lt;span style="color:#000">queryStringKeys&lt;/span>.&lt;span style="color:#000">All&lt;/span>(&lt;span style="color:#000">q&lt;/span> =&amp;gt; &lt;span style="color:#000">q&lt;/span> != &lt;span style="color:#000">methodParameter&lt;/span>.&lt;span style="color:#000">Name&lt;/span>.&lt;span style="color:#000">ToLower&lt;/span>()))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">24&lt;/span>&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">25&lt;/span>&lt;span> &lt;span style="color:#00f">continue&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">26&lt;/span>&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">27&lt;/span>&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">28&lt;/span>&lt;span> &lt;span style="color:#00f">else&lt;/span> &lt;span style="color:#00f">if&lt;/span> (&lt;span style="color:#000">queryStringKeys&lt;/span>.&lt;span style="color:#000">All&lt;/span>(&lt;span style="color:#000">q&lt;/span> =&amp;gt; &lt;span style="color:#000">q&lt;/span> != &lt;span style="color:#000">methodParameter&lt;/span>.&lt;span style="color:#000">Name&lt;/span>.&lt;span style="color:#000">ToLower&lt;/span>()))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">29&lt;/span>&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">30&lt;/span>&lt;span> &lt;span style="color:#00f">return&lt;/span> &lt;span style="color:#00f">false&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">31&lt;/span>&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">32&lt;/span>&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">33&lt;/span>&lt;span> &lt;span style="color:#00f">return&lt;/span> &lt;span style="color:#00f">true&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">34&lt;/span>&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">35&lt;/span>&lt;span>}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;h3 id="step-2">Step 2&lt;/h3>
&lt;p>Add the &lt;code>QueryStringConstraint&lt;/code> to the action methods that need to be distinguished by query string parameters.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-csharp" data-lang="csharp">&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1&lt;/span>&lt;span>&lt;span style="color:#888;font-style:italic">// http://localhost:62922/api/values/?id=1&amp;amp;another=22&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2&lt;/span>&lt;span>&lt;span style="color:#000">[QueryStringConstraint]&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3&lt;/span>&lt;span>&lt;span style="color:#00f">public&lt;/span> &lt;span style="color:#00f">string&lt;/span> &lt;span style="color:#000">GetAnother&lt;/span>(&lt;span style="color:#00f">int&lt;/span> &lt;span style="color:#000">id&lt;/span>, &lt;span style="color:#00f">int&lt;/span> &lt;span style="color:#000">another&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4&lt;/span>&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5&lt;/span>&lt;span> &lt;span style="color:#00f">return&lt;/span> &lt;span style="color:#5a2">$&amp;#34;GetAnother {id} {another}&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6&lt;/span>&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7&lt;/span>&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8&lt;/span>&lt;span>&lt;span style="color:#888;font-style:italic">// http://localhost:62922/api/values/?id=1&amp;amp;something=22&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9&lt;/span>&lt;span>&lt;span style="color:#000">[QueryStringConstraint]&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10&lt;/span>&lt;span>&lt;span style="color:#00f">public&lt;/span> &lt;span style="color:#00f">string&lt;/span> &lt;span style="color:#000">GetSomething&lt;/span>(&lt;span style="color:#00f">int&lt;/span> &lt;span style="color:#000">id&lt;/span>, &lt;span style="color:#00f">int&lt;/span> &lt;span style="color:#000">something&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11&lt;/span>&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12&lt;/span>&lt;span> &lt;span style="color:#00f">return&lt;/span> &lt;span style="color:#5a2">$&amp;#34;GetSomething {id} {something}&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13&lt;/span>&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14&lt;/span>&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15&lt;/span>&lt;span>&lt;span style="color:#888;font-style:italic">// http://localhost:62922/api/values/?id=1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16&lt;/span>&lt;span>&lt;span style="color:#888;font-style:italic">// http://localhost:62922/api/values/?id=1&amp;amp;myNullable=33 &lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17&lt;/span>&lt;span>&lt;span style="color:#000">[QueryStringConstraint]&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18&lt;/span>&lt;span>&lt;span style="color:#00f">public&lt;/span> &lt;span style="color:#00f">string&lt;/span> &lt;span style="color:#000">GetWithNullables&lt;/span>(&lt;span style="color:#00f">int&lt;/span> &lt;span style="color:#000">id&lt;/span>, &lt;span style="color:#00f">int?&lt;/span> &lt;span style="color:#000">myNullable&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">19&lt;/span>&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">20&lt;/span>&lt;span> &lt;span style="color:#00f">return&lt;/span> &lt;span style="color:#5a2">$&amp;#34;GetWithNullables {id} {myNullable}&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">21&lt;/span>&lt;span>}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;p>&lt;em>Full source code available &lt;a href="media/ActionDescriptorRoutingCore.zip">here&lt;/a>.&lt;/em>&lt;/p></description></item></channel></rss>