2016-04-10 5 views
2

iは、ユーザがアップロード画像を含むフォームを完成させることができるという点で、ノックアウトとasp.netウェブAPIを使用して単一ページアプリケーションを作成扱う入力フォームは

これは私のコードです

public class Employee 
{ 
    public int EmployeeId { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string ImagePath { get; set; } 
    public string Address { get; set; } 

    public int DeptId { get; set; } 
    public Dept Dept { get; set; } 
} 

私のシードデータ

context.Employees.AddOrUpdate(x => x.EmployeeId, 
    new Employee() 
    { 
     EmployeeId = 1, 
     LastName = "Carson", 
     FirstName = "Alexander", 
     ImagePath = "images/CarsonAlex.png", 
     Address = "Brazil", 
     DeptId = 2 
    }, 
    new Employee() 
    { 
     EmployeeId = 2, 
     LastName = "Arturo", 
     FirstName = "Olivetto", 
     ImagePath = "images/ArturoOliva.png", 
     Address = "Brazil", 
     DeptId = 1 
    }, 
    new Employee() 
    { 
     EmployeeId = 3, 
     LastName = "Alonso", 
     FirstName = "Meredith", 
     ImagePath = "images/MeredithAlonso.png", 
     Address = "Brazil", 
     DeptId = 3 
    } 
); 

私のViewModelクラス

を必要とする場合、あなたはそれを修正するのは自由ですしてください
public class EmployeeDetailVm 
{ 
    public int EmployeeId { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string ImagePath { get; set; } 
    public string Address { get; set; } 
    public int DeptId { get; set; } 
    public string DeptName { get; set; } 
} 

ポスト従業員のAPIコントローラここ

[ResponseType(typeof(EmployeeDetailVm))] 
public IHttpActionResult PostEmployee(EmployeeDetailVm employees) 
{ 
    var employee = new Employee 
    { 
     EmployeeId = employees.EmployeeId, 
     LastName = employees.LastName, 
     FirstName = employees.FirstName, 
     ImagePath = employees.ImagePath, 
     Address = employees.Address, 
     DeptId = employees.DeptId 
    }; 

    if (employees != null) 
    { 
     // Extract the image from the image string 
     string regEx = "data:(.+);base64,(.+)"; 
     Match match = Regex.Match(employees.ImagePath, regEx); 

     if (match.Success) 
     { 
      // Get the content-type of the file and the content 
      string imageType = match.Groups[1].Value; 
      string base64Image = match.Groups[2].Value; 

      if (imageType != null && base64Image != null) 
      { 
       // Verify the content-type is an image 
       string imageRegEx = "image/(.+)"; 
       match = Regex.Match(imageType, imageRegEx); 
      } 

      if (match.Success) 
      { 
       // Get the file extension from the content-type 
       string fileExtension = match.Groups[1].Value; 
       // Get the byte-array of the file from the base64 string 

       byte[] image = Convert.FromBase64String(base64Image); 

       string path = HttpContext.Current.Server.MapPath("~/images"); 
       string fileName = employees.FirstName + employees.LastName; 

       // Generate a unique name for the file (add an index to it if it already exists)               
       string targetFile = fileName + "." + fileExtension; 

       int index = 0; 
       while (File.Exists(Path.Combine(path, targetFile))) 
       { 
        index++; 
        targetFile = fileName + index + "." + fileExtension; 
       } 

       // Write the image to the target file, and update the agent with the new image path 
       File.WriteAllBytes(Path.Combine(path, targetFile), image); 
       employees.ImagePath = "images/" + targetFile; 

       db.Employees.Add(employee); 
       db.SaveChanges(); 


       employees.EmployeeId = employee.EmployeeId; 

       return Ok(employees); 

      } 

     } 
    } 

    throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, "Could not deserialize Employee")); 
} 

が、これは単純なHTMLテーブルの上に私のディスプレイである

var employeeUrl = "http://localhost:50081/api/employees"; 
var deptUrl = "http://localhost:50081/api/depts"; 

var EmployeeViewModel = function() { 
    var self = this; 
    self.error = ko.observable(); 

    self.employeeList = ko.observableArray(); 

    self.listDepts = ko.observableArray(); 

    self.newEmployee = { 
     LastName: ko.observable(), 
     FirstName: ko.observable(), 
     ImagePath: ko.observable(), 
     Address: ko.observable(), 
     Dept: ko.observable() 
    } 


    self.ajaxHelper = function(uri, method, data) { 
     self.error(''); 
     return $.ajax({ 
      type: method, 
      url: uri, 
      dataType: 'json', 
      contentType: 'application/json', 
      data: data ? JSON.stringify(data) : null 
     }).error(function(jqXhr, textStatus, errorThrown) { 
      self.error(errorThrown + ': ' + jqXhr.responseText); 
     }); 
    }, 

    self.getDepts = function() { 
     self.ajaxHelper(deptUrl, 'GET').done(function (data) { 
      self.listDepts(data); 
     }); 
    }, 

    self.getAllEmployee = function() { 
     self.ajaxHelper(employeeUrl, 'GET').done(function(data) { 
      self.employeeList(data); 
     }); 
    }, 

    self.addEmployee = function (formElement) { 
     var employee = { 
      LastName: self.newEmployee.LastName(), 
      FirstName: self.newEmployee.FirstName(), 
      ImagePath: self.newEmployee.ImagePath(), 
      Address: self.newEmployee.Address(), 
      DeptId: self.newEmployee.Dept().DeptId 
     }; 

     self.ajaxHelper(employeeUrl, 'POST', employee).done(function (item) { 
      self.employeeList.push(item); 
     }); 
    } 

}; 

$(document).ready(function() { 
    var employeeVm = new EmployeeViewModel(); 
    ko.applyBindings(employeeVm); 
    employeeVm.getAllEmployee(); 
    employeeVm.getDepts(); 
}); 

ノックアウトのviewmodelで、この作品罰金ついに

<div class="col-md-6"> 
    <div class="panel panel-default"> 
     <div class="panel-heading"> 
      <h2 class="panel-title">Authors</h2> 
     </div> 
     <div class="panel-body"> 
      <table class="table table-striped "> 
       <thead> 
       <tr> 
        <th>Employee Photo </th> 
        <th>Last Name</th> 
        <th>First Name </th> 
        <th>Dept Name </th> 
       </tr> 
       </thead> 
       <tbody data-bind="foreach: employeeList"> 
       <tr> 
        <td> 
         <img data-bind="attr:{ src: ImagePath}" width="75" height="75"/> 
        </td> 
        <td data-bind="text: LastName"></td> 
        <td data-bind="text: FirstName"></td> 
        <td data-bind="text: DeptName"></td> 
       </tr> 
       </tbody> 
      </table> 

     </div> 
    </div> 
</div> 

この追加フォーム、

私のブラウザコンソールで
<div class="col-md-6"> 
    <form class="form-horizontal" data-bind="submit: addEmployee" enctype="multipart/form-data"> 
     <div class="form-group"> 
      <label class="col-sm-4 control-label">Dept Name</label> 
      <div class="col-sm-8"> 
       <select class="form-control" data-bind="options:listDepts, optionsText: 'DeptName', value: newEmployee.Dept"></select> 
      </div> 
     </div> 

     <div class="form-group" data-bind="with: newEmployee"> 
      <label for="inputLastName" class="col-sm-4 control-label">Last Name</label> 
      <div class="col-sm-8"> 
       <input type="text" class="form-control" id="inputLastName" data-bind="value:LastName"/> 
      </div> 

      <label for="inputFirstName" class="col-sm-4 control-label">First Name</label> 
      <div class="col-sm-8"> 
       <input type="text" class="form-control" id="inputFirstName" data-bind="value:FirstName"/> 
      </div> 

      <label for="inputImagePath" class="col-sm-4 control-label">Upload Photo</label> 
      <div class="col-sm-8"> 
       <input type="file" class="form-control" id="inputImagePath" data-bind="value:ImagePath"/> 
      </div> 

      <label for="inputAddress" class="col-sm-4 control-label">Address</label> 
      <div class="col-sm-8"> 
       <input type="text" class="form-control" id="inputAddress" data-bind="value:Address"/> 
      </div> 
     </div> 
     <div class="col-md-offset-4 col-md-8"> 
      <button type="submit" class="btn btn-default">Submit</button> 
     </div> 
    </form> 
</div> 

iは、次のエラーを得た

POST http://localhost:50081/api/employees 400(不正な要求)私はエラーがコードの行に由来している可能性があると信じて

<input type="file" class="form-control" id="inputImagePath" data-bind="value:ImagePath" /> 

私はノックアウトの新しいです、そして、彼らのサイトに助けてくれる多くの文書はありません、

あなたは

ko.bindingHandlers.fileSrc = { 
    init: function (element, valueAccessor) { 
     ko.utils.registerEventHandler(element, "change", function() { 
      var reader = new FileReader(); 

      reader.onload = function (e) { 
       var value = valueAccessor(); 
       value(e.target.result); 
      } 
      // Read in the image file as a data URL. 
      reader.readAsDataURL(element.files[0]); 
     }); 
    } 
}; 

をコントローラに送信されるファイルデータを管理するためのカスタムバインディングのハンドラを使用することができます

<input type="file" 
     class="form-control" 
     id="inputImagePath" 
     data-bind="fileSrc: ImagePath" 
     accept="image/*"> 

画像/ファイルに対してあなたが入力に結合更新する必要があり

+0

アクションにブレークポイントを設定すると、フォームはコントローラ内のアクションを実行して送信されますか? – Nkosi

答えて

1

あなたのルートがどのように設定されているかわからないことを考えれば、私はあなたの行動の名前に応じて、PostEmployee、APIルーティングがデフォルトの慣習に基づくルーティングを使用するように設定し、 api/employees/PostEmployee。あなたはデフォルトの規則に従うように、アクション名と一致しているか、お使いのコントローラのアクションを編集するポストのためのURLを変更することができますいずれか

var employeeUrl = "http://localhost:50081/api/employees"; 

あなたのノックアウトコードはに投稿しようとしている

... ...

public class EmployeesController: ApiController { 

    [HttpPost] 
    [ResponseType(typeof(EmployeeDetailVm))] 
    public IHttpActionResult Post(EmployeeDetailVm employees){...} 

} 
+0

ありがとう、私はちょうど今あなたのコードを試してみましたが、私のブラウザのコンソールで、この時に別のエラーが発生しましたPOST http:// localhost:50081/api/employees 500(内部サーバーエラー) –

+0

コントローラをデバッグできますか?コントローラがヒット/コールされていますか? – Nkosi

+0

いいえ、あなたはどのようにウェブAPIのポストコントローラ、 –

関連する問題