I am building an android application. My code shows no errors neither the LogCat but when i run my app i get only the dialog "Loading...." and nothing more. Can anyone help me to resolve this issue?
Here is my Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="movies.esprit.tn.edu.moviesparsingjson" >
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:name=".AppController"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
AppController
public class AppController extends Application {
public static final String TAG = AppController.class.getSimpleName();
private RequestQueue mRequestQueue;
private ImageLoader mImageLoader;
private static AppController mInstance;
#Override
public void onCreate() {
super.onCreate();
mInstance=this;
}
public static synchronized AppController getmInstance(){
return mInstance;
}
public RequestQueue getmRequestQueue(){
if(mRequestQueue == null){
mRequestQueue=Volley.newRequestQueue(getApplicationContext());
}
return mRequestQueue;
}
public ImageLoader getmImageLoader(){
getmRequestQueue();
if (mImageLoader==null){
mImageLoader = new ImageLoader(this.mRequestQueue, new BitmapCache());
}
return this.mImageLoader;
}
public <T> void addToRequestQueue (Request<T> request, String tag){
request.setTag((TextUtils.isEmpty(tag) ? TAG : tag));
getmRequestQueue().add(request);
}
private <T> void addToRequestQueue(Request<T> request) {
request.setTag(TAG);
getmRequestQueue().add(request);
}
public void cancelPendingRequest (Object tag){
if (mRequestQueue!=null){
mRequestQueue.cancelAll(tag);
}
}
}
this is my ItemAdapter (my customized Adapter)
public class ItemAdapter extends BaseAdapter {
private Activity activity;
private LayoutInflater inflater;
private List<Item> items;
private ImageLoader imageLoader = AppController.getmInstance().getmImageLoader();
public ItemAdapter(Activity activity, List<Item> items){
this .activity = activity;
this.items=items;
}
#Override
public int getCount() {
return items.size();
}
#Override
public Object getItem(int position) {
return items.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (inflater == null){
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
if(convertView==null){
convertView = inflater.inflate(R.layout.custom_layout,null);
}
if (imageLoader==null){
imageLoader=AppController.getmInstance().getmImageLoader();
NetworkImageView imageView = (NetworkImageView) convertView.findViewById(R.id.thumbnail);
TextView title = (TextView) convertView.findViewById(R.id.titile);
TextView rating = (TextView) convertView.findViewById(R.id.rating);
Item.ResultsEntity item = (Item.ResultsEntity) getItem(position);
imageView.setImageUrl(item.getPoster_120x171(),imageLoader);
title.setText(String.valueOf(item.getTitle()));
rating.setText(String.valueOf(item.getRating()));
}
return convertView;
}
}
this is my mainActivity
public class MainActivity extends AppCompatActivity {
private static final String url = "http://api-public.guidebox.com/v1.43/Tunisia/rKgEWJbFg0kgEHrcGXPKhPDo0XtTafyC/movies/all/250/250";
private ProgressDialog dialog;
private List<Item> array=new ArrayList<Item>();
private ListView listView;
private ItemAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.list_item);
adapter = new ItemAdapter(this, array);
listView.setAdapter(adapter);
dialog = new ProgressDialog(this);
dialog.setMessage("Loading.... ");
dialog.show();
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(url, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray jsonArray) {
hideDialog();
for (int i = 0; i<jsonArray.length(); i++){
try {
JSONObject obj = jsonArray.getJSONObject(i);
Item.ResultsEntity item = new Item.ResultsEntity();
item.setTitle(obj.getString("title"));
item.setPoster_120x171(obj.getString("poster_120x171"));
item.setRating(obj.getString("rating"));
}catch (JSONException ex){
ex.printStackTrace();
}
}
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
}
});
AppController.getmInstance().addToRequestQueue(jsonArrayRequest,url);
}
public void hideDialog(){
if (dialog!=null){
dialog.dismiss();
dialog=null;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Finally this is the LogCat
05-12 03:22:28.582 813-813/movies.esprit.tn.edu.moviesparsingjson I/SELinux﹕ Function: selinux_android_load_priority [0], There is no sepolicy file.
05-12 03:22:28.622 813-813/movies.esprit.tn.edu.moviesparsingjson I/SELinux﹕ Function: selinux_android_load_priority , spota verifySig and checkHash pass. priority version is VE=SEPF_SM-G3815_4.4.2_0046
05-12 03:22:28.622 813-813/movies.esprit.tn.edu.moviesparsingjson E/dalvikvm﹕ >>>>> Normal User
05-12 03:22:28.622 813-813/movies.esprit.tn.edu.moviesparsingjson E/dalvikvm﹕ >>>>> movies.esprit.tn.edu.moviesparsingjson [ userId:0 | appId:10201 ]
05-12 03:22:28.622 813-813/movies.esprit.tn.edu.moviesparsingjson D/dalvikvm﹕ Late-enabling CheckJNI
05-12 03:22:28.862 813-813/movies.esprit.tn.edu.moviesparsingjson W/dalvikvm﹕ VFY: unable to find class referenced in signature (Landroid/view/SearchEvent;)
05-12 03:22:28.862 813-813/movies.esprit.tn.edu.moviesparsingjson I/dalvikvm﹕ Could not find method android.view.Window$Callback.onSearchRequested, referenced from method android.support.v7.view.WindowCallbackWrapper.onSearchRequested
05-12 03:22:28.862 813-813/movies.esprit.tn.edu.moviesparsingjson W/dalvikvm﹕ VFY: unable to resolve interface method 14536: Landroid/view/Window$Callback;.onSearchRequested (Landroid/view/SearchEvent;)Z
05-12 03:22:28.862 813-813/movies.esprit.tn.edu.moviesparsingjson D/dalvikvm﹕ VFY: replacing opcode 0x72 at 0x0002
05-12 03:22:28.862 813-813/movies.esprit.tn.edu.moviesparsingjson I/dalvikvm﹕ Could not find method android.view.Window$Callback.onWindowStartingActionMode, referenced from method android.support.v7.view.WindowCallbackWrapper.onWindowStartingActionMode
05-12 03:22:28.862 813-813/movies.esprit.tn.edu.moviesparsingjson W/dalvikvm﹕ VFY: unable to resolve interface method 14540: Landroid/view/Window$Callback;.onWindowStartingActionMode (Landroid/view/ActionMode$Callback;I)Landroid/view/ActionMode;
05-12 03:22:28.862 813-813/movies.esprit.tn.edu.moviesparsingjson D/dalvikvm﹕ VFY: replacing opcode 0x72 at 0x0002
05-12 03:22:28.893 813-813/movies.esprit.tn.edu.moviesparsingjson I/dalvikvm﹕ Could not find method android.content.res.TypedArray.getChangingConfigurations, referenced from method android.support.v7.widget.TintTypedArray.getChangingConfigurations
05-12 03:22:28.893 813-813/movies.esprit.tn.edu.moviesparsingjson W/dalvikvm﹕ VFY: unable to resolve virtual method 420: Landroid/content/res/TypedArray;.getChangingConfigurations ()I
05-12 03:22:28.893 813-813/movies.esprit.tn.edu.moviesparsingjson D/dalvikvm﹕ VFY: replacing opcode 0x6e at 0x0002
05-12 03:22:28.893 813-813/movies.esprit.tn.edu.moviesparsingjson I/dalvikvm﹕ Could not find method android.content.res.TypedArray.getType, referenced from method android.support.v7.widget.TintTypedArray.getType
05-12 03:22:28.893 813-813/movies.esprit.tn.edu.moviesparsingjson W/dalvikvm﹕ VFY: unable to resolve virtual method 442: Landroid/content/res/TypedArray;.getType (I)I
05-12 03:22:28.893 813-813/movies.esprit.tn.edu.moviesparsingjson D/dalvikvm﹕ VFY: replacing opcode 0x6e at 0x0002
05-12 03:22:28.963 813-813/movies.esprit.tn.edu.moviesparsingjson D/AbsListView﹕ Get MotionRecognitionManager
05-12 03:22:29.113 813-813/movies.esprit.tn.edu.moviesparsingjson I/Adreno-EGL﹕ <qeglDrvAPI_eglInitialize:381>: EGL 1.4 QUALCOMM build: Nondeterministic_AU_msm8960_KK_2.7_RB1__release_AU ()
OpenGL ES Shader Compiler Version: 17.01.12.SPL
Build Date: 03/25/14 Tue
Local Branch:
Remote Branch: quic/kk_2.7_rb1.32
Local Patches: NONE
Reconstruct Branch: NOTHING
05-12 03:22:29.143 813-813/movies.esprit.tn.edu.moviesparsingjson D/OpenGLRenderer﹕ Enabling debug mode 0
05-12 03:22:29.153 813-813/movies.esprit.tn.edu.moviesparsingjson D/ProgressBar﹕ updateDrawableBounds: left = 0
05-12 03:22:29.153 813-813/movies.esprit.tn.edu.moviesparsingjson D/ProgressBar﹕ updateDrawableBounds: top = 0
05-12 03:22:29.153 813-813/movies.esprit.tn.edu.moviesparsingjson D/ProgressBar﹕ updateDrawableBounds: right = 72
05-12 03:22:29.153 813-813/movies.esprit.tn.edu.moviesparsingjson D/ProgressBar﹕ updateDrawableBounds: bottom = 72
Since i got no answer for this issue, i worked with Retrofit and it worked like a charm. In case anyone got the same issue
Related
Here's my xaml file.
<RefreshView x:Name="myRefreshView" Refreshing="myRefreshView_RefreshingAsync" RefreshColor="#b52b2b">
<ScrollView>
<StackLayout>
<Label Text="{Binding firstName }" />
</StackLayout>
</ScrollView>
</RefreshView>
Here's my .cs file which has a function
namespace Health.Views
{
public partial class LandingPage : ContentPage
{
public string firstName { set; get; }
public LandingPage()
{
firstName = "Mary";
this.BindingContext = this;
}
async void myRefreshView_RefreshingAsync(Object sender, System.EventArgs e)
{
await Task.Delay(3000);
firstName = "John";
myRefreshView.IsRefreshing = false;
}
}
}
The problem is when I refresh, the name is not change to "John". Not sure what else I have to add.
You need to implement INotifyPropertyChanged.
public class LandingPage : ContentPage, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _firstName;
public string firstName {
get{return _firstName;}
set
{
_firstName = value;
OnPropertyChanged("firstName");
} }
protected void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
I am getting following exception when implementing the code below the exception.
Java.lang.IllegalStateException: The specific child already has a parent. you must call the removeView() on the child's parent first.
using System;
using Android.Support.V7.Widget;
using Android.Views;
using Android.Widget;
using Android.App;
namespace Recycle.Droid
{
internal class albumadapter1 : RecyclerView.Adapter
{
// private int[] imageid;
// private Photo_album palbum;
// private _Recycler _Recycler;
private int[] imageid;
private Activity mainActivity;
public albumadapter1(Activity context, int[] imageid)
{
this.mainActivity = context;
this.imageid = imageid;
}
public override int ItemCount
{
get
{
return imageid.Length;
}
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
PhotoViewHolder vh1 = holder as PhotoViewHolder;
vh1.img.SetImageResource(imageid[position]);
//vh.Caption.Text = palbum[position].Caption;
}
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
var itemview = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.view_holder, parent);
PhotoViewHolder vh = new PhotoViewHolder(itemview);
return vh;
}
}
public class PhotoViewHolder : RecyclerView.ViewHolder
{
public TextView tv { get; private set; }
public ImageView img { get; private set; }
public PhotoViewHolder(View itemView) : base(itemView)
{
img = itemView.FindViewById<ImageView>(Resource.Id.imageView1);
// var Caption = itemView.FindViewById<TextView>(Resource.Id.textView);
// public PhotoViewHolder(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
}
}
}
please help me with problem.
Add False to the code below your issue will be solved
.......
...
...
..
.
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
var itemview = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.view_holder, parent, false);
PhotoViewHolder vh = new PhotoViewHolder(itemview);
return vh;
}
.....
...
..
.
I have tried using callback similar to my fragments and other people suggestion on callbacks, However I've had no luck i could be doing the callbacks wrong. The Toast inside the onResponse method of JsonArrayRequest returns an array size of 2. But i get 0 on the toast outside of the request. consignment.class implements parcelable
public class BackgroundTask{
String json_url;
Gson gson;
Type listType;
ProgressDialog pDialog;
ArrayList<Consignment> arrayList = new ArrayList<>();
AppController appController;
ConsAdapter adapter;
Context context;
public BackgroundTask(Context context){
this.context = context;
listType = new TypeToken<List<Consignment>>(){}.getType();
appController = AppController.getInstance();
gson = new Gson();
}
public void getAllCons(final GetAllConsListener callBack) {
String tag_json_obj = "json_obj_req";
//showProgressDialog();
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, json_url,null,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
callBack.onSuccess(response.toString());
//hideProgressDialog();
Toast.makeText(context, "Consignments:"+arrayList.size(), Toast.LENGTH_LONG).show();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//Toast.makeText(context, "Error...", Toast.LENGTH_SHORT).show();
error.printStackTrace();
//hideProgressDialog();
}
});
appController.addToRequestQueue(jsonArrayRequest);
}
Activity Class:
public class GetConsActivity extends AppCompatActivity {
RecyclerView recyclerView;
ConsAdapter adapter;
RecyclerView.LayoutManager layoutManager;
ArrayList<Consignment> arrayList;
TextView txtView;
BackgroundTask backgroundTask;
Type listType;
Gson gson;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_get_cons);
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
gson = new Gson();
listType = new TypeToken<ArrayList<Consignment>>(){}.getType();
BackgroundTask backgroundTask = new BackgroundTask(GetConsActivity.this);
backgroundTask.getAllCons(new GetAllConsListener() {
#Override
public void onSuccess(String response) {
ArrayList<Consignment> list = parseResponse(response);
updateUI(list);
//Toast.makeText(GetConsActivity.this, "Consignments:"+arrayList.size(), Toast.LENGTH_LONG).show();
Log.d("ONSUCCESS", "ARRAYSIZE: "+arrayList.size());
}
});
}
public ArrayList<Consignment> parseResponse(String response){
ArrayList<Consignment> list = new ArrayList<>();
try {
JSONArray jsonArray = new JSONArray(response);
Log.d("PARSE", "parseResponse: "+jsonArray.length());
JSONObject jsonObject = jsonArray.getJSONObject(0);
for (int i = 0; i<jsonArray.length();i++){
Consignment con = null;
Log.d("PARSE", "parseID: "+jsonObject.getInt("conid"));
con.setConid(jsonObject.getInt("conid"));
Log.d("PARSE", "conID: "+con.getConid());
con.setDescription(jsonObject.getString("description"));
list.add(con);
}
Log.d("PARSED", "parsedResponse: "+list.size());
} catch (JSONException e) {
e.printStackTrace();
}
//arrayList =gson.fromJson(response,new TypeToken<ArrayList<Consignment>>(){}.getType());
//updateUI(arrayList);
return list;
}
public void updateUI(ArrayList<Consignment> consignments){
this.arrayList = consignments;
Log.d("UPDATE", "parseResponse: "+consignments.size());
if (adapter == null) {
adapter = new ConsAdapter(consignments,GetConsActivity.this);
recyclerView.setAdapter(adapter);
}else{
adapter.setConsignments(consignments);
adapter.notifyDataSetChanged();
}
}
Error:
D/mali_winsys: EGLint new_window_surface(egl_winsys_display*, void*, EGLSurface, EGLConfig, egl_winsys_surface**, egl_color_buffer_format*, EGLBoolean) returns 0x3000, [1440x2560]-format:1
E/RecyclerView: No adapter attached; skipping layout
I/qtaguid: Untagging socket 51
D/ViewRootImpl: MSG_RESIZED_REPORT: ci=Rect(0, 84 - 0, 0) vi=Rect(0, 84 - 0, 0) or=1
E/RecyclerView: No adapter attached; skipping layout
D/PARSE: parseResponse: 4
D/PARSE: parseID: 123456789
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.angel.createcon, PID: 26952
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.angel.createcon.Consignment.setConid(int)' on a null object reference
at com.angel.createcon.GetConsActivity.parseResponse(GetConsActivity.java:80)
at com.angel.createcon.GetConsActivity$2.onSuccess(GetConsActivity.java:56)
at com.angel.createcon.BackgroundTask$2.onResponse(BackgroundTask.java:50)
at com.angel.createcon.BackgroundTask$2.onResponse(BackgroundTask.java:47)
at com.android.volley.toolbox.JsonRequest.deliverResponse(JsonRequest.java:65)
at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7331)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
I/Process: Sending signal. PID: 26952 SIG: 9
Application terminated.
So I'll take a stab at this - having the activity implement the listener that way is a bit strange, though I don't think that's the issue. I also don't understand why you chose to save the list type to a variable - I've not seen anyone do that before.
However, getting to your question about the toast and why it's 0 - If you're talking about the toast that comes after the getAllCons call -it's because that code is executed before the callback code. completes.
Try something like this and see what it does.
public class BackgroundTask{
String json_url;
Gson gson;
Type listType;
Context context;
public BackgroundTask(Context context){
this.context = context;
listType = new TypeToken<List<Consignment>>(){}.getType();
appController = AppController.getInstance();
gson = new Gson();
}
public void getAllCons(final GetAllConsListener callBack) {
String tag_json_obj = "json_obj_req";
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, json_url,null,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
callBack.onSuccess(response.toString());
Toast.makeText(context, "Consignments:"+arrayList.size(), Toast.LENGTH_LONG).show();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
appController.addToRequestQueue(jsonArrayRequest);
}
public class GetConsActivity extends AppCompatActivity {
RecyclerView recyclerView;
ConsAdapter adapter;
RecyclerView.LayoutManager layoutManager;
TextView txtView;
BackgroundTask backgroundTask;
Gson gson;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_get_cons);
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
gson = new Gson();
BackgroundTask backgroundTask = new BackgroundTask(GetConsActivity.this);
backgroundTask.getAllCons(new GetAllConsListener() {
#Override
public void onSuccess(String response) {
List<Consignment> values = parseResponse(response);
updateUI(values);
}
});
//code may execute here but callback is not yet complete.
}
public List<Consignment> parseResponse(String response){
return gson.fromJson(response,listType);
}
private void updateUI(List<Consignment> consignments){
if(adapter == null){
adapter = new ConsAdapter(consignments)
recyclerView.setAdapter(adapter);
} else {
adapter.consignments = consignments;
adapter.notifyDataSetChanged();
}
}
I have a problem about screen rotation. I know that I must use method "onSaveInstanceState(Bundle outState)" but I have no ideal how it works. My application have to add the "marker" to Google Map.
class AddMarker extends Fragment{
private static final String KEY = "marker";
private ArrayList<LatLng> mData;
private GoogleMap mMap;
private MapView mMapView;
#Override
public void onSaveInstanceState(Bundle outState) {
outState.putParcelableArrayList(KEY, mData);
super.onSaveInstanceState(outState);
mapView.onSaveInstanceState(outState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View v = inflater.inflate(R.layout.map, container, false);
mMapView = (MapView) v.findViewById(R.id.mapview);
mMapView.onCreate(savedInstanceState);
mMap = mMapView.getMap();
mMap.setMyLocationEnabled(true);
if((savedInstanceState != null)
&& (savedInstanceState.getParcelableArrayList(KEY) != null)){
mData = savedInstanceState.getParcelableArrayList(KEY);
// What should I do here ????
// call drawMarker(mData) ???
}
else
drawMarker(mData);
return v;
}
}
}
Here is my Error Message which is shown when I browse: ../api/User
<Error>
<Message>An error has occurred.</Message>
<ExceptionMessage>
Type 'RavenReader.Web.Controllers.UserController' does not have a default constructor
</ExceptionMessage>
<ExceptionType>System.ArgumentException</ExceptionType>
<StackTrace>
at System.Linq.Expressions.Expression.New(Type type) at System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType) at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator) at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
</StackTrace>
</Error>
My Controller Classes are
public class BaseController : ApiController
{
private readonly ICookieStorageService _cookieStorageService;
public BaseController(ICookieStorageService cookieStorageService)
{
_cookieStorageService = cookieStorageService;
}
}
public class UserController : BaseController
{
private readonly RavenUserFacade _facade;
private readonly ICookieStorageService _cookieStorageService;
public UserController(ICookieStorageService cookieStorageService, RavenUserFacade facade):base(cookieStorageService)
{
_facade = facade;
}
// GET api/User
public IEnumerable<RavenUserView> Get()
{
var users = _facade.GetAllUser();
return users.RavenUsers;
}
..........................................
..........................................
}
According to http://www.peterprovost.org/blog/2012/06/19/adding-ninject-to-web-api/ this blog I organized my NinjectDependencyScope class, NinjectDependencyResolver class and NinjectWebCommon as follows:
public class NinjectDependencyScope : IDependencyScope
{
private IResolutionRoot resolver;
internal NinjectDependencyScope(IResolutionRoot resolver)
{
Contract.Assert(resolver != null);
this.resolver = resolver;
}
public void Dispose()
{
var disposable = resolver as IDisposable;
if (disposable != null)
disposable.Dispose();
resolver = null;
}
public object GetService(Type serviceType)
{
if (resolver == null)
throw new ObjectDisposedException("this", "This scope has already been disposed");
return resolver.TryGet(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
if (resolver == null)
throw new ObjectDisposedException("this", "This scope has already been disposed");
return resolver.GetAll(serviceType);
}
}
public class NinjectDependencyResolver : NinjectDependencyScope, IDependencyResolver
{
private IKernel kernel;
public NinjectDependencyResolver(IKernel kernel)
: base(kernel)
{
this.kernel = kernel;
}
public IDependencyScope BeginScope()
{
return new NinjectDependencyScope(kernel.BeginBlock());
}
}
public static class NinjectWebCommon
{
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
/// <summary>
/// Starts the application
/// </summary>
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
bootstrapper.Initialize(CreateKernel);
}
/// <summary>
/// Stops the application.
/// </summary>
public static void Stop()
{
bootstrapper.ShutDown();
}
/// <summary>
/// Creates the kernel that will manage your application.
/// </summary>
/// <returns>The created kernel.</returns>
public static IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);
return kernel;
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IDbFactory>().To<IDbFactory>().InSingletonScope();
kernel.Bind<IUnitOfWork>().To<EFUnitOfWork>();
kernel.Bind<IRavenUserRepository>().To<RavenUserRepository>();
kernel.Bind<IRavenUserFacade>().To<RavenUserFacade>();
kernel.Bind<ICookieStorageService>().To<CookieStorageService>();
kernel.Bind<ICacheStorage>().To<HttpContextCacheAdapter>();
}
}
I am using visual Studio 2013 Ninject For MVC-3
I am posting this answer in order to help you track down the root issue you are facing. It is not a solution but this is how I reproduced the exact same error you are having.
First of all, you should use a different implementation for the NinjectDependencyResolver. I've set this gist. The reason behind that is avoiding problem with scopes (specially singletons), which you can learn more about here.
Back to your problem, the error is in your bindings, somewhere. First, try removing the InSingletonScope from your IDbFactory. Then, try removing one dependency from your controller constructor and check if that works. Finally, strip out the base class and see if it works.
These steps are just to guide you track down the problem. I've replicated your scenario here and I couldn't face the same issue. My setup was like this:
public class BaseController : ApiController
{
protected readonly IService _service;
public BaseController(IService service)
{
_service = service;
}
}
public class ValuesController : BaseController
{
public ISomeOtherDependency Dependency { get; set; }
public ValuesController(IService service, ISomeOtherDependency dependency) : base(service)
{
Dependency = dependency;
}
// GET api/values/5
public string Get(int id)
{
return _service.CreatedAt.ToString("u");
}
}
public interface ISomeOtherDependency
{
}
public class ConcreteDependency : ISomeOtherDependency
{
}
public interface IService
{
DateTime CreatedAt { get; }
}
public class Service : IService
{
public Service()
{
CreatedAt = DateTime.Now;
}
public DateTime CreatedAt { get; private set; }
}
And my bindings:
kernel.Bind<IService>().To<Service>(); // If I comment this, I get the same exception.
kernel.Bind<ISomeOtherDependency>().To<ConcreteDependency>();
But by commenting out one of these bindings, I get the exact same error as you:
ValuesController' does not have a default constructor
I hope this gets you on the right track to fix your issue.
Thanks for your reply. I followed each your steps but same results here. Finally I debugged by bindings that belongs inside NinjectWebCommon.cs and I found a problem here. While debugging it shows me following problem:
Locating source for
Bootstrapper.cs not found
You need to find Bootstrapper.cs to view the source for the current call stack frame
'c:\Projects\Ninject\Ninject.Web.Common\src\Ninject.Web.Common\Bootstrapper.cs'. Checksum: MD5 {13 3e b1 f3 ba a7 65 14 f6 dc 4d f1 dd aa 21 bf}
The file 'c:\Projects\Ninject\Ninject.Web.Common\src\Ninject.Web.Common\Bootstrapper.cs' does not exist.
Looking in script documents for 'c:\Projects\Ninject\Ninject.Web.Common\src\Ninject.Web.Common\Bootstrapper.cs'...
Looking in the projects for 'c:\Projects\Ninject\Ninject.Web.Common\src\Ninject.Web.Common\Bootstrapper.cs'.
The file was not found in a project.
Looking in directory 'C:\Program Files\Microsoft Visual Studio 11.0\VC\crt\src\'...
Looking in directory 'C:\Program Files\Microsoft Visual Studio 11.0\VC\crt\src\vccorlib\'...
Looking in directory 'C:\Program Files\Microsoft Visual Studio 11.0\VC\atlmfc\src\mfc\'...
Looking in directory 'C:\Program Files\Microsoft Visual Studio 11.0\VC\atlmfc\src\atl\'...
Looking in directory 'C:\Program Files\Microsoft Visual Studio 11.0\VC\atlmfc\include'...
The debug source files settings for the active solution indicate that the debugger will not ask the user to find the file: c:\Projects\Ninject\Ninject.Web.Common\src\Ninject.Web.Common\Bootstrapper.cs.
The debugger could not locate the source file 'c:\Projects\Ninject\Ninject.Web.Common\src\Ninject.Web.Common\Bootstrapper.cs'.