Saturday, 30 November 2013

How to use WebRequest to POST/Upload some data programmatically and read response using ASP.NET MVC?

In one of my project I got condition where I need to POST file along with data from my application to other application located on other server. I just want to POST some fields along with file same as we do with simple Form Submission but need to done it programmatically. So for this I used WebRequest Class in System.Net Namespace which makes a request to a Uniform Resource Identifier(URI).

I created following function which takes path of file to POST/Upload and URL to which make WebRequest.

public string PostData(string FilePath, string UrlToPost)
{
 string ResponseFromServer = string.Empty;

 try
 {
  /* Setting data fields to post */
  string DataToPost = "?username=myusername&password=mypassword&app=myapp";

  /* Generating Url to Request */
  Uri uri = new Uri(UrlToPost + DataToPost);

  string boundary = "----------" + System.DateTime.Now.Ticks.ToString("x");

  /* Creating WebRequest object and assigning Request Info. */
  HttpWebRequest MyRequest = (HttpWebRequest)WebRequest.Create(uri);
  MyRequest.ContentType = "multipart/form-data; boundary=" + boundary;
  MyRequest.Method = "POST";

  /* Build up the post message header */
  StringBuilder sb = new StringBuilder();
  sb.Append("--");
  sb.Append(boundary);
  sb.Append("\r\n");
  sb.Append("Content-Disposition: form-data; name=\"myfile\"; filename=\"");
  sb.Append(Path.GetFileName(FilePath));
  sb.Append("\"");
  sb.Append("\r\n");
  sb.Append("Content-Type: application/octect-stream \r\n");
  sb.Append("\r\n");

  string PostHeader = sb.ToString();
  byte[] PostHeaderBytes = Encoding.UTF8.GetBytes(PostHeader);

  /* Build the trailing boundary string as a byte array
     ensuring the boundary appears on a line by itself */
  byte[] BoundaryBytes = Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");


  FileStream fileStream = new FileStream(Server.MapPath(FilePath), FileMode.Open, FileAccess.Read);
  long length = PostHeaderBytes.Length + fileStream.Length + BoundaryBytes.Length;
  MyRequest.ContentLength = length;

  Stream RequestStream = MyRequest.GetRequestStream();

  /* Write out our post header */
  RequestStream.Write(PostHeaderBytes, 0, PostHeaderBytes.Length);

  /* Write out the file contents */
  byte[] buffer = new Byte[checked((uint)Math.Min(4096, (int)fileStream.Length))];
  int bytesRead = 0;
  while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
  {
   RequestStream.Write(buffer, 0, bytesRead);
  }

  /* Write out the trailing boundary */
  RequestStream.Write(BoundaryBytes, 0, BoundaryBytes.Length);
  WebResponse MyResponse = MyRequest.GetResponse();
  Stream s = MyResponse.GetResponseStream();
  StreamReader sr = new StreamReader(s);

  ResponseFromServer = sr.ReadToEnd();
 }
 catch (Exception ex)
 {

 }

 /* This is response from server to return */
 return ResponseFromServer;

}
When this function called all data fields along file posted to destination Url and we get posted data as it is posted by simple form submission but it's done programmatically.

I hope this article will help you. Please leave comments to improve this article, any suggestion also welcomed.

Tuesday, 8 October 2013

How to Pass Custom Error Messages to Data Annotations in Asp.Net MVC?

In previous article we saw "How to Preserve Data Annotations When EDMX File is Recreated?", now in this article I am going to show you "How to Pass Custom Error Messages to Data Annotations in Asp.Net MVC".

It is always better to put all error messages in centralized place instead of hard-coding it. Because of this when we need to change it we change it easily by changing it in centralized place which will reflect all over project instead of manually searching and replacing it all over the project.

For creating this centralized place Right click on project in Solution Explorer, Select Add -> New Folder name it "Resource" or anything meaningful. Then Right click on "Resource" folder, Select Add -> New Item... In Add New Item Dialog go to General Tab -> Resource File name it "ValidationMessages.resx" or anything meaningful. After doing this your Solution Explorer will be like this



In Resource file you can enter your validation messages as Name-Value. For example, error message for FirstName which is required field can be like this and so on..



Now once we define all error messages in Resource file we can easily pass these error messages to data annotations used to validate our model like this

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using MyResource = CustomizeErrorMessages.Resource;

namespace CustomizeErrorMessages.Models {     public class UserInfo     {         [Required(ErrorMessageResourceType = typeof(MyResource.ValidationMessages), ErrorMessageResourceName = "FirstNameReq")]         public string FirstName { get; set; }         public string MiddleName { get; set; }         [Required(ErrorMessageResourceType = typeof(MyResource.ValidationMessages), ErrorMessageResourceName = "LastNameReq")]         public string LastName { get; set; }     } }
Here, "MyResource" is folder in our project which contains Resource file, "ErrorMessageResourceType" is name of our Resource file which sets the resource type to use for error-message lookup if validation fails and "ErrorMessageResourceName" is name we added in our Resource file which sets the error message resource name to use. During validation process the value related to "ErrorMessageResourceName" is shown.

I hope this article will help you. Please leave comments to improve this article, any suggestion also welcomed.

Sunday, 29 September 2013

How to Preserve Data Annotations When EDMX File is Recreated?

This is common problem when using Entity Framework, If we use Data Annotations directly in classes generated by Entity Framework this Annotations are removed when we recreate EDMX file. In this article I am going to tell you how to preserve these Data Annotations even EDMX file is recreated.

Many programmers including Me write Data Annotations directly in classes generated by Entity Framework. This works fine but will creates problem when you need to modify table schema. I suffered from this problem when I modified my table schema and recreate my EDMX file to find all my Data Annotations are removed.

To deal with this problem I keep my automatically generated classes by Entity Framework as it is and added a class in Models folder to contain the partial class and namespace declaration same as the partial class and namespace declaration of the data model that I am using like this



This is TblUser class in Entity folder



This is TblUser class in my Models folder with Data Annotations applied



Here notice that I keep namespace and partial class declaration of class in Models Folder same as that of in my Entity Folder. Also associated the new class(TblUserMD) with the table class(TblUser) by using the MetadataTypeAttribute attribute found in System.ComponentModel.DataAnnotations. The associated class can have any name, a convention is to append "MD" or "MetaData" to the table class name. The associated class must be used with EDM or LINQ-to-SQL models because CLR types cannot mark existing properties with new attributes.

Now when I use this model with view like this
@model PreservingDataAnnotation.Entity.TblUser

All Data Annotations used in model get applied to my view like this



So next time I recreate EDMX file my Data Annotations keep safe in class in Models folder.

I hope this article will help you. Please leave comments to improve this article, any suggestion also welcomed.