InvalidOperationException, генерируемый относительно DotNetOpenAuth.IEmbeddedResourceRetrieval с представлением Razor - PullRequest
7 голосов
/ 21 января 2011

Когда мое представление Razor вызывает @Html.OpenIdSelector(..., я получаю InvalidOperationException:

Текущий IHttpHandler не относится к одному из типов: System.Web.UI.Page, DotNetOpenAuth.IEmbeddedResourceRetrieval.В вашем файле .config должен быть указан поставщик URL-адреса встроенного ресурса.

Что именно я должен установить в файле config?

Ответы [ 2 ]

8 голосов
/ 30 марта 2011

Я столкнулся с этой проблемой, когда пытался заставить OpenID NerdDinner работать на MVC3 / razor. Решение, которое сработало для меня:

Создайте этот класс в своем решении: (это было найдено в одной из сборок NerdDinner - http://nerddinner.codeplex.com/SourceControl/changeset/view/55257#1328982 (спасибо JasonHaley) по какой-то причине этот файл не в последней сборке для NerdDinner MVC3 / Razor

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using DotNetOpenAuth;
namespace <Your App>.Services
{
    public class EmbeddedResourceUrlService : IEmbeddedResourceRetrieval
    {

        private static string pathFormat = "{0}/{1}/Resource/GetWebResourceUrl?assemblyName={2}&typeName={3}&resourceName={‌​4}";
        //private static string pathFormat = "{0}/Resource/GetWebResourceUrl";

        public Uri GetWebResourceUrl(Type someTypeInResourceAssembly, string manifestResourceName)
        {
            if (manifestResourceName.Contains("http"))
            {
                return new Uri(manifestResourceName);
            }
            else
            {
                var assembly = someTypeInResourceAssembly.Assembly;

                // HACK
                string completeUrl = HttpContext.Current.Request.Url.ToString();
                string host = completeUrl.Substring(0,
                    completeUrl.IndexOf(HttpContext.Current.Request.Url.AbsolutePath));

                var path = string.Format(pathFormat,
                            host,
                            HttpContext.Current.Request.ApplicationPath.Substring(1),
                            HttpUtility.UrlEncode(assembly.FullName),
                            HttpUtility.UrlEncode(someTypeInResourceAssembly.ToString()),
                            HttpUtility.UrlEncode(manifestResourceName));

                return new Uri(path);
            }
        }
    }
}

Затем в вашем файле web.config добавьте эту строку:

<webResourceUrlProvider type="<Your App>.Services.EmbeddedResourceUrlService, <Your App>" />

просто поместите в раздел DotNetOpenAuth

вам также понадобится настроить этот маршрут: ( Html.OpenIdSelectorScripts вспомогательный метод, генерирующий NullReferenceException )

    routes.MapRoute(
        "OpenIdDiscover",
        "Auth/Discover"
    );
8 голосов
/ 21 января 2011

Just NuGet DotNetOpenAuth пакет.Он настроит все, что вам нужно в вашем конфигурационном файле:

alt text

  1. Щелкните правой кнопкой мыши References вашего веб-проекта в обозревателе решений
  2. Add Library Package Reference...
  3. Нажмите на вкладку Online.
  4. В поле поиска введите dotnetopenauth
  5. Нажмите Install

Все будет автоматически настроено, и правильные сборки будут загружены из Интернета и добавлены в качестве ссылки.

Вот как выглядит файл web.config после выполнения этого:

<?xml version="1.0" encoding="utf-8"?>
<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=152368
  -->
<configuration>
  <configSections>
    <section name="uri" type="System.Configuration.UriSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    <section name="dotNetOpenAuth" type="DotNetOpenAuth.Configuration.DotNetOpenAuthSection" requirePermission="false" allowLocation="true" />
  </configSections>
  <connectionStrings>
    <add name="ApplicationServices" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true" providerName="System.Data.SqlClient" />
  </connectionStrings>
  <appSettings>
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.0">
      <assemblies>
        <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        <add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        <add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        <add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        <add assembly="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
      </assemblies>
    </compilation>
    <authentication mode="Forms">
      <forms loginUrl="~/Account/LogOn" timeout="2880" />
    </authentication>
    <membership>
      <providers>
        <clear />
        <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
      </providers>
    </membership>
    <profile>
      <providers>
        <clear />
        <add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/" />
      </providers>
    </profile>
    <roleManager enabled="false">
      <providers>
        <clear />
        <add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="/" />
        <add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />
      </providers>
    </roleManager>
    <pages>
      <namespaces>
        <add namespace="System.Web.Helpers" />
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Routing" />
        <add namespace="System.Web.WebPages" />
      </namespaces>
    </pages>
  </system.web>
  <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <modules runAllManagedModulesForAllRequests="true" />
  </system.webServer>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0" />
        <bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
    <legacyHMACWarning enabled="0" />
  </runtime>
  <uri>
    <!-- The uri section is necessary to turn on .NET 3.5 support for IDN (international domain names),
         which is necessary for OpenID urls with unicode characters in the domain/host name. 
         It is also required to put the Uri class into RFC 3986 escaping mode, which OpenID and OAuth require. -->
    <idn enabled="All" />
    <iriParsing enabled="true" />
  </uri>
  <system.net>
    <defaultProxy enabled="true" />
    <settings>
      <!-- This setting causes .NET to check certificate revocation lists (CRL) 
                 before trusting HTTPS certificates.  But this setting tends to not 
                 be allowed in shared hosting environments. -->
      <!--<servicePointManager checkCertificateRevocationList="true"/>-->
    </settings>
  </system.net>
  <dotNetOpenAuth>
    <!-- This is an optional configuration section where aspects of dotnetopenauth can be customized. -->
    <!-- For a complete set of configuration options see http://www.dotnetopenauth.net/developers/code-snippets/configuration-options/ -->
    <openid>
      <relyingParty>
        <security requireSsl="false" />
        <behaviors>
          <!-- The following OPTIONAL behavior allows RPs to use SREG only, but be compatible
                         with OPs that use Attribute Exchange (in various formats). -->
          <add type="DotNetOpenAuth.OpenId.Behaviors.AXFetchAsSregTransform, DotNetOpenAuth" />
        </behaviors>
      </relyingParty>
    </openid>
    <messaging>
      <untrustedWebRequest>
        <whitelistHosts>
          <!-- Uncomment to enable communication with localhost (should generally not activate in production!) -->
          <!--<add name="localhost" />-->
        </whitelistHosts>
      </untrustedWebRequest>
    </messaging>
    <!-- Allow DotNetOpenAuth to publish usage statistics to library authors to improve the library. -->
    <reporting enabled="true" />
  </dotNetOpenAuth>
</configuration>

ОБНОВЛЕНИЕ:

Вы можете реализовать пользовательский поставщик поиска ресурсов:

public class CustomResourceProvider : IEmbeddedResourceRetrieval
{
    public Uri GetWebResourceUrl(Type someTypeInResourceAssembly, string manifestResourceName)
    {
        return new Uri("http://www.google.com");
    }
}

, а затем зарегистрировать его в web.config:

<dotNetOpenAuth>
    <webResourceUrlProvider type="AppName.CustomResourceProvider, AppName" />
    ...
</dotNetOpenAuth>

Но я бы порекомендовал вам использовать библиотеку openid-selector для создания форм входа в систему.

...