.NET Framework Swashbucket Examples SwaggerRequestExample throws System.ArgumentNullException - swashbuckle

I use Swashbucket and Swashbucket.Examples NugetPackages to provide a Swagger API in .NET Framework (v.4.7.2)
Following the documentation onhttps://github.com/mattfrear/Swashbuckle.AspNetCore.Filters
I am trying to use the SwaggerRequestExample Attribute like this:
[HttpPost]
[Route("search")]
[SwaggerRequestExample(typeof(OrderRequestExample), typeof(OrderRequestExampleProvider))]
public async Task<HttpResponseMessage> SearchAsync()
{
...
}
My Startup class is configured as described in the docs:
config.EnableSwagger(c =>
{
c.SingleApiVersion("v1", "MyApi");
c.OperationFilter<ExamplesOperationFilter>();
c.IncludeXmlComments(System.String.Format(#"{0}\bin\MyApi_Api.xml",
System.AppDomain.CurrentDomain.BaseDirectory));
//c.OperationFilter<AddResponseHeadersFilter>();
}).EnableSwaggerUi(c => { c.DocumentTitle("My API");});
When I use the SwaggerRequestExample Attribute, the UI displays an error:
500 : {"Message":"An error has occurred.","ExceptionMessage":"Der Wert darf nicht NULL sein.\r\nParametername: source","ExceptionType":"System.ArgumentNullException","StackTrace":" bei System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)\r\n bei Swashbuckle.Examples.ExamplesOperationFilter.SetRequestModelExamples(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)\r\n bei Swashbuckle.Examples.ExamplesOperationFilter.Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)\r\n bei Swashbuckle.Swagger.SwaggerGenerator.CreateOperation(ApiDescription apiDesc, SchemaRegistry schemaRegistry)\r\n bei Swashbuckle.Swagger.SwaggerGenerator.CreatePathItem(IEnumerable`1 apiDescriptions, SchemaRegistry schemaRegistry)\r\n bei Swashbuckle.Swagger.SwaggerGenerator.<>c__DisplayClass7.<GetSwagger>b__4(IGrouping`2 group)\r\n bei System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)\r\n bei Swashbuckle.Swagger.SwaggerGenerator.GetSwagger(String rootUrl, String apiVersion)\r\n bei Swashbuckle.Application.SwaggerDocsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)\r\n bei System.Net.Http.HttpMessageInvoker.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)\r\n bei System.Web.Http.Dispatcher.HttpRoutingDispatcher.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)\r\n bei System.Net.Http.DelegatingHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)\r\n bei System.Web.Http.HttpServer.<SendAsync>d__24.MoveNext()"} https://localhost:44384/swagger/docs/v1
obviously, a "source" (IEnumerable) is missing (null). I can't find where to add it.
Example Classes:
public class OrderRequestExampleProvider : IExamplesProvider
{
public object GetExamples()
{
return new OrderRequestExample()
{
Name = "some name"
};
}
}
public class OrderRequestExample
{
public string Name { get; set; }
}

The solution seems quite obvious but in case you don't use deserialization of the body in the signature of the method, you get this error.
After adding the request object to the method signature the exception does not occur.
public async Task<HttpResponseMessage> SearchAsync([FromBody]OrderRequestExample request) {
...
}

Related

Cannot test ILogger<T> Received with NSubstitute

I have a .Net Core 3 application and am trying to test calls to ILogger in my method:
public class MyClass
{
private readonly ILogger<MyClass> _logger;
public MyClass(ILogger<MyClass> logger)
{
_logger = logger;
}
public void MyMethod(string message)
{
_logger.LogError(message);
}
}
Having found answers here on SO and on blogs, I know that I have to test against the interface method, not the extension method, so I have this test:
[TestMethod]
public void MyMethodTest()
{
// Arrange
var logger = Substitute.For<ILogger<MyClass>>();
var myClass = new MyClass(logger);
var message = "a message";
// Act
myClass.MyMethod(message);
// Assert
logger.Received(1).Log(
LogLevel.Error,
Arg.Any<EventId>(),
Arg.Is<object>(o => o.ToString() == message),
null,
Arg.Any<Func<object, Exception, string>>());
}
However, this isn't working and I get this error:
Test method MyLibrary.Tests.MyClassTests.MyMethodTest threw exception:
NSubstitute.Exceptions.ReceivedCallsException: Expected to receive exactly 1 call matching:
Log<Object>(Error, any EventId, o => (o.ToString() == value(MyLibrary.Tests.MyClassTests+<>c__DisplayClass0_0).message), <null>, any Func<Object, Exception, String>)
Actually received no matching calls.
at NSubstitute.Core.ReceivedCallsExceptionThrower.Throw(ICallSpecification callSpecification, IEnumerable`1 matchingCalls, IEnumerable`1 nonMatchingCalls, Quantity requiredQuantity)
at NSubstitute.Routing.Handlers.CheckReceivedCallsHandler.Handle(ICall call)
at NSubstitute.Routing.Route.Handle(ICall call)
at NSubstitute.Core.CallRouter.Route(ICall call)
at NSubstitute.Proxies.CastleDynamicProxy.CastleForwardingInterceptor.Intercept(IInvocation invocation)
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at NSubstitute.Proxies.CastleDynamicProxy.ProxyIdInterceptor.Intercept(IInvocation invocation)
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Castle.Proxies.ObjectProxy.Log[TState](LogLevel logLevel, EventId eventId, TState state, Exception exception, Func`3 formatter)
at MyLibrary.Tests.MyClassTests.MyMethodTest() in D:\Source\Scratch\MyLibrary\MyLibrary.Tests\MyClassTests.cs:line 25
What am I doing wrong?
netcoreapp3.0 / Microsoft.Extensions.Logging 3.1.2 / NSubstitute 4.2.1
UPDATE: I have tried the match with Arg.Any<>() and get the same result:
logger.Received(1).Log(
Arg.Any<LogLevel>(),
Arg.Any<EventId>(),
Arg.Any<object>(),
Arg.Any<Exception>(),
Arg.Any<Func<object, Exception, string>>());
UPDATE 2: I have tried the same test using Moq and get the same result:
logger.Verify(l => l.Log(
LogLevel.Error,
It.IsAny<EventId>(),
It.Is<object>(o => o.ToString() == message),
null,
It.IsAny<Func<object, Exception, string>>()),
Times.Once);
Result:
Test method MyLibrary.Tests.Moq.MyClassTests.MyMethodTest threw exception:
Moq.MockException:
Expected invocation on the mock once, but was 0 times: l => l.Log<object>(LogLevel.Error, It.IsAny<EventId>(), It.Is<object>(o => o.ToString() == "a message"), null, It.IsAny<Func<object, Exception, string>>())
Performed invocations:
Mock<ILogger<MyClass>:1> (l):
ILogger.Log<FormattedLogValues>(LogLevel.Error, 0, a message, null, Func<FormattedLogValues, Exception, string>)
at Moq.Mock.Verify(Mock mock, LambdaExpression expression, Times times, String failMessage)
at Moq.Mock`1.Verify(Expression`1 expression, Times times)
at Moq.Mock`1.Verify(Expression`1 expression, Func`1 times)
at MyLibrary.Tests.Moq.MyClassTests.MyMethodTest() in D:\Source\Scratch\MyLibrary\MyLibrary.Tests.Moq\MyClassTests.cs:line 25
The main issue unit testing ILogger invocations with .NET Core 3.* is that FormattedLogValues was changed to internal, it complicates things.
The Moq workaround is to use It.IsAnyType:
public class TestsUsingMoq
{
[Test]
public void MyMethod_String_LogsError()
{
// Arrange
var logger = Mock.Of<ILogger<MyClass>>();
var myClass = new MyClass(logger);
var message = "a message";
// Act
myClass.MyMethod(message);
//Assert
Mock.Get(logger)
.Verify(l => l.Log(LogLevel.Error,
It.IsAny<EventId>(),
It.Is<It.IsAnyType>((o, t) => ((IReadOnlyList<KeyValuePair<string, object>>) o).Last().Value.ToString().Equals(message)),
It.IsAny<Exception>(),
(Func<It.IsAnyType, Exception, string>) It.IsAny<object>()),
Times.Once);
}
}
NSubstitute doesn't have an It.IsAnyType equivalent at the moment as far as I am aware, which presents an issue when trying to use the Received method. There is a workaround however as it does provide a ReceivedCalls method which you can iterate over and do you own invocation check.
public class TestsUsingNSubstitute
{
[Test]
public void MyMethod_String_LogsError()
{
// Arrange
var logger = Substitute.For<ILogger<MyClass>>();
var myClass = new MyClass(logger);
var message = "a message";
// Act
myClass.MyMethod(message);
//Assert
Assert.That(logger.ReceivedCalls()
.Select(call => call.GetArguments())
.Count(callArguments => ((LogLevel) callArguments[0]).Equals(LogLevel.Error) &&
((IReadOnlyList<KeyValuePair<string, object>>) callArguments[2]).Last().Value.ToString().Equals(message)),
Is.EqualTo(1));
}
}
As a workaround, it's not a bad one, and could be easily bundled up into an extension method.
FormattedLogValues implements IReadOnlyList<KeyValuePair<string, object>>. The last item in this list is the original message that you specified.
Working sample
I tried wrapping the Logger around an adapter, more like a proxy class.
You can mock the adapter interface and that would return what log function has been called.
public class LoggerAdapter<TType> : ILoggerAdapter<TType>
{
private readonly ILogger<TType> _logger;
public LoggerAdapter(ILogger<TType> logger)
{
_logger = logger;
}
public void LogInformation(string message, params object[] args)
{
_logger.LogInformation(message,args);
}
public void LogError(string message, params object[] args)
{
_logger.LogError(message, args);
}
}
private readonly ILoggerAdapter<PosUpdateService> _logger = Substitute.For<ILoggerAdapter<PosUpdateService>>();
_logger.Received(1).LogInformation("User with Id {id} was fetched in {0} milliseconds",
Arg.Is(Id),
Arg.Any<long>());

HttpMediaTypeNotSupportedException on mockmvc post

I have a RestController and a function that accepts post requests
#RequestMapping(path = "/auth",method = RequestMethod.POST)
public void authenticate(#RequestBody AuthenticationRequest authenticationRequest, HttpServletResponse httpServletResponse) throws IOException {
}
I try to issue a post request
mockMvc.perform(post("/auth")
.contentType(MediaType.APPLICATION_JSON)
.content("{ \"foo\": \"bar\", \"fruit\": \"apple\" }".getBytes()))
.andDo(print());
I receive
Resolved Exception:
Type = org.springframework.web.HttpMediaTypeNotSupportedException
Any workaround ideas?
Edit: I also tried specifying the consumes="application/json" on the controller, but still does not work.
The Exception says that the "media type" aka "content type" is not accepted.
Try adding consumes = "application/json" to your controller function.
#RequestMapping(path = "/auth",method = RequestMethod.POST,consumes = "application/json")
public void authenticate(#RequestBody AuthenticationRequest authenticationRequest, HttpServletResponse httpServletResponse) throws IOException {
}
See the spring documentation for details https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/RequestMapping.html#consumes--

Glass Mapper (4.1.2.67) failing to map rich text field

I've got a few classes defined to map template items as follows:
public class ContentBase
{
public virtual Guid Id { get; set; }
public virtual string Name { get; set; }
[SitecoreParent]
public virtual ContentBase Parent { get; set; }
[SitecoreItem]
public virtual Item Self { get; set; }
}
[SitecoreType(TemplateId = "{7979766D-DB9C-4E75-9BE3-5B481C6AB6FF}", AutoMap = true)]
public class EventsListing : ContentBase
{
[SitecoreField(FieldName = "EventsLocation")]
public virtual SitecoreFolder<Event> Events { get; set; }
}
[SitecoreType(TemplateId = "{CED01C9B-6284-461A-848F-2CDD00CC6DEB}", AutoMap = true)]
public class Event : ContentBase
{
public virtual string Title { get; set; }
public virtual string Details { get; set; }
public virtual string iCalSummary { get; set; }
public virtual Image ImageLandscape { get; set; }
public virtual Image ImagePortrait { get; set; }
public virtual Image ImageSquare { get; set; }
public virtual string Date { get; set; }
public virtual DateTime DateStart { get; set; }
public virtual DateTime DateEnd { get; set; }
public virtual string Location { get; set; }
public virtual string GoogleMapsAddress { get; set; }
public virtual string MemberDiscount { get; set; }
public virtual Link EventLinkUrl { get; set; }
public virtual string EventLinkText { get; set; }
}
The template for the Event
I have a sublayout for the EventsListing based on GlassUserControl and that successfully gets all fields for EventsListing and the children Events. I then have a link on Date to generate an iCal for the Event via a web.api controller
[RoutePrefix("hbf/api/ical")]
public class EventICalController : ApiController
{
[Route("{id:guid}")]
[HttpGet]
public HttpResponseMessage Get(Guid id)
{
var scc = new SitecoreContext();
var item = scc.GetItem<Item>(id);
var myEvent = scc.GetItem<Models.Event>(id);
The item looks fine and I can access the fields; but the call scc.GetItem(id) throws an exception on the "Details" field.
The exception nesting is (full stack trace below):
Glass.Mapper.MapperException "Failed to create type Models.Event"
Glass.Mapper.MapperException "Failed to map properties on /sitecore/content/..."
Glass.Mapper.MapperException "Failed to map property Details on Models.Event"
System.NullReferenceException
If I comment out the "Details" property it works.
I've tried various ways to get the SitecoreContext, even specifying the language to no avail. I've also tried setting the SitecoreField attribute with the name and/or ID and the field type.
What can I in terms of configuration (or something) to resolve this?
{
"Message": "An error has occurred.",
"ExceptionMessage": "Failed to create type xxx.Web.Models.Event",
"ExceptionType": "Glass.Mapper.MapperException",
"StackTrace": " at Glass.Mapper.Pipelines.ObjectConstruction.Tasks.CreateConcrete.CreateConcreteTask.CreateObject(ObjectConstructionArgs args) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper\\Pipelines\\ObjectConstruction\\Tasks\\CreateConcrete\\CreateConcreteTask.cs:line 115
at Glass.Mapper.Pipelines.ObjectConstruction.Tasks.CreateConcrete.CreateConcreteTask.Execute(ObjectConstructionArgs args) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper\\Pipelines\\ObjectConstruction\\Tasks\\CreateConcrete\\CreateConcreteTask.cs:line 68
at Glass.Mapper.Pipelines.AbstractPipelineRunner`2.<>c__DisplayClass3.<CreateTaskExpression>b__2(T args) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper\\Pipelines\\AbstractPipelineRunner.cs:line 77
at Glass.Mapper.Pipelines.AbstractPipelineRunner`2.<>c__DisplayClass3.<CreateTaskExpression>b__2(T args) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper\\Pipelines\\AbstractPipelineRunner.cs:line 82
at Glass.Mapper.Pipelines.AbstractPipelineRunner`2.<>c__DisplayClass3.<CreateTaskExpression>b__2(T args) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper\\Pipelines\\AbstractPipelineRunner.cs:line 82
at Glass.Mapper.Pipelines.AbstractPipelineRunner`2.<>c__DisplayClass3.<CreateTaskExpression>b__2(T args) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper\\Pipelines\\AbstractPipelineRunner.cs:line 82
at Glass.Mapper.Pipelines.AbstractPipelineRunner`2.<>c__DisplayClass3.<CreateTaskExpression>b__2(T args) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper\\Pipelines\\AbstractPipelineRunner.cs:line 82
at Glass.Mapper.Pipelines.AbstractPipelineRunner`2.<>c__DisplayClass3.<CreateTaskExpression>b__2(T args) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper\\Pipelines\\AbstractPipelineRunner.cs:line 82
at Glass.Mapper.AbstractService.InstantiateObject(AbstractTypeCreationContext abstractTypeCreationContext) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper\\AbstractService.cs:line 138
at Glass.Mapper.Sc.SitecoreService.CreateType(Type type, Item item, Boolean isLazy, Boolean inferType, Dictionary`2 parameters, Object[] constructorParameters) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper.Sc\\SitecoreService.cs:line 498
at Glass.Mapper.Sc.SitecoreService.GetItem[T](Guid id, Boolean isLazy, Boolean inferType) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper.Sc\\SitecoreService.cs:line 899
at xxx.Web.Services.xxx.EventICalController.Get(Guid id) in d:\\Dev\\LW\\xxx.Web\\Services\\xxx\\EventICalController.cs:line 57
at lambda_method(Closure , Object , Object[] )
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass10.<GetExecutor>b__9(Object instance, Object[] methodParameters)
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()",
"InnerException": {
"Message": "An error has occurred.",
"ExceptionMessage": "Failed to map properties on /sitecore/content/xxx/Home/Living well/Events/datasources/Health and fitness events/xxx Fitness.",
"ExceptionType": "Glass.Mapper.MapperException",
"StackTrace": " at Glass.Mapper.Configuration.AbstractTypeConfiguration.MapPropertiesToObject(Object obj, IAbstractService service, AbstractTypeCreationContext context) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper\\Configuration\\AbstractTypeConfiguration.cs:line 174
at Glass.Mapper.Pipelines.ObjectConstruction.Tasks.CreateConcrete.CreateConcreteTask.CreateObject(ObjectConstructionArgs args) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper\\Pipelines\\ObjectConstruction\\Tasks\\CreateConcrete\\CreateConcreteTask.cs:line 104",
"InnerException": {
"Message": "An error has occurred.",
"ExceptionMessage": "Failed to map property Details on xxx.Web.Models.Event",
"ExceptionType": "Glass.Mapper.MapperException",
"StackTrace": " at Glass.Mapper.Configuration.AbstractTypeConfiguration.<>c__DisplayClassb.<CreatePropertyExpression>b__a(Object obj, AbstractDataMappingContext context) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper\\Configuration\\AbstractTypeConfiguration.cs:line 123
at Glass.Mapper.Configuration.AbstractTypeConfiguration.MapPropertiesToObject(Object obj, IAbstractService service, AbstractTypeCreationContext context) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper\\Configuration\\AbstractTypeConfiguration.cs:line 144",
"InnerException": {
"Message": "An error has occurred.",
"ExceptionMessage": "Failed to map to property 'Details' on type 'xxx.Web.Models.Event'",
"ExceptionType": "Glass.Mapper.MapperException",
"StackTrace": " at Glass.Mapper.AbstractDataMapper.MapCmsToProperty(AbstractDataMappingContext mappingContext) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper\\AbstractDataMapper.cs:line 64
at Glass.Mapper.Configuration.AbstractTypeConfiguration.<>c__DisplayClassb.<CreatePropertyExpression>b__a(Object obj, AbstractDataMappingContext context) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper\\Configuration\\AbstractTypeConfiguration.cs:line 119",
"InnerException": {
"Message": "An error has occurred.",
"ExceptionMessage": "Object reference not set to an instance of an object.",
"ExceptionType": "System.NullReferenceException",
"StackTrace": " at xxx.Core.Pipelines.RenderField.GetDevModeContent.Process(RenderFieldArgs args)
at (Object , Object[] )
at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args)
at Glass.Mapper.Sc.DataMappers.SitecoreFieldStringMapper.RunPipeline(Field field) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper.Sc\\DataMappers\\SitecoreFieldStringMapper.cs:line 99
at Glass.Mapper.AbstractDataMapper.MapCmsToProperty(AbstractDataMappingContext mappingContext) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper\\AbstractDataMapper.cs:line 60"
}
}
}
}
}
I added the Glass.Mapper.Sc.* projects source to my solution (yay for open source) and stepped through and found that I needed to add some extra configuration for the rich text field, as follows:
[SitecoreField(Setting = SitecoreFieldSettings.RichTextRaw)]
public virtual string Details { get; set; }
This way the field does not go through the render process and just returns the raw HTML, which is what I wanted. It was the render process that failed, this is kind of a half answer as I don't know why the render process failed, but I don't need it. Unfortunately I didn't find what I needed in the Glass.Mapper documentation.
I believe that Glass is failing to resolve the Context.Site. Since web api calls don't have a context site by default. You can probably wrap your entire call inside a using (new SiteContextSwitcher(Factory.GetSite("yoursite"))), or find another way to set the Context.Site inside your service call.
or if you have multiple sites, make sure they have the hostName property defined in your <sites> node, and something like this at the top of the call:
var sites = Sitecore.Configuration.Factory.GetSiteInfoList();
string currentHost = HttpContext.Current.Request.Url.Host;
var currentSite = sites.FirstOrDefault(obj => obj.HostName.Equals(currentHost, StringComparison.InvariantCultureIgnoreCase));
if (currentSite != null)
{
var newSite = new Sitecore.Sites.SiteContext(currentSite);
if (newSite != null)
{
using (new SiteContextSwitcher(newSite))
{
///Code here
}
{
{

No 'Access-Control-Allow-Origin' header is present on the requested resource.

I'm using SpringMVC.I want to call an XML file with web service in order to parse it later.The problem is that I can't access the XML file, I have got this error:No 'Access-Control-Allow-Origin' header is present on the requested resource.I have tried the solution below:
I created a new class which purpose is to add Access-Control-Allow-Origin' header on the requested ressource.This is the class
package com.mycompany.myapp;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class JsonpFilter implements Filter {
private String functionName;
#Override
public void destroy() {
}
#Override
public void doFilter(ServletRequest request, ServletResponse servletResponse,
FilterChain chain) throws IOException, ServletException {
if (!(request instanceof HttpServletRequest)) {
throw new ServletException("This filter can "
+ " only process HttpServletRequest requests");
}
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse response = (HttpServletResponse) servletResponse;
if (isJSONPRequest(httpRequest)) {
ServletOutputStream out = response.getOutputStream();
out.println(getCallbackMethod(httpRequest) + "(");
chain.doFilter(request, response);
out.println(");");
response.setContentType("text/javascript");
} else {
response.addHeader("Access-Control-Allow-Origin", "*");
chain.doFilter(request, response);
}
}
#Override
public void init(FilterConfig filterConfig) throws ServletException {
this.functionName = filterConfig.getInitParameter("encoding");
if(this.functionName == null || this.functionName.length() <= 0) {
this.functionName = "callback";
}
}
private String getCallbackMethod(HttpServletRequest httpRequest) {
return httpRequest.getParameter(this.functionName);
}
private boolean isJSONPRequest(HttpServletRequest httpRequest) {
String callbackMethod = getCallbackMethod(httpRequest);
return (callbackMethod != null && callbackMethod.length() > 0);
}
}
then I add the these two lines in my web.xml file:
<display-name>DataServices</display-name>
<filter>
<filter-name>JSONPRequestFilter</filter-name>
<filter-class> com.mycompany.myapp.JsonpFilter</filter-class>
<init-param>
<param-name>functionName</param-name>
<param-value>callback</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>JSONPRequestFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
I don't have any complilation problem, but I still have the same error in the console at the execution time.So, the 'Access-Control-Allow-Origin' header isn't taken into account.
Please,If you can find out what is wrong with my program, or suggest me another solution, I will be thankful
To do this implement this interface
org.springframework.web.servlet.HandlerInterceptor
here is an example
#Component
public class CORSInterceptor implements HandlerInterceptor{
private static final Log LOG = LogFactory.getLog(CORSInterceptor.class);
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
LOG.trace("sending headers");
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
return true;
}
#Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
throws Exception {
}
#Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
LOG.trace("afterCompletion is called");
}
}
Then add this line to your application context
<mvc:interceptors>
<bean class="com.elm.mb.rest.interceptors.CORSInterceptor" />
</mvc:interceptors>

What's about "ClassCastExceptionclass org.apache.avro.mapred.AvroKey"?

I am programming MapR with Avro, and a real beginner against Avro. The input and output are both avro format with specific schema.
Here is my mapper and reducer using mapreduce API of MR1:
public class UserClassifyMapReduce extends Configured implements Tool {
private final static Logger logger = LoggerFactory.getLogger(UserClassifyMapReduce.class);
public static void main(String[] args) throws Exception {
int res = ToolRunner.run(new Configuration(), new UserClassifyMapReduce(), args);
System.exit(res);
}
#Override
public int run(String[] args) throws Exception {
if (args.length < 2) {
logger.error("Usage: UserClassify <intputfile> <outputfolder>");
System.exit(-1);
}
Configuration conf = new Configuration();
Job job = new Job(getConf());
job.setJobName("UserClassify");
AvroJob.setInputKeySchema(job, NetflowRecord.getClassSchema());
AvroJob.setOutputKeySchema(job, NetflowRecord.getClassSchema());
FileInputFormat.setInputPaths(job, new Path(args[0]));
Path outPath = new Path(args[1]);
FileOutputFormat.setOutputPath(job, outPath);
outPath.getFileSystem(conf).delete(outPath, true);
job.setJarByClass(DataSerializeMapReduce.class);
job.setMapperClass(MyAvroMap.class);
job.setReducerClass(MyAvroReduce.class);
job.setInputFormatClass(AvroKeyInputFormat.class);
job.setOutputFormatClass(AvroKeyOutputFormat.class);
job.setMapOutputKeyClass(AvroKey.class);
job.setMapOutputValueClass(AvroValue.class);
job.setOutputKeyClass(AvroKey.class);
job.setOutputValueClass(NullWritable.class);
return job.waitForCompletion(true) ? 0 : 1;
}
public static class MyAvroMap extends Mapper<AvroKey<NetflowRecord>, NullWritable,
AvroKey<CharSequence>, AvroValue<NetflowRecord>>{
#Override
protected void map(AvroKey<NetflowRecord> key, NullWritable value, Context context)
throws IOException, InterruptedException{
CharSequence devMac = key.datum().getDevMacAddr();
context.write(new AvroKey<CharSequence>(devMac), new AvroValue<NetflowRecord>(key.datum()));
}
}
public static class MyAvroReduce extends Reducer<AvroKey<CharSequence>, AvroValue<NetflowRecord>,
AvroKey<NetflowRecord>, NullWritable>{
#Override
protected void reduce(AvroKey<CharSequence> key, Iterable<AvroValue<NetflowRecord>> values, Context context)
throws IOException, InterruptedException{
(...code)
}
}
}
The CastError throws messages like
java.lang.Exception: java.lang.ClassCastException: class org.apache.avro.mapred.AvroKey
at org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:354)
Caused by: java.lang.ClassCastException: class org.apache.avro.mapred.AvroKey
at java.lang.Class.asSubclass(Class.java:3116)
at org.apache.hadoop.mapred.JobConf.getOutputKeyComparator(JobConf.java:795)
at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.<init>(MapTask.java:964)
at org.apache.hadoop.mapred.MapTask$NewOutputCollector.<init>(MapTask.java:673)
at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:756)
at org.apache.hadoop.mapred.MapTask.run(MapTask.java:364)
at org.apache.hadoop.mapred.LocalJobRunner$Job$MapTaskRunnable.run(LocalJobRunner.java:223)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
A very simple program. Do u have any idea about this problem. Thanks alot.
Jamin
You appear to be lacking a schema for the mapper output key AvroKey<CharSequence>. Adding the corresponding schema should be sufficient:
AvroJob.setMapOutputKeySchema(job, Schema.create(Schema.Type.STRING));