使用Razor视图抛出有关DotNetOpenAuth.IEmbeddedResourceRetrieval的InvalidOperationException

时间:2011-01-21 09:39:27

标签: asp.net-mvc-3 razor dotnetopenauth

当我的Razor视图调用@Html.OpenIdSelector(...时,我得到InvalidOperationException

  

目前的IHttpHandler不是其中之一   类型:System.Web.UI.Page,   DotNetOpenAuth.IEmbeddedResourceRetrieval。   嵌入式资源URL提供程序必须   在你的.config文件中设置。

我应该在config文件中设置什么?

2 个答案:

答案 0 :(得分:8)

只需NuGet DotNetOpenAuth个套件。它将在配置文件中设置您需要的所有内容:

alt text

  1. 右键单击解决方案资源管理器中的Web项目的References
  2. Add Library Package Reference...
  3. 点击Online标签。
  4. 在搜索框中输入dotnetopenauth
  5. 点击Install
  6. 将自动设置所有内容,并从互联网上下载正确的程序集并添加为参考。

    以下是执行此操作后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库生成登录表单。

答案 1 :(得分:8)

当我试图让NerdDinner OpenID为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 helper method throwing NullReferenceException

    routes.MapRoute(
        "OpenIdDiscover",
        "Auth/Discover"
    );