HTTPPost文件上传到ASP.Net API时出错

时间:2013-10-03 12:05:17

标签: android asp.net asp.net-mvc-4 http-post asp.net-apicontroller

我正在使用android尝试将文件上传到我的服务器,该服务器运行的是asp.net mvc4 web api。我的android类如下:

package com.example.wsis;

import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Base64;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class UploadImage extends Activity implements View.OnClickListener {
    Button upload_btn, uploader;
    Uri currImageURI;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_upload_image);
        upload_btn = (Button) this.findViewById(R.id.btnUpload);
        uploader = (Button) this.findViewById(R.id.btnUploadFile);
        upload_btn.setOnClickListener(this);
        uploader.setOnClickListener(this);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.upload_image, menu);
        return true;
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.btnUpload:
            Intent intent = new Intent();
            intent.setType("image/*");
            intent.setAction(Intent.ACTION_GET_CONTENT);
            startActivityForResult(Intent.createChooser(intent, "Select Picture"),1);
            break;

    case R.id.btnUploadFile:
        HttpUploader uploader = new HttpUploader();
        try {
          String image_name = uploader.execute(getRealPathFromURI(currImageURI)).get();        
        } catch (InterruptedException e) {
          e.printStackTrace();
        } catch (ExecutionException e) {
          e.printStackTrace();
        }
        break;
    }
    }

    // To handle when an image is selected from the browser
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_OK) {
            if (requestCode == 1) {
                // currImageURI is the global variable I’m using to hold the content:
                currImageURI = data.getData();
                System.out.println("Current image Path is ----->" + getRealPathFromURI(currImageURI));
                TextView tv_path = (TextView) findViewById(R.id.path);
                tv_path.setText(getRealPathFromURI(currImageURI));
            }
        }
    }

    //Convert the image URI to the direct file system path of the image file
    public String getRealPathFromURI(Uri contentUri) {
        String [] proj={MediaStore.Images.Media.DATA};
        android.database.Cursor cursor = managedQuery( contentUri,
                proj,     // Which columns to return
                null,     // WHERE clause; which rows to return (all rows)
                null,     // WHERE clause selection arguments (none)
                null);     // Order-by clause (ascending by name)
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    }

       public class HttpUploader extends AsyncTask<String, Void, String> {

           @Override
           protected String doInBackground(String... path) {

                String outPut = null;

                for (String sdPath : path) {

                    Bitmap bitmapOrg = BitmapFactory.decodeFile(sdPath);
                    ByteArrayOutputStream bao = new ByteArrayOutputStream();

                    //Resize the image
                    double width = bitmapOrg.getWidth();
                    double height = bitmapOrg.getHeight();
                    double ratio = 400/width;
                    int newheight = (int)(ratio*height);

                    System.out.println("———-width" + width);
                    System.out.println("———-height" + height);

                    bitmapOrg = Bitmap.createScaledBitmap(bitmapOrg, 400, newheight, true);

                    //Here you can define .PNG as well
                    bitmapOrg.compress(Bitmap.CompressFormat.JPEG, 95, bao);
                    byte[] ba = bao.toByteArray();
                    String ba1 = Base64.encodeToString(ba, Base64.NO_WRAP);
                    System.out.println("uploading image now ——–" + ba1);

                    ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
                    nameValuePairs.add(new BasicNameValuePair("image", ba1));

                    try {
                        HttpClient httpclient = new DefaultHttpClient();
                        HttpPost httppost = new HttpPost("http://proopt.co.za.winhost.wa.co.za/api/Files/");
                        httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

                        HttpResponse response = httpclient.execute(httppost);
                        HttpEntity entity = response.getEntity();                

                        // print response
                        outPut = EntityUtils.toString(entity);
                        Log.i("GET RESPONSE—-", outPut);

                        //is = entity.getContent();
                        Log.e("log_tag ******", "good connection");

                        bitmapOrg.recycle();

                    } catch (Exception e) {
                        Log.e("log_tag ******", "Error in http connection " + e.toString());
                    }
                }
                return outPut;

           }
       }
}

我的asp.net控制器类是:

public class FilesController : ApiController
    {
        // GET api/files
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }

        // GET api/files/5
        public string Get(int id)
        {
            return "value";
        }

        // POST api/files
        public HttpResponseMessage Post(string filename)
        {
            var task = this.Request.Content.ReadAsStreamAsync();
            task.Wait();
            Stream requestStream = task.Result;

            try
            {
                Stream fileStream = File.Create(HttpContext.Current.Server.MapPath("~/" + filename));
                requestStream.CopyTo(fileStream);
                fileStream.Close();
                requestStream.Close();
            }
            catch (IOException)
            {
              //  throw new HttpResponseException("A generic error occured. Please try again later.", HttpStatusCode.InternalServerError);
            }

            HttpResponseMessage response = new HttpResponseMessage();
            response.StatusCode = HttpStatusCode.Created;
            return response;
        }

        // PUT api/files/5
        public void Put(int id, [FromBody]string value)
        {
        }

        // DELETE api/files/5
        public void Delete(int id)
        {
        }
    }

这是global.asax.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;

namespace WSISWebService
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801

    public class WebApiApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

        }

        public static void RegisterRoutes(RouteCollection routes)
        {

            routes.MapHttpRoute(

                name: "DefaultApi",

                routeTemplate: "{controller}/{filename}",

                defaults: new { filename = RouteParameter.Optional }

            );

        }
    }
}

我非常渴望让这个工作,任何人都可以帮助我吗?

更新:我已经设法“找到”post方法,但我似乎无法让android发送文件,有人可以帮我编码服务器端邮政方法???

1 个答案:

答案 0 :(得分:1)

您发布到的URL正在找到通往控制器类的路径,因为您的默认路由映射是将“/ api / Files /”映射到FilesController。但是,您的URI无法识别“操作”,例如“/ API /文件/后”。

BTW,ASP.NET MVC应用程序中的默认路由是“/ {controller} / {action}”,通常默认为“controller = Default”和“action = Index”。因此,默认情况下,“/ api / Files”会查找名为“Index”的操作方法,但是您的FilesController没有这样的方法。

简答:

  1. 将“/ Post”添加到您要发布到的网址
  2. 的末尾
  3. 或者,将“Post()”操作方法重命名为“Index()”
  4. 答案很长:

    1. 查看设置路由的Global.asax.cs,并考虑设置一些非常自定义的路由,这样您就可以看到自己的URI,而不管您如何组织控制器类和操作方法。
    2. 现在您已经发布了Global.asax.cs,让我们检查您拥有的一个路由模板:

      "{controller}/{filename}"
      

      你告诉MVC,当你有一个看起来像“/ something / somethingelse”的URL来获取“某些东西”并将其用作控制器名称,并使用“somethingelse”作为文件名。您的路线中没有任何内容标识要调用的操作。

      如果您不希望调用任何其他操作,那么现在就可以了。在这种情况下,您可以在路径的默认值中对“Post”操作进行硬编码:

      defaults: new { filename = RouteParameter.Optional, action = "Post" }
      

      如果您希望能够调用您拥有的其他操作方法(例如Put,Delete等),那么您可以修改您的URL模式(并调用URL)以包含“action”:

      "{controller}/{action}/{filename}" // E.g. url: "/Files/Post/myfilename.txt"
      

      或者,也许你真的希望一切都要经过FilesController,在这种情况下你可以设置默认的控制器,让路径模板只需要动作和文件名(例如... / Post / myfilename.txt) :

              routes.MapHttpRoute(
                  name: "DefaultApi",
                  routeTemplate: "{action}/{filename}",
                  defaults: new { filename = RouteParameter.Optional, controller = "Files"}
              );