Hi, OSTEPHAN:
I installed the Orchard 1.9.1 and Orchard.Syndication.OData-1.9.0.1 on my computer with VS2013+WIN 7, Then I write some client's test code using "OData V4 Client Code Genterator", it will got an error that told "Please make sure that the top level element is a valid Atom or JSON element"
I tried many time that I found it always returned "content-type:text/html" at all odata request, so I checked the your code and I found something error at "Orchard.OData.ODataExtensions.GetODataMessageWriter"
```
internal static ODataMessageWriter GetODataMessageWriter(this HttpContext httpContext,
HttpStatusCode statusCode, string contentTypeHeader, IEdmModel edmModel) {
var httpRequest = httpContext.Request;
var httpResponse = httpContext.Response;
// #### problem line ####
httpResponse.Headers.Add(ODataConstants.ContentTypeHeader, contentTypeHeader);
var httpWebResponseMessage = new HttpWebResponseMessage(
httpResponse.Headers.ToDictionary(),
(int)statusCode,
() => httpResponse.OutputStream) as IODataResponseMessage;
var settings = new ODataMessageWriterSettings();
//settings.SetContentType(ODataFormat.Json);
settings.ODataUri = new ODataUri() { ServiceRoot = httpRequest.ODataRootService() };
return new ODataMessageWriter((IODataResponseMessage)httpWebResponseMessage, settings, edmModel);
}
```
I've reading the code of "HttpResponse.cs", and I found httpResponse.ContentType will set to httpResposne.Header["Content-type"] when response flushing, so it don't work in .NET 4.X with IISExpress OR IIS, maybe it work in Azure?
but If I direct set httpResponse.ContentType , it will get another OData error, so I add some code at Orchard.OData.Services.ODataHttpHandler
```
void IHttpHandler.ProcessRequest(HttpContext context) {
var oDataHttpHandler = this as IODataHttpHandler;
var edmModel = this._metadataBuilder.BuildModel();
var httpRequest = context.Request;
var httpResponse = context.Response;
httpResponse.Headers.Add(ODataConstants.ODataVersionHeader, ODataHttpHandler.odata_version);
var lastUriSegment = httpRequest.Url.Segments.LastOrDefault();
try {
if (httpRequest.HttpMethod.ToLower() != "get") {
throw new ODataErrorException(new ODataError() {
ErrorCode = HttpStatusCode.NotImplemented.ToString(),
InnerError = new ODataInnerError(new NotImplementedException()) });
}
if (lastUriSegment.ToLower().StartsWith("odata")) {
oDataHttpHandler.ProcessServiceDocumentRequest(context, edmModel);
return;
}
if (lastUriSegment.ToLower() == "$metadata") {
oDataHttpHandler.ProcessMetadataRequest(context, edmModel);
return;
}
oDataHttpHandler.ProcessDataRequest(context, edmModel);
}
catch (ODataErrorException oDataException) {
HttpStatusCode httpStatusCode = HttpStatusCode.BadRequest;
Enum.TryParse<HttpStatusCode>(oDataException.Error.ErrorCode, out httpStatusCode);
var odataWriter = context.GetODataMessageWriter(httpStatusCode, MimeConstants.MimeApplicationJson, edmModel);
odataWriter.WriteError(oDataException.Error, true);
}
catch {
throw;
}
finally
{
// ##### CONTENT-TYPE BUG FIX BY NETHERWIND
if( !string.IsNullOrEmpty( context.Response.Headers["content-type"] ) )
{
context.Response.ContentType = context.Response.Headers["content-type"];
}
}
}
```
Then my client application worked. may be here have compatibility bug?
Another error that it always display error when no query data matched, but custom odata webapi base on ODataController will not, so I changed some code at "IODataHttpHandler.ProcessDataRequest"
```
void IODataHttpHandler.ProcessDataRequest(HttpContext context, IEdmModel edmModel) {
// ####### begin fix [by NetherWind]
var requestUri = context.Request.Url;
var lastSegment = requestUri.Segments.Last();
var entitySetName = lastSegment.Split("(".ToArray()).First();
var entitySet = edmModel.FindEntityContainer(MetadataBuilder._qualifiedContainer)
.EntitySets()
.FirstOrDefault(es => es.Name.ToLower() == entitySetName.ToLower());
if (null == entitySet)
{
throw new ODataErrorException(new ODataError()
{
ErrorCode = HttpStatusCode.NotFound.ToString()
});
}
var entityType = entitySet.EntityType();
var contentItems = this._dataRequestBroker.ExecuteQuery(context.Request, edmModel);
//if (!(null != contentItems && contentItems.Any()))
if ( null == contentItems )
{
throw new ODataErrorException(new ODataError() {
ErrorCode = HttpStatusCode.NoContent.ToString() });
}
// ####### end fix [by NetherWind]
var contentItemEntries = contentItems
.Select(contentItem => this._dataRequestBroker.BuildEntry(contentItem, edmModel))
.ToList();
// var entitySetName = contentItems.First().TypeDefinition.Name + "s";
// var entitySet = edmModel.EntityContainer.EntitySets().First(es => es.Name == entitySetName);
// var entityType = entitySet.EntityType();
var odataWriter = context.GetODataMessageWriter(HttpStatusCode.OK, MimeConstants.MimeApplicationJson, edmModel);
ODataWriter feedWriter = odataWriter.CreateODataFeedWriter(entitySet, entityType);
feedWriter.WriteStart(new ODataFeed() {
Id = new System.Uri(context.Request.ODataRootService(), entitySet.Name)
});
contentItemEntries.ForEach(cie => {
feedWriter.WriteStart(cie);
feedWriter.WriteEnd();
});
feedWriter.WriteEnd();
}
```
it only just worked but it broked OO struction, I don't have more solution so I using this bad hot fix because I am Orchard's greenhand, Could you help me test my code and fix bug?
Comments: ** Comment from web user: nate_bunton **
OStephan do you have an expected release of the bug fix?