Нужно немного разъяснений по JSONP с JQuery / WCF - PullRequest
0 голосов
/ 10 апреля 2011

Цель: предоставить простой сервис WCF, который будет принимать в качестве параметра строку с именем пользователя и проверять, существует ли она уже.Этот сервис будет использоваться на странице регистрации сайта, над которым я работаю, поэтому, когда пользователь вводит имя пользователя, он автоматически проверяет, было ли оно взято.

Я действительно включил эту функцию, но мне пришлось включить crossDomainScripting для службы WCF.У меня вопрос «почему?»

К коду!

Мой сервис WCF размещен на моем сайте MVC3 (у меня изначально он был на отдельном сайте, но для устранения любой и всех проблем, связанных с перекрестным доступом).scriptiong сайта Я переместил его локально.)

Интерфейс для службы WCF

    [ServiceContract]
public interface IMembershipServices
{
    [OperationContract]
    [WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json,
        UriTemplate = "IsUsernameAvailable/{username}",
        BodyStyle = WebMessageBodyStyle.Bare)]
    MembershipUserAvailability IsUsernameAvailable(string username);

    [OperationContract]
    [WebGet(UriTemplate = "helloto/{name}", ResponseFormat = WebMessageFormat.Json)]
    string Hello(string name);
}

Реализация:

    [AspNetCompatibilityRequirements(RequirementsMode
    = AspNetCompatibilityRequirementsMode.Allowed)]
public class MembershipServices : IMembershipServices
{
    #region IMembershipServices Members

    public string Hello(string name)
    {
        return String.Format("Hello:{0}", name);
    }


    public MembershipUserAvailability IsUsernameAvailable(string username)
    {
        if (String.IsNullOrWhiteSpace(username))
        {
            throw new ArgumentException(username);
        }

        MembershipUser membershipUser = Membership.GetUser(username, false);

        var membershipUserAvailability = new MembershipUserAvailability
                                             {
                                                 UserName = username,
                                                 IsAvailable = membershipUser == null ? true : false
                                             };

        return membershipUserAvailability;
    }

    #endregion
}

Web.config

<system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
    <services>
        <!-- This section is optional with the default configuration
    model introduced in .NET Framework 4 -->
        <service name="MedicalPracticeWeb.Services.MembershipServices" behaviorConfiguration="MembershipServicesBehaviors">

            <!-- This endpoint is exposed at the base address provided by host: http://localhost/servicemodelsamples/service.svc  -->
            <endpoint address="" binding="webHttpBinding" bindingConfiguration="webHttpBindingJsonP" contract="MedicalPracticeWeb.Services.IMembershipServices" behaviorConfiguration="EndpBehavior" />

            <!-- The mex endpoint is exposed at http://localhost/servicemodelsamples/service.svc/mex -->
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        </service>
    </services>
    <behaviors>
        <serviceBehaviors>
            <behavior name="MembershipServicesBehaviors">
                <!-- Add the following element to your service behavior configuration. -->
                <serviceMetadata httpGetEnabled="true" />
                <serviceDebug includeExceptionDetailInFaults="true" />
            </behavior>
        </serviceBehaviors>
        <endpointBehaviors>
            <behavior name="EndpBehavior">
                <webHttp />
            </behavior>
        </endpointBehaviors>
    </behaviors>
    <bindings>
        <webHttpBinding>
            <binding name="webHttpBindingJsonP" crossDomainScriptAccessEnabled="true"></binding>
        </webHttpBinding>
    </bindings>
</system.serviceModel>

Jquery to imlement call:

$(document).ready(function () {

var usernameTextbox = $('#username');
var usernameUnavailableRow = $('#usernameUnavailableRow');
var availabilityMessage = $('#availabilityMessage');

usernameTextbox.blur(function () {
    if ($(this).val()) {

        $.getJSON('/Services/MembershipServiceHost.svc/IsUsernameAvailable/' + escape($(this).val()), function (results) {
            if (results.IsAvailable) {
                if (usernameUnavailableRow.is(':visible')) {
                    availabilityMessage.html('This username is available.');
                    availabilityMessage.addClass('usernameAvailable');
                    availabilityMessage.removeClass('usernameTaken');
                }
            }
            else {
                usernameUnavailableRow.show();
                availabilityMessage.html('This username is already taken!');
                availabilityMessage.addClass('usernameTaken');
                availabilityMessage.removeClass('usernameAvailable');
            }
        });

    }
});

});

Теперь все это прекрасно работает.Я могу ввести имя пользователя в текстовое поле в моей регистрационной форме, и когда я покидаю поле, событие onBlur запускается и вызывает службу WCF, возвращающую результаты, как и ожидалось ... но только , если у меня есть crossDomainScriptAccessEnabled = "true"в моем web.config.Это озадачивает меня.Возможно, это недостаток понимания JSON и JSONP (вполне возможно. Я довольно плохо знаком с работой с JSON), но так как служба размещена в одном домене, зачем мне этот набор?

Я взялпосмотрим, что отправлял Fiddler:

GET /Services/MembershipServiceHost.svc/IsUsernameAvailable/Tim?callback=jQuery1510988704698288691_1302393437642&_=1302393485350 HTTP / 1.130 * обратный вызов I * 10 * и 1030 * 1029JQuery docs.

http://api.jquery.com/jQuery.getJSON/

Если URL содержит строку "callback =?"(или аналогичный, как определено серверным API), запрос обрабатывается как JSONP.См. Обсуждение типа данных jsonp в $ .ajax () для более подробной информации.

Означает ли это, что простое действие обратного вызова on success заставит GetJSON использовать JSONP?

Любой вклад приветствуется.

1 Ответ

0 голосов
/ 10 апреля 2011

Означает ли это, что простое действие обратного вызова on success заставит GetJSON использовать JSONP?

Простой ответ - да.

Если вы добавите параметр или зададите тип jsonp, jQuery автоматически сделает всю тяжелую работу за вас.Вам также нужно, чтобы ваш сервис был достаточно умен, чтобы обернуть данные в вызов функции перед тем, как отправить их вам - но .net делает это, если передается параметр.

Есть несколько других ответов на SOэтот разговор о том, как использовать jsonp через jQuery.

...