طريقة الويب ASP.NET التي تقبل قائمة تفشل مع "اسم خدمة الويب غير صالح".

StackOverflow https://stackoverflow.com/questions/2225781

سؤال

أريد إنشاء طريقة ويب تقبل قائمة بالأشياء المخصصة (مرت عبر Jquery / JSON).

عندما أقوم بتشغيل موقع الويب محليا، يبدو أن كل شيء يبدو للعمل. JQuery و ASP.NET والجميع سعيد. ولكن عندما أضعها على أحد خوادمنا التي تهبها. JQuery يحصل على 500 خطأ بعد طلب AJAX مع استجابة كونه:

system.invalidoperationException: EditCustomObjects اسم طريقة خدمة الويب غير صالحة.

إليك طريقة خدمة الويب:

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

وكود مسج الخاص بي (الذي لا أعتقد أن الأمور، نظرا لأن الخطأ يبدو أن يحدث على مستوى خدمة الويب):

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
  }
});

تمت تهيئة قائمة CustomObject مثل ذلك:

var customObjectList = [];

وأضيف عناصر لها مثل ذلك (عبر حلقة):

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

customObjectList.push(itemObject);

إذن، هل أفعل أي شيء خاطئ هنا؟ هل هناك طريقة أفضل لتمرير مجموعة من البيانات من JQUERY إلى طريقة خدمة الويب ASP.NET؟ هل هناك طريقة لحل "اسم طريقة خدمة الويب غير صالحة". خطأ؟

FYI، أنا أقوم بتشغيل .NET 2.0 على جهاز Windows Server 2003، وحصلت على التعليمات البرمجية لما سبق من هذا الموقع: http://elegantcode.com/2009/02/21/javascript-arriays-via-jquery-ajax-to-an-aspnet-webmethod/

تحرير: شخص طلب بعض المعلومات الإضافية على خدمة الويب، بل لن أقدم الفصل بأكمله ولكن هنا أكثر قليلا قد يساعد:

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

براء

هل كانت مفيدة؟

المحلول

أقدم القدر بناء على التعليقات التي يمكنك الذهاب مباشرة إلى خدمة الويب في المتصفح.

فقط لعزل كائنك المخصص من التكوين، يمكنك وضع خدمة أخرى في مكان مثل:

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

استدعاء ذلك من مكالمة JQuery بجانب العميل. إذا كان هذا يعمل، فمن المحتمل أن يرتبط بالكائن الخاص بك على وجه التحديد وليس التكوين على جانب الخادم. خلاف ذلك، استمر في النظر إلى مسار التكوين الجانبي للخادم.

تحرير: بعض رمز العينة:

[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
 }

يتضمن هذا بالفعل صفيفان من الكائنات داخله ... يتم تعريف نوع My NewProceduredata في الفصل الذي يضع هؤلاء.

Edit2:

فيما يلي كيفية التعامل مع كائن معقد في مثيل واحد:

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...
        });
    };

ملاحظة! هام يجب أن يتطابق اسم الإجراءات التنفيذية تماما على جانب العميل والخادم لهذا العمل بشكل صحيح. 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; }
        }
     }
}

أتمنى أن يساعدك هذا.

نصائح أخرى

نظرا لأن الخطأ يذكر مشكلة في اسم طريقة الويب، أظن أن هذا يرجع تماما إلى مشاكل في كيفية إنشاء WSDL ومصمم بخدمة الويب. أرى مشكلتان محتملتان:

  1. ID هو اسم شائع بفظاعة وقد يتم حجزه أو قد يسبب تعارضات. حاول إعادة تسمية ذلك objectId (أسماء المعلمات الكبيرة ليست هي القاعدة ل .NET على أي حال)
  2. WSDL ليس لديه مفهوم الأنواع العامة. اعتمادا على المولد، اسم النوع الذي تم إنشاؤه ل List<CustomObject> أو CustomObject[] قد يتعارض مع اسم المعلمة الخاص بك CustomObjectList. وبعد حاول إعادة تسمية المعلمة الثانية customObjects في حين أن.

أو ربما هناك بعض مشاكل الإطارات السخيفة الأخرى في اللعب هنا. في أي حال، يجب عليك إضافة إلى سؤالك WSDL الذي تم إنشاؤه بواسطة .NET. يمكنك الحصول على WSDL XML عن طريق تنزيل /manageobjects.asmx؟wsdl من خادم الويب الخاص بك.

قد ترغب في التحقق من عنصر خادم الويب / البروتوكولات الخاص بك في قسم System.Web وتأكد من إضافة httppost. عادة ما يتم تمكين المنشور المحلي افتراضيا كوضع التطوير ولكن ليس عن بعد، وهو ما سيكون عليه عندما يتم نشر الخدمة على الخادم ...

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

أذهب إلى مزيد من التفاصيل هنا

ربما لا يوجد المسار الذي تتجاوزه مع مسج محاولة لرؤية الاستجابة باستخدام Firebug.

كلما أحصل على هذه الأنواع من الأخطاء (العمل على المحلي ولكن ليس على الخادم) أطلق النار على أداة المسؤول IIS (أو ما كنت تستخدمه) والتحقق من أن كل شيء هو نفسه بالضبط. إن لم يكن جعلهم نفس الشيء ثم تغيير شيء صغير في وقت واحد.

اعتمادا على دورك / مؤسستك قد لا يكون لديك إمكانية الوصول إلى الخادم بهذه الطريقة ولكن غالبا ما تنزل هذه الأخطاء إلى خانة الاختيار العشوائية الأثرية في علامة تبويب لا تنظر إليها أبدا.

إنها لقطة طويلة ولكن لا يمكن أن تساعد في المحاولة.

هل لديك 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>

هذا إعلان خاطئ في جافا سكريبت.

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

يجب أن يكون تهيئة الكائن الصحيح:

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

حاول أيضا إزالة مؤقت async: false من $.ajaxالمعلمات.

يجب أن أقول، أنا لست مباعة 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";
}

قم بإنشاء فئة AcessData Cointing قائمة من ObjectITEM مماثلة لمثالتي الأخرى التي تطابق الكائنات (حذرا من الأسماء).

ملاحظة: لدي امتدادات ASP.NET AJAX مثبتة - العمل مع رمز ASP.NET 2.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!";
}

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

وهذا يعمل لكائن واحد، التالي سأحاول قائمة الكائنات :)

تأكد من أن لديك هذا في الجزء العلوي من صفك

[ScriptService] <--- this bit :D

public class Surveyors : WebService

تحقق أيضا من كل ما تبذلونه من الحلمة، وذهب resharper مجنون قليلا بالنسبة لي وقد استغرق الأمر بعض الوقت للتحقق من خلال.

أيضا إذا كان لديك العديد من WebMethods، فحاول إنشاء WebService Hello World Basic، فتأكد من عملها بالفعل في المقام الأول بعد ذلك، يمكنك استكشاف الأخطاء وإصلاحها من هناك.

حظ سعيد.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top