0

パブリック (外部呼び出し可能) JSON データ フィードを ASP.net (4) Forms Web サイトに追加したいと考えています。このために、次の Web サービスを作成しました。

[WebService(Namespace = "http://localtest.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
[System.Web.Script.Services.ScriptService]
public class BlogWebService : System.Web.Service.WebService
{
   [WebMethod]
   [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
   public List<Blog> GetLatestBlogs(int noBlogs)
   {
      return GetLatestBlogs(noBlogs)
         .Select(b => b.ToWebServiceModel())
         .ToList();
   }
}

開いてローカルサーバーでこれをテストしました

http://localhost:55671/WebServices/BlogWebService.asmx?op=GetLatestBlogs

そしてそれは正しく動作します。

このサービスにリモートでアクセスしようとすると、内部サーバー エラーが発生します。たとえば、LinqPad を使用して次のコードを実行しました ( http://geekswithblogs.net/JuanDoNeblo/archive/2007/10/24/json_in_aspnetajax_part2.aspxのスクリプトに基づく):

void Main()
{
   GetLatestBlogs().Dump();
}

private readonly static string BlogServiceUrl =
   "http://localhost:55671/BlogWebService.asmx/GetLatestBlogs?noBlogs={0}";

public static string GetLatestBlogs(int noBlogs = 5)
{
   string formattedUri = String.Format(CultureInfo.InvariantCulture,
      BlogServiceUrl, noBlogs);

   HttpWebRequest webRequest = GetWebRequest(formattedUri);
   HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse();
   string jsonResponse = string.Empty;
   using (StreamReader sr = new StreamReader(response.GetResponseStream()))
   {
      jsonResponse = sr.ReadToEnd();
   }
   return jsonResponse;
}

private static HttpWebRequest GetWebRequest(string formattedUri)
{
   Uri serviceUri = new Uri(formattedUri, UriKind.Absolute);
   return (HttpWebRequest)System.Net.WebRequest.Create(serviceUri);
}

いくつかの質問/疑問があります:

  1. Web サービスへの呼び出しはどのようにフォーマットする必要がありますか? LinqPad テスト コードでの BlogServiceUrl の構成が正しいかどうかはわかりません。
  2. BlogWebService クラスと GetBlogs() メソッドは正しく定義され、正しく属性付けされていますか?
  3. これを機能させるには、Web サイトの構成に何か追加する必要がありますか?

アドバイスをいただければ幸いです。

4

1 に答える 1

0

リモート JavaScript 呼び出しで HttpHandler (.ashx) メカニズムを機能させる方法を見つけることができませんでした。リモート jQuery 呼び出しで常に「無効なリファラー」エラーを受け取りました。不可能だと言っているわけではありませんが、それを行う方法に関するドキュメントが見つかりませんでした-とにかくうまくいきませんでした。

最後に、 Ben Deweyによるこの記事のガイドに従ってコードを WCF サービスに変換しました。これは非常に役に立ちました。クラスとメソッドの属性を慎重に適用してください。何が間違っていた!

コードは次のとおりです。

IBlogService.cs

[ServiceContract]
public interface IBlogService
{
   [OperationContract]
   List<WebServiceModels.Blog> GetLatestBlogs(int noItems);
}

ブログサービス.svc

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class BlogService 
   : Ninject.Web.WebServiceBase, IBlogService
{

   private readonly IScoRepository ScoDb;       // Data repository


   public BlogService(IScoRepository scoDb)
   {
      this.ScoDb = scoDb;
   }


   [WebGet(ResponseFormat = WebMessageFormat.Json)]
   public List<WebServiceModels.Blog> GetLatestBlogs(int noItems)
   {
      return ScoDb
         .GetLatestBlogs(noItems)
         .Select(b => b.ToWebServiceModel(hostAddress))
         .ToList();
   }
}

Web.config

<system.serviceModel>
   <serviceHostingEnvironment multipleSiteBindingsEnabled="true"  aspNetCompatibilityEnabled="true" />
   <behaviors>
      <endpointBehaviors>
         <behavior name="webHttpBehavior">
            <webHttp />
         </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
         <behavior name="">
            <serviceMetadata httpGetEnabled="true" />
            <serviceDebug includeExceptionDetailInFaults="false" />
         </behavior>
      </serviceBehaviors>
   </behaviors>
   <bindings>
      <webHttpBinding>
         <binding name="webHttpBindingWithJsonP" crossDomainScriptAccessEnabled="true" />
      </webHttpBinding>
   </bindings>
   <services>
      <service name="WebServices.JSON.BlogService">
         <endpoint name="WebServices.JSON.IBlogService" address="" binding="webHttpBinding" bindingConfiguration="webHttpBindingWithJsonP" contract="WebServices.JSON.IBlogService" behaviorConfiguration="webHttpBehavior" />
      </service>
   </services>
</system.serviceModel>

JavaScript をテストする

$.ajax({
   type: "GET",
   url: "http://localhost:55671/WebServices/JSON/BlogService.svc/GetLatestBlogs",
   data: {
      noItems: 3
   },
   dataType: "jsonp",
   cache: false,
   success: function(result) {
      alert(result[0].Title + " (" + result.length + " Blogs returned)");
   },
   error: function(jqXHR, textStatus, errorThrown) {
     alert(errorThrown);
   }
});

ご覧のとおり、Ninject DI も使用しました。Ninject.Extension.Wcf モジュールに出会うまで、これは問題でした。これにより、作業が非常に楽になりました。しかし、いくつかの落とし穴があります。

  • 多くのドキュメントを見つけることができませんでした

  • 'factory' 属性を WCF ページに追加します。

    Factory="Ninject.Extensions.Wcf.NinjectWebServiceHostFactory"

    • Web.config を調整して、サービスインターフェイスを参照するようにします。そうしないと、バインディング マジックが発生しません。

お役に立てば幸いです。

于 2013-02-05T11:30:24.777 に答える