Returning *Bare* JSON from WCF Web Service
I have a WCF web service that returns JSON data back to an app (not an ASP.NET web app.) Here is the code:
[ServiceContract(Namespace = "Navtrak.Services.WCF.MobileAPI")]
public interface IJobServiceJSON
{
[OperationContract]
[ServiceKnownType(typeof(Job))]
[WebInvoke(
Method = "GET",
BodyStyle = WebMessageBodyStyle.WrappedRequest,
ResponseFormat = WebMessageFormat.Json)]
PagedResult<Job> ReadJobs(int userId, int? startIndex, int? maxResults, string searchTerm, string sortBy);
}
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class JobServiceJSON : IJobServiceJSON
{
public PagedResult<Job> ReadJobs(int userId, int? startIndex, int? maxResults, string searchTerm, string sortBy)
{
var service = new JobService();
return service.ReadJobs(userId, startIndex, maxResults, searchTerm, sortBy);
}
}
<%@ ServiceHost Language="C#" Debug="true" Service="Navtrak.Services.WCF.MobileAPI.JobSe开发者_如何学PythonrviceJSON" CodeBehind="JobServiceJSON.svc.cs" Factory="System.ServiceModel.Activation.WebScriptServiceHostFactory" %>
And here is the web.config settings:
<services>
<service name="JobServiceJSON" behaviorConfiguration="HttpGetMetadata">
<endpoint contract="Navtrak.Services.WCF.MobileAPI.Interfaces.IJobServiceJSON" binding="basicHttpBinding" behaviorConfiguration="AjaxBehavior" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="HttpGetMetadata">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="AjaxBehavior">
<!--<enableWebScript />-->
<webHttp defaultOutgoingResponseFormat="Json"/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
The issue with this approach is that it returns the JSON wrapped in a "d" object, which isn't that terrible, but it also returns a "___type" property for each object with the namespace of the class. This really bloats the size of the JSON, as seen here:
{"d":{"__type":"PagedResultOfJobPUkCTgiD:#Navtrak.Business.Schemas.CommonSchemas.Schemas","Results":[{"__type":"Job:#Navtrak.Business.Schemas.CommonSchemas.Schemas.Job","Address":"1011 Granite Ct, Salisbury, MD 21804-8609,","Contact":null,"CreateDate":"\/Date(1313514808000-0400)\/","DstActive":0,"Id":18416,"JobAttributes":[{"__type":"JobAttribute:#Navtrak.Business.Schemas.CommonSchemas.Schemas.Job","Id":0,"JobAttributeId":0,"JobId":0,"MobileDisplay":1,"Name":"","Sequence":0,"Value":"1011 Granite Ct, Salisbury, MD 21804-8609"},{"__type":"JobAttribute:#Navtrak.Business.Schemas.CommonSchemas.Schemas.Job","Id":0,"JobAttributeId":0,"JobId":0,"MobileDisplay":1,"Name":"","Sequence":1,"Value":"1011 Granite Ct, Salisbury, MD 21804-8609,"},{"__type":"JobAttribute:#Navtrak.Business.Schemas.CommonSchemas.Schemas.Job","Id":0,"JobAttributeId":0,"JobId":0,"MobileDisplay":0,"Name":"","Sequence":4,"Value":"2:00p ET"},{"__type":"JobAttribute:#Navtrak.Business.Schemas.CommonSchemas.Schemas.Job","Id":0,"JobAttributeId":0,"JobId":0,"MobileDisplay":1,"Name":"","Sequence":5,"Value":"test job!"}],"JobTextForMobileDisplay":null,"Latitude":38352974,"Longitude":-75563528,"Name":"1011 Granite Ct, Salisbury, MD 21804-8609","Notes":"test job!","Phone":null,"PromisedDate":"\/Date(1313604000000-0400)\/","ScheduledDay":"\/Date(1313553600000-0400)\/","ScheduledTimeFrom":0,"ScheduledTimeTo":0,"Status":10,"TimeZoneOffset":0},{"__type":"Job:#Navtrak.Business.Schemas.CommonSchemas.Schemas.Job","Address":", , ,","Contact":null,"CreateDate":"\/Date(1313515111000-0400)\/","DstActive":0,"Id":18419,"JobAttributes":[{"__type":"JobAttribute:#Navtrak.Business.Schemas.CommonSchemas.Schemas.Job","Id":0,"JobAttributeId":0,"JobId":0,"MobileDisplay":1,"Name":"","Sequence":1,"Value":", , ,"},{"__type":"JobAttribute:#Navtrak.Business.Schemas.CommonSchemas.Schemas.Job","Id":0,"JobAttributeId":0,"JobId":0,"MobileDisplay":1,"Name":"","Sequence":0,"Value":"1 test place jul 13"},{"__type":"JobAttribute:#Navtrak.Business.Schemas.CommonSchemas.Schemas.Job","Id":0,"JobAttributeId":0,"JobId":0,"MobileDisplay":0,"Name":"","Sequence":4,"Value":"2:00p ET"},{"__type":"JobAttribute:#Navtrak.Business.Schemas.CommonSchemas.Schemas.Job","Id":0,"JobAttributeId":0,"JobId":0,"MobileDisplay":1,"Name":"","Sequence":5,"Value":"test"}],"JobTextForMobileDisplay":null,"Latitude":38774850,"Longitude":-96554630,"Name":"1 test place jul 13","Notes":"test","Phone":null,"PromisedDate":"\/Date(1313604000000-0400)\/","ScheduledDay":"\/Date(1313553600000-0400)\/","ScheduledTimeFrom":0,"ScheduledTimeTo":0,"Status":10,"TimeZoneOffset":0},{"__type":"Job:#Navtrak.Business.Schemas.CommonSchemas.Schemas.Job","Address":"1011 Granite Ct, Salisbury, MD 21804-8609,","Contact":null,"CreateDate":"\/Date(1313515357000-0400)\/","DstActive":0,"Id":18420,"JobAttributes":[{"__type":"JobAttribute:#Navtrak.Business.Schemas.CommonSchemas.Schemas.Job","Id":0,"JobAttributeId":0,"JobId":0,"MobileDisplay":1,"Name":"","Sequence":0,"Value":"1011 Granite Ct, Salisbury, MD 21804-8609"},{"__type":"JobAttribute:#Navtrak.Business.Schemas.CommonSchemas.Schemas.Job","Id":0,"JobAttributeId":0,"JobId":0,"MobileDisplay":1,"Name":"","Sequence":1,"Value":"1011 Granite Ct, Salisbury, MD 21804-8609,"},{"__type":"JobAttribute:#Navtrak.Business.Schemas.CommonSchemas.Schemas.Job","Id":0,"JobAttributeId":0,"JobId":0,"MobileDisplay":0,"Name":"","Sequence":4,"Value":"2:00p ET"},{"__type":"JobAttribute:#Navtrak.Business.Schemas.CommonSchemas.Schemas.Job","Id":0,"JobAttributeId":0,"JobId":0,"MobileDisplay":1,"Name":"","Sequence":5,"Value":"test"}],"JobTextForMobileDisplay":null,"Latitude":38352974,"Longitude":-75563528,"Name":"1011 Granite Ct, Salisbury, MD 21804-8609","Notes":"test","Phone":null,"PromisedDate":"\/Date(1313604000000-0400)\/","ScheduledDay":"\/Date(1313553600000-0400)\/","ScheduledTimeFrom":0,"ScheduledTimeTo":0,"Status":10,"TimeZoneOffset":0}],"TotalRecords":4}}
I've been trying to return BARE JSON but haven't been able to figure it out. If I change the BodyStyle to WebMessageBodyStyle.Bare then it gives me an error that any type except WrappedRequest is incompatible with web script behavior. If I remove the Factory="System.ServiceModel.Activation.WebScriptServiceHostFactory" from the svc file then if I try to call the json service/method from a web browser, it returns a 400 bad request error.
One other site note related to that, I thought that setting "enableWebScript" in the AjaxBehavior section would do the same as the Factory= setting in the svc file, however it isn't doing anything. I have to set the Factory= in order for it to to correctly return the JSON and not give the 400 error.
So, any suggestions on how I can get this working? This JSON service is being called by mobile apps so I really don't want to return all of the "___type" attributes.
If you're using the WebScriptServiceHostFactory
, you don't need to use config at all (and since the "name" attribute in the <service>
element doesn't have a namespace, I think it's being ignored anyway). WebScriptServiceHostFactory is intended for use with the ASP.NET AJAX framework, not gor general usage. If you replace it with WebServiceHostFactory
, you should see both the {"d":
wrapping and the __type
hints for objects.
精彩评论