6

カスタムオブジェクトのリスト(jQuery / JSONを介して渡される)を受け入れるWebメソッドを作成したいと思います。

私がウェブサイトをローカルで運営しているとき、すべてがうまくいくようです。jQueryとASP.NET、そして誰もが満足しています。しかし、私がそれを私たちのサーバーの1つに置くと、それは爆発します。jQueryは、ajaxリクエストの後に500エラーを受け取り、応答は次のようになります。

System.InvalidOperationException:EditCustomObjectsWebサービスのメソッド名が無効です。

Webサービスの方法は次のとおりです。

[WebMethod]
public void EditCustomObjects(int ID, List<CustomObject> CustomObjectList)
{
  // Code here
}

そして私のjQueryコード(エラーはWebサービスレベルで発生しているように見えるので、私は重要ではないと思います):

var data = JSON.stringify({
  ID: id,
  CustomObjectList: customObjectList
});

$.ajax({
  type: "POST",
  url: "/manageobjects.asmx/EditCustomObjects",
  data: data,
  contentType: "application/json; charset=utf-8",
  async: false,
  dataType: "json",
  success: function(xml, ajaxStatus) {
    // stuff here
  }
});

customObjectListは次のように初期化されます。

var customObjectList = [];

そして、私はそれにアイテムをそのように追加します(ループを介して):

var itemObject = { 
  ObjectTitle = objectTitle,
  ObjectDescription = objectDescription,
  ObjectValue = objectValue
}

customObjectList.push(itemObject);

それで、私はここで何か間違ったことをしていますか?jQueryからASP.NETWebサービスメソッドにデータの配列を渡すためのより良い方法はありますか?「Webサービスのメソッド名が無効です」を解決する方法はありますか?エラー?

参考までに、私はWindows Server2003マシンで.NET2.0を実行しており、上記のコードを次のサイトから入手しました:http: //elegantcode.com/2009/02/21/javascript-arrays-via-jquery-ajax -to-an-aspnet-webmethod /

編集:誰かがWebサービスに関する詳細情報を要求しました。クラス全体を提供するのではなく、もう少し役立つかもしれません。

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService] 
public class ManageObjects : Custom.Web.UI.Services.Service 
{
}

バラ

4

10 に答える 10

4

ブラウザで直接Webサービスにアクセスできるというコメントに基づいて推測します。

カスタムオブジェクトを構成から分離するために、次のような別のサービスを配置できます。

[WebMethod]
public static string GetServerTimeString()
{
    return "Current Server Time: " + DateTime.Now.ToString();
}

クライアント側のjQueryajax呼び出しから呼び出します。これが機能する場合は、サーバー側の構成ではなく、オブジェクトに特に関連している可能性があります。それ以外の場合は、サーバー側の構成トラックを引き続き確認してください。

編集:いくつかのサンプルコード:

[WebMethod(EnableSession = true)]
public Category[] GetCategoryList()
{
    return GetCategories();
}
private Category[] GetCategories()
{
     List<Category> category = new List<Category>();
     CategoryCollection matchingCategories = CategoryList.GetCategoryList();
     foreach (Category CategoryRow in matchingCategories)
    {
         category.Add(new Category(CategoryRow.CategoryId, CategoryRow.CategoryName));
    }
    return category.ToArray();
}

そして、これは私が複雑なデータ型のJSON値を投稿する例です

[WebMethod]
 public static string SaveProcedureList(NewProcedureData procedureSaveData)
 {
          ...do stuff here with my object
 }

これには、実際にはオブジェクトの2つの配列が含まれています...私のNewProcedureData型は、それらをレイアウトするクラスで定義されています。

EDIT2:

複雑なオブジェクトを1つのインスタンスで処理する方法は次のとおりです。

function cptRow(cptCode, cptCodeText, rowIndex)
{
    this.cptCode = cptCode;
    this.cptCodeText = cptCodeText;
    this.modifierList = new Array();
//...more stuff here you get the idea
}
/* set up the save object */
function procedureSet()
{
    this.provider = $('select#providerSelect option:selected').val(); // currentPageDoctor;
    this.patientIdtdb = currentPatientIdtdb;// a javascript object (string)
//...more object build stuff.
    this.cptRows = Array();
    for (i = 0; i < currentRowCount; i++)
    {
        if ($('.cptIcdLinkRow').eq(i).find('.cptEntryArea').val() != watermarkText)
        {
            this.cptRows[i] = new cptRow($('.cptIcdLinkRow').eq(i).find('.cptCode').val(), $('.cptIcdLinkRow').eq(i).find('.cptEntryArea').val(), i);//this is a javscript function that handles the array object
        };
    };
};
//here is and example where I wrap up the object
    function SaveCurrentProcedures()
    {

        var currentSet = new procedureSet();
        var procedureData = ""; 
        var testData = { procedureSaveData: currentSet };
        procedureData = JSON.stringify(testData);

        SaveProceduresData(procedureData);
    };
    function SaveProceduresData(procedureSaveData)
    {
        $.ajax({
            type: "POST",
            contentType: "application/json; charset=utf-8",
            data: procedureSaveData,
the rest of the ajax call...
        });
    };

注!重要これが正しく機能するには、procedureSaveData名がクライアント側とサーバー側で正確に一致している必要があります。EDIT3:その他のコード例:

using System;
using System.Collections.Generic;
using System.Web;

namespace MyNamespace.NewProcedure.BL
{
    /// <summary>
    /// lists of objects, names must match the JavaScript names
    /// </summary>
    public class NewProcedureData
    {
        private string _patientId = "";
        private string _patientIdTdb = "";

        private List<CptRows> _cptRows = new List<CptRows>();

        public NewProcedureData()
        {
        }

        public string PatientIdTdb
        {
            get { return _patientIdTdb; }
            set { _patientIdTdb = value; }
        }
       public string PatientId
        {
            get { return _patientId; }
            set { _patientId = value; }
        }
        public List<CptRows> CptRows = new List<CptRows>();

}

--------
using System;
using System.Collections.Generic;
using System.Web;

namespace MyNamespace.NewProcedure.BL
{
    /// <summary>
    /// lists of objects, names must match the JavaScript names
    /// </summary>
    public class CptRows
    {
        private string _cptCode = "";
        private string _cptCodeText = "";

        public CptRows()
        {
        }

        public string CptCode
        {
            get { return _cptCode; }
            set { _cptCode = value; }
        }

        public string CptCodeText
        {
            get { return _cptCodeText; }
            set { _cptCodeText = value; }
        }
     }
}

お役に立てれば。

于 2010-02-15T18:45:27.603 に答える
1

エラーはWebメソッド名の問題に言及しているため、これは完全に、WSDLが生成されてWebサービスにマップされる方法の問題が原因であると思われます。2つの潜在的な問題があります。

  1. IDはひどく一般的な名前であり、予約されているか、競合を引き起こす可能性があります。名前を変更してみてくださいobjectId(大文字のパラメーター名は、とにかく.NETの標準ではありません)
  2. WSDLにはジェネリック型の概念がありません。ジェネレーターによっては、パラメーター名に対して生成された、List<CustomObject>またはCustomObject[]パラメーター名と競合する可能性のあるタイプ名CustomObjectListcustomObjects代わりに、2番目のパラメーターの名前を変更してみてください。

あるいは、ここで他の愚かなフレームワークの問題が発生している可能性があります。いずれの場合も、.NETによって生成されたWSDLを質問に追加する必要があります。Webサーバーから/manageobjects.asmx?WSDLをダウンロードすると、WSDLXMLを取得できます。

于 2010-02-20T19:34:08.280 に答える
0

jqueryで渡したパスが存在しない可能性があります。FireBugを使用して応答を確認してみてください。

于 2010-02-14T15:37:50.660 に答える
0

system.webセクションのwebServices/protocol要素をチェックして、HttpPostが追加されていることを確認することをお勧めします。通常、ローカル投稿は開発モードとしてデフォルトで有効になっていますが、リモートでは有効になっていません。これは、サービスがサーバーにデプロイされたときに有効になります...

<system.web>
 ...
 <webServices>
  <protocols>
   <add name="HttpPost" />
  </protocols>
 </webServices>
</system.web>

ここでさらに詳しく説明します

于 2010-02-10T03:54:44.317 に答える
0

この種のエラー(ローカルでは機能しているがサーバーでは機能していない)が発生するたびに、IIS管理ツール(または使用しているもの)を起動し、すべてがまったく同じであることを確認します。それらを同じにしない場合は、一度に1つの小さなものを変更します。

役割/組織によっては、この方法でサーバーにアクセスできない場合がありますが、多くの場合、これらのエラーは、見たことのないタブの最も奇妙なランダムチェックボックスに起因します。

ロングショットですが、試してみるのは仕方がありません。

于 2010-02-15T18:17:26.767 に答える
0

ScriptServiceとしてマークされたWebサービスを許可するために必要なhttpHandlerを登録していますか?

<httpHandlers>
   <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</httpHandlers>
于 2010-02-15T18:25:07.813 に答える
0

これはjavascriptの間違った宣言です。

var itemObject = { 
  ObjectTitle = objectTitle,
  ObjectDescription = objectDescription,
  ObjectValue = objectValue
}

正しいオブジェクトの初期化は次のようになります。

var itemObject = { 
  ObjectTitle : objectTitle,
  ObjectDescription : objectDescription,
  ObjectValue : objectValue
};

また、のパラメータasync: falseから一時的に削除してみてください。$.ajax

于 2010-02-16T13:15:19.203 に答える
0

言わなければならないのは、私は100%売れているわけではないということです。私の答えは(すべて)問題ですが、これは逆シリアル化に対処します。特定のオブジェクトの詳細を追加します。

クライアント側:

function itemObject (objectTitle,  objectDescription ,objectValue )
{
    this.ObjectTitle  = objectTitle,;
    this.ObjectDescription  = objectDescription ;
    this.ObjectValue  = objectValue ;
}; 

//  4 objects in source-fix for your list
function objRow()
{
    this.myCode = myCode;
    this.myCodeText = myCodeText;
    this.customObjectList  = new Array();
    for (k = 0; k < 4; k++)
    {
        this.customObjectList [k] = new itemObject (sourceTitle[k],sourceDescription[k],sourceValue[k]);
    };
};
var myCode = "hicode1";
var  myCodeText = "hicodeText1";
$(function()
{
   function SaveCurrentObjects()
    {
         var currentSet = new objRow();
        var objectData = "";
        var testData = {objectSaveData : currentSet };
        objectData = JSON.stringify(testData);

        SaveObjectsData(objectData );
    };

    /* save the objects */
    function SaveObjectsData(objectSaveData)
    {
        $.ajax({
            type: "POST",
            contentType: "application/json; charset=utf-8",
            data: objectSaveData,
            dataFilter: function(data)
            {
                var msg;
                if (typeof (JSON) !== 'undefined' &&
                typeof (JSON.parse) === 'function')
                    msg = JSON.parse(data);
                else
                    msg = eval('(' + data + ')');
                if (msg.hasOwnProperty('d'))
                    return msg.d;
                else
                    return msg;
            },
            url: "/manageobjects.asmx/EditCustomObjects", 
            success: function(msg)
            {
               //do stuff
            },
            failure: function(msg)
            {
               //handlefail
            }
        });
    };

});

サーバー側では、クライアントコードのように:(「objectSaveData」の正確な名前)があります。

[WebMethod]
public static string EditCustomObjects(ObjectData objectSaveData)
{
   // code to save your object
   return "saved objects";
}

オブジェクトを照合する他の例と同様に、objectItemのリストを含むObjectDataクラスを作成します(名前に注意してください)。

注:ASP.NETajax拡張機能をインストールしています-この例ではasp.net2.0コードを使用しています。

于 2010-02-16T18:30:59.193 に答える
0

さて、これがオブジェクトの場合です。これをテストしました:==================================== ======== ASPX ==================================

        $("#btngeMethodCallWithAnObjectAsAParameter").click(function (event) {

            $.ajax({
                type: 'POST',
                url: 'Default.aspx/PageMethodCallWithAnObjectAsAParameter',
                data: '{"id":"' + '5' + '", "jSonAsset":' + JSON.stringify(new BuildJSonAsset()) + '}',
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: function (msg) {
                    if (msg.d) {
                        alert(msg.d);
                    }
                },
                error: function () {
                    alert("Error! Try again...");
                }
            });

        });
    });


    function BuildJSonAsset() {
        this.AssetId = '100';
        this.ContentId = '200';
        this.AssetName = 'Asset1';
    }

================================================== ======================

[WebMethod()]
public static string PageMethodCallWithAnObjectAsAParameter(int id, JSonAsset jSonAsset)
{
    return "Success!";
}

================================================== ====================

そして、これは単一のオブジェクトに対して機能します。次に、オブジェクトのリストを試してみます:)

于 2012-03-21T21:01:48.347 に答える
0

クラスのトップにこれがあることを確認してください

[ScriptService] <--- this bit :D

public class Surveyors : WebService

また、あなたのすべてのパラセシスをチェックしてください、resharperは私に少し夢中になりました、そしてそれはチェックするのに時間がかかりました。

また、多くのWebメソッドがある場合は、基本的なhello world Webサービスを作成してみてください。最初に実際に機能することを確認してから、そこからトラブルシューティングを行うことができます。

幸運を。

于 2014-03-04T20:19:33.257 に答える