Consuming WCF Data Service EF , Failed to SaveChange() - odata

I am consuming WCF Data Service as Following:
DataMan.ContextWrapper context = new DataMan.ContextWrapper(new Uri("http://localhost:2060/PCM/DataMan.svc/rest/"));
DataMan.Report newReport = DataMan.Report.CreateReport("123123123123", DateTime.Now, "999.199905171156550187000.25");
newReport.Title = "tt";
newReport.StudyAcDate = Convert.ToDateTime("2016-05-04 12:09:00");
newReport.Body = "asdasd";
newReport.Auther = "ali.h";
newReport.ApproverComment = "cm";
newReport.Approver = "admin";
context.AddToReports(newReport);
DataServiceResponse response = context.SaveChanges();
but after calling SaveChange() I have got the following error:
The server encountered an error processing the request. The exception message is 'Incoming message for operation 'ProcessRequestForMessage' (contract 'IRequestHandler' with namespace 'http://tempuri.org/') contains an unrecognized http body format value 'Xml'. The expected body format value is 'Raw'. This can be because a WebContentTypeMapper has not been configured on the binding. See the documentation of WebContentTypeMapper for more details.'. See server logs for more details.
and my WCF Data Service is as following:
public class ContextWrapper : DataAccessDbContext
{
public ContextWrapper() : base("connection string")
{
}
}
[JSONPSupportBehavior]
public class DataMan : EntityFrameworkDataService<ContextWrapper>
{
public static void InitializeService(DataServiceConfiguration config)
{
config.SetEntitySetAccessRule("*", EntitySetRights.All);
config.SetEntitySetAccessRule("Studies", EntitySetRights.None);
config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
config.UseVerboseErrors = true; // TODO - Remove for production?
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
}
protected override void HandleException(HandleExceptionArgs args)
{
base.HandleException(args);
}
}
I also implemented and configured WebContentTypeMapper to bypass mentioned Error as following:
public class ContentTypeMapper : WebContentTypeMapper
{
public override WebContentFormat GetMessageFormatForContentType(string contentType)
{
return WebContentFormat.Raw;
}
}
Custom binding:
<binding name="XmlMapper">
<webMessageEncoding webContentTypeMapperType="MARCO.SOA.PCMServiceLib.ContentTypeMapper,MARCO.SOA.PCMServiceLib.Core"/>
<httpTransport manualAddressing="true"/>
</binding>
</customBinding>
Service endpoint:
<service behaviorConfiguration="Commom2.Behavior" name="MARCO.SOA.PCMServiceLib.DataMan">
<endpoint address="rest" behaviorConfiguration="Rest.Behavior" binding="webHttpBinding"
bindingConfiguration="XmlMapper" contract="System.Data.Services.IRequestHandler">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<host>
<baseAddresses>
<add baseAddress="http://localhost:2060/PCM/DataMan.svc"/>
</baseAddresses>
</host>
</service>
but it still get exception, I think something went wrong with my configuration.
Any help would be truly appreciated.
Thanks in advance.

okay, after much trouble I finally solved the problem,
so we need to initiate factory property for serviceActivation
So my relative address was:
<serviceHostingEnvironment>
<serviceActivations>
.
.
.
<add relativeAddress="DataMan.svc" service="MARCO.SOA.PCMServiceLib.DataMan"/>
.
.
.
</serviceActivations>
</serviceHostingEnvironment>
and I have changed it to
<serviceHostingEnvironment>
<serviceActivations>
.
.
.
<add relativeAddress="DataMan.svc" service="MARCO.SOA.PCMServiceLib.DataMan" factory="System.Data.Services.DataServiceHostFactory, Microsoft.Data.Services, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
.
.
.
</serviceActivations>
</serviceHostingEnvironment>
now everything is now working nice.
more info about DataServiceHostFactory
Note:
By this we don't need to override GetMessageFormatForContentType of WebContentTypeMapper and force it to return WebContentFormat.Raw or another content format and don't need any customBinding in config file.
Thanks to all.

Related

How to temporary stop logging RequestTrackingTelemetryModule in Application Insights for ASP.NET MVC(.NET Full)

How can we stop logging specific module such as RequestTrackingTelemetryModule in ASP.NET MVC (.NET Full, not .NET Core)
I have tried to remove
<Add Type="Microsoft.ApplicationInsights.Web.RequestTrackingTelemetryModule, Microsoft.AI.Web">
in ApplicationInsights.config but it throws me a strange exception
I am using Azure Web App for both staging and live environments. So I just want to stop logging request information on live environment since it cost too much.
Thanks for helping!
You can use ITelemetryProcessor, and following this link.
Add a custom class which implements ITelemetryProcessor:
public class MyTelemetryProcessor : ITelemetryProcessor
{
private ITelemetryProcessor Next { get; set; }
public MyTelemetryProcessor(ITelemetryProcessor next)
{
this.Next = next;
}
public void Process(ITelemetry telemetry)
{
RequestTelemetry request = telemetry as RequestTelemetry;
if (request != null)
{
return;
}
if (request == null)
{
this.Next.Process(telemetry);
}
}
}
Then in the ApplicationInsights.config, add this:
<TelemetryProcessors>
<Add Type="WebApplicationMVC.MyTelemetryProcessor, WebApplicationMVC">
<!-- Set public property -->
</Add>
</TelemetryProcessors>
the screenshot:
It did filter out all the requests from app insights data, test result as below:

How to set Password and Username in web.config

In my MVC Application I use the connection string is set in the Web.config via
Private connectionString As String = ConfigurationManager.ConnectionStrings("DBCS").ConnectionString
and have no problems with my db connection. But since I need a password and username to log into my database I hardcoded that in the web.config
<connectionStrings>
<add name="DBCS" connectionString="server=win\SQLExpress;database=myDb; uid=myUsername;password=myPassword" providerName="System.Data.SqlClient" />
</connectionStrings>
I am looking for a way to send the password and username from the userinterface to the config.web file first off I thought the ConfigurationManager Class should provide a property for that but I cannot find something. Can anyone explain to me how to do this?
You can save this value in app settings:
<appSettings>
<add key="DBCS" value="Data Source=win\SQLExpress;Initial Catalog=myDb;User ID={0};Password={1}" />
</appSettings>
and then do the following:
using System.Data.SqlClient;
public void DoDatabaseOperations(string _Username, string _Password)
{
string connetionString = null;
SqlConnection cnn ;
connetionString = string.Format(ConfigurationManager.AppSettings("DBCS"), _Username, _Password);
cnn = new SqlConnection(connetionString);
try
{
cnn.Open();
// your code here
cnn.Close();
}
catch (Exception ex)
{
// handle exception
}
}
VB.NET Equivalent:
Imports System.Data.SqlClient
Public Sub DoDatabaseOperations(_Username As String, _Password As String)
Dim connetionString As String = Nothing
Dim cnn As SqlConnection
connetionString = String.Format(ConfigurationManager.AppSettings("DBCS"), _Username, _Password)
cnn = New SqlConnection(connetionString)
Try
cnn.Open()
' your code here
cnn.Close()
' handle exception
Catch ex As Exception
End Try
End Sub

Entity Framework with oracle can´t change connection string

I´m using Entity Framework (latest Version) with the Oracle Driver (latest Version) in an ASP.NET MVC 5 Application. I want to set the connection string for my model during runtime, but every time I do it receives the data from the table that I used to create the model. It´s the same when I change the connection string in the web.config. Does anybody know why it behaves this way?
this is how i create the connection string:
public static string CreateConnectionString(string userName, string service)
{
const string providerName = "Oracle.ManagedDataAccess.Client";
OracleConnectionStringBuilder oraBuilder = new OracleConnectionStringBuilder();
oraBuilder.DataSource = service + ":1521/" + service;
oraBuilder.UserID = userName;
oraBuilder.Password ="xxx";
oraBuilder.PersistSecurityInfo = true;
EntityConnectionStringBuilder efBuilder = new EntityConnectionStringBuilder();
efBuilder.Metadata = "res://*/Model2.csdl|res://*/Model2.ssdl|res://*/Model2.msl";
efBuilder.Provider = providerName;
efBuilder.ProviderConnectionString = oraBuilder.ConnectionString;
return efBuilder.ConnectionString;
}
this is the overload of the model´s constructor:
public Entities(string connectionString)
: base(connectionString)
{
}
this ist my connection string:
try this connection string:
<connectionStrings>
<add name="VoccDbContext" connectionString="metadata=res://*/Entities.Vocc.VoccModel.csdl|res://*/Entities.Vocc.VoccModel.ssdl|
res://*/Entities.Vocc.VoccModel.msl;provider=Oracle.DataAccess.Client;provider connection string="DATA SOURCE=sameDbName;PASSWORD=somePass;USER ID=someUser;""providerName="System.Data.EntityClient" />
</connectionStrings>
DIRECTORY_SERVERS=(tnsnames.somesite.org:389:636)
DEFAULT_ADMIN_CONTEXT="dc=site,dc=com"
DIRECTORY_SERVER_TYPE=OID
here( LDAP.ORA file) to be modified with correct LDAP Parameters
Do not edit XXXModels.cs. Try to edit XXXModels.Context.tt.
Add following code after public <#=code.Escape(container)#>()...}
public <#=code.Escape(container)#>(string connectionString)
: base(connectionString)
{
<#
if (!loader.IsLazyLoadingEnabled(container))
{
#>
this.Configuration.LazyLoadingEnabled = false;
<#
}
foreach (var entitySet in container.BaseEntitySets.OfType<EntitySet>())
{
// Note: the DbSet members are defined below such that the getter and
// setter always have the same accessibility as the DbSet definition
if (Accessibility.ForReadOnlyProperty(entitySet) != "public")
{
#>
<#=codeStringGenerator.DbSetInitializer(entitySet)#>
<#
}
}
#>
}

Spring OXM 3 + JiBXException: No marshaller defined for class

I have used Spring OXM and JiBX in my application.
below is my Spring Config file
<context:component-scan base-package="com.controller"/>
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
<oxm:jibx-marshaller target-class="com.request.RequestClass" id="rqMarshaller"/>
<oxm:jibx-marshaller target-class="com.response.ResponseClass" id="rsMarshaller"/>
<bean id="xmlViewer" class="org.springframework.web.servlet.view.xml.MarshallingView">
<constructor-arg ref="rsMarshaller" />
</bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
below is controller class
#Controller
public class MyController {
#Autowired
private JibxMarshaller rqMarshaller;
#RequestMapping(value = "/myrequest", method = RequestMethod.POST)
public ModelAndView searchFlights(#RequestBody String request) {
System.out.println("Inside");
System.out.println("request = "+request);
Source source = new StreamSource(new StringReader(request));
RequestClass rq = null;
try {
rq = (RequestClass) rqMarshaller.unmarshal(source);
} catch (XmlMappingException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
ResponseClass e = new ResponseClass();
e.setVersion("2.0");
Orig ond = new Orig();
ond.setCode("AIT");
e.getOrig().add(ond);
return new ModelAndView("xmlViewer","object",e);
}
}
When i send XML request it marshaled successfully but for response i got following error message.
org.jibx.runtime.JiBXException: No marshaller defined for class com.response.ResponseClass
I have already defined marshaller for ResponseClassin spring config file.
please help. Thanks.
Finally i figured out the solution !!!
Need to specify the bindingName attribute while registering the JiBxMarshaller.
<oxm:jibx-marshaller target-class="com.request.RequestClass" id="rqMarshaller" bindingName="rqBinding"/>
<oxm:jibx-marshaller target-class="com.response.ResponseClass" id="rsMarshaller" bindingName="rsBinding/>
and specify same name in respective binding/mapping file of JiBX.
That's it !

Removing a dependency from a constructor

I'm using webforms and I'm wondering how I can remove the followoing concrete reference to a repository. In the past I've used castle windsor with MVC but I don't think I can use that here?
Code behind:
ICustomerRepository repos;
public Workout_Admin()
// here is the offending concrete implementation
: this(new SqlCustomerRepository()) { }
public Workout_Admin(ICustomerRepository repos)
{
this.repos = repos;
}
UPDATED ---
I've updated the static method as suggeted, as well as adding the additional code to the windsor factory
WindsorContainer container;
public WindsorControllerFactory()
{
container = new WindsorContainer(
new XmlInterpreter(new ConfigResource("castle")));
var controllerTypes =
from t in Assembly.GetExecutingAssembly().GetTypes()
where typeof(IController).IsAssignableFrom(t)
select t;
foreach (Type t in controllerTypes)
{
container.AddComponentLifeStyle(t.FullName, t,
LifestyleType.Transient);
}
CommonServiceLocatorPageHandlerFactory.Container = container;
}
The issue that keeps arriseing is with loading the assembly from the config file. The CommonServiceLocatorPageHandlerFactory is in and assembly called yourfit, folder called factory. And here are the relevant configs
<httpHandlers>
<add verb="*" path="*.aspx"
type="YourFit.Factory.CommonServiceLocatorPageHandlerFactory, YourFit"/>
</httpHandlers>
<handlers>
<remove name="UrlRoutingHandler"/>
<add name="CSLPageHandler" verb="*" path="*.aspx"
type="YourFit.Factory.CommonServiceLocatorPageHandlerFactory, YourFit"/>
</handlers>
and the error is:
Could not load type 'YourFit.Factory.CommonServiceLocatorPageHandlerFactory' from assembly 'YourFit'.
I know I'm most likely being really stupid. Thanks so much for your time on this.
You can do this. The ASP.NET compilation engine however needs a default constructor, but you can make it protected. You can inject the dependencies in the other constructor by defining a custom PageHandlerFactory that injects dependencies in the overloaded (public) constructor. Your class would look like this:
public class Workout_Admin : Page
{
ICustomerRepository repos;
protected Workout_Admin() { }
public Workout_Admin(ICustomerRepository repos)
{
this.repos = repos;
}
}
Here is an article that shows you how to do this (for Castle Windsor, just change the code in the GetInstance method to call the Windsor container). Note that you need to run in full trust for this.
UPDATE
You can change the private static object GetInstance(Type type) method that the article describes to the following:
public static IWindsorContainer Container;
private static object GetInstance(Type type)
{
return Container.Resolve(type);
}
In your application's startup path (where you configure the Castle Windsor container) you than must set the static Container property:
// Create
IWindsorContainer container = ...
// Configure
// Set container to page handler factory
CommonServiceLocatorPageHandlerFactory.Container = container;
I hope this makes sense.

Resources